digitalmars.D.learn - Wrong result with enum
- Salih Dincer (29/29) Nov 10 2021 is this a issue, do you need to case?
 - zjh (2/3) Nov 10 2021 out of bound.
 - Stanislav Blinov (4/9) Nov 10 2021 https://dlang.org/spec/enum.html#named_enums
 - Salih Dincer (10/21) Nov 11 2021 100001
 - Tejas (3/26) Nov 11 2021 Are you on 32-bit OS? I believe `size_t` is 32 bits on 32 bit OS
 - Patrick Schluter (6/33) Nov 11 2021 That's not the issue with his code. The 32 bit overflow happens
 - Stanislav Blinov (10/20) Nov 11 2021 That code is
 - Salih Dincer (18/39) Nov 11 2021 Thank you all :)
 - Adam D Ruppe (4/8) Nov 11 2021 That's an `int` literal. Try
 - Patrick Schluter (9/38) Nov 11 2021 Integer overflow. By default an enum is defined as `int` which is
 
is this a issue, do you need to case?
```d
enum tLimit = 10_000;  // (1) true result
enum wLimit = 100_000; // (2) wrong result
void main()
{
   size_t subTest1 = tLimit;
   assert(subTest1 == tLimit);        /* no error */
   size_t subTest2 = wLimit;
   assert(subTest2 == wLimit);        /* no error */
   size_t gauss = (tLimit * (tLimit + 1)) / 2;
   assert(gauss == 50_005_000);       /* no error */
   gauss = (wLimit * (wLimit + 1)) / 2;
   assert(gauss == 5_000_050_000);    /* failure
   // Fleeting Solution:
     enum size_t limit = 100_000;
     gauss = (limit * (limit + 1)) / 2;
     assert(gauss == 5_000_050_000); //* no error */
} /* Small Version:
void main(){
   enum t = 10_000;
   size_t a = t * t;
   assert(a == 100_000_000);    // No Error
   enum w = 100_000;
   size_t b = w * w;
   assert(b == 10_000_000_000); // Assert Failure
}
*/
```
 Nov 10 2021
On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:is this a issue, do you need to case?out of bound.
 Nov 10 2021
On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:is this a issue, do you need to case? ```d enum tLimit = 10_000; // (1) true result enum wLimit = 100_000; // (2) wrong result ```https://dlang.org/spec/enum.html#named_enums Unless explicitly set, default type is int. 10000100000 is greater than int.max.
 Nov 10 2021
On Thursday, 11 November 2021 at 06:34:16 UTC, Stanislav Blinov wrote:On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:100001 ```d enum w = 100_000; size_t b = w * w; // size_t b = 100000 * 100000; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...is this a issue, do you need to case? ```d enum tLimit = 10_000; // (1) true result enum wLimit = 100_000; // (2) wrong result ```https://dlang.org/spec/enum.html#named_enums Unless explicitly set, default type is int. 10000100000 is greater than int.max.
 Nov 11 2021
On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote:On Thursday, 11 November 2021 at 06:34:16 UTC, Stanislav Blinov wrote:Are you on 32-bit OS? I believe `size_t` is 32 bits on 32 bit OS and 64 on a 64-bit OSOn Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:100001 ```d enum w = 100_000; size_t b = w * w; // size_t b = 100000 * 100000; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...is this a issue, do you need to case? ```d enum tLimit = 10_000; // (1) true result enum wLimit = 100_000; // (2) wrong result ```https://dlang.org/spec/enum.html#named_enums Unless explicitly set, default type is int. 10000100000 is greater than int.max.
 Nov 11 2021
On Thursday, 11 November 2021 at 12:05:19 UTC, Tejas wrote:On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote:That's not the issue with his code. The 32 bit overflow happens already during the `w * w` mulitplication. The wrong result is then assigned to the `size_t`. `cast(size_t)w * w` or the declaration `enum : size_t { w = 100_000 };` would change that.On Thursday, 11 November 2021 at 06:34:16 UTC, Stanislav Blinov wrote:Are you on 32-bit OS? I believe `size_t` is 32 bits on 32 bit OS and 64 on a 64-bit OSOn Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:100001 ```d enum w = 100_000; size_t b = w * w; // size_t b = 100000 * 100000; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...is this a issue, do you need to case? ```d enum tLimit = 10_000; // (1) true result enum wLimit = 100_000; // (2) wrong result ```https://dlang.org/spec/enum.html#named_enums Unless explicitly set, default type is int. 10000100000 is greater than int.max.
 Nov 11 2021
On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote:That code is ``` size_t b = int(w) * int(w); ``` That is, `multiply two ints and assign result to a size_t`. Multiplication of two ints is still an int though, and you can't fit ten billion in an int, so that's overflow. It doesn't matter that you declare `b` as `size_t` here. Overflow happens before that assignment.Unless explicitly set, default type is int. 10000100000 is greater than int.max.100001 ```d enum w = 100_000; size_t b = w * w; // size_t b = 100000 * 100000; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...
 Nov 11 2021
On Thursday, 11 November 2021 at 14:52:45 UTC, Stanislav Blinov wrote:On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote:Thank you all :) DMD still has to type inference... I think the safest and most practical method is to explicitly use double types: ```d import std.stdio; enum factors { n = 1e+9, n1 } auto gauss (double a = factors.n, double b = factors.n1) { return cast(size_t)(a * b)/2; } void main() { gauss.writeln; ulong.max.writeln; } ```That code is ``` size_t b = int(w) * int(w); ``` That is, `multiply two ints and assign result to a size_t`. Multiplication of two ints is still an int though, and you can't fit ten billion in an int, so that's overflow. It doesn't matter that you declare `b` as `size_t` here. Overflow happens before that assignment.Unless explicitly set, default type is int. 10000100000 is greater than int.max.100001 ```d enum w = 100_000; size_t b = w * w; // size_t b = 100000 * 100000; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...
 Nov 11 2021
On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:is this a issue, do you need to case? ```d enum tLimit = 10_000; // (1) true result enum wLimit = 100_000; // (2) wrong resultThat's an `int` literal. Try enum wLimit = 100_000L; the L suffix makes a `long` literal.
 Nov 11 2021
On Thursday, 11 November 2021 at 05:37:05 UTC, Salih Dincer wrote:
 is this a issue, do you need to case?
 ```d
 enum tLimit = 10_000;  // (1) true result
 enum wLimit = 100_000; // (2) wrong result
 void main()
 {
   size_t subTest1 = tLimit;
   assert(subTest1 == tLimit);        /* no error */
   size_t subTest2 = wLimit;
   assert(subTest2 == wLimit);        /* no error */
   size_t gauss = (tLimit * (tLimit + 1)) / 2;
   assert(gauss == 50_005_000);       /* no error */
   gauss = (wLimit * (wLimit + 1)) / 2;
   assert(gauss == 5_000_050_000);    /* failure
   // Fleeting Solution:
     enum size_t limit = 100_000;
     gauss = (limit * (limit + 1)) / 2;
     assert(gauss == 5_000_050_000); //* no error */
 } /* Small Version:
 void main(){
   enum t = 10_000;
   size_t a = t * t;
   assert(a == 100_000_000);    // No Error
   enum w = 100_000;
   size_t b = w * w;
   assert(b == 10_000_000_000); // Assert Failure
 }
 */
 ```
Integer overflow. By default an enum is defined as `int` which is 
limited to 32 bit. `int.max` is 2_147_483_647 which is the 
biggest number representable with an int.
You can declare the enum to be of a bigger type `enum  : long { w 
= 100_000 };`
or you can use `std.bigint` if you don't know the maximum you 
work with or the library `std.experimental.checkedint` which 
allows to set the behaviour one wants in case of overflow.
 Nov 11 2021








 
 
 
 zjh <fqbqrr 163.com> 