Re: Wrong result with enum
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: Unless explicitly set, default type is int. 110 is greater than int.max. 11 ```d enum w = 100_000; size_t b = w * w; // size_t b = 10 * 10; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)... 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. 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; } ```
Re: Wrong result with enum
On Thursday, 11 November 2021 at 09:11:37 UTC, Salih Dincer wrote: Unless explicitly set, default type is int. 110 is greater than int.max. 11 ```d enum w = 100_000; size_t b = w * w; // size_t b = 10 * 10; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)... 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.
Re: Wrong result with enum
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.
Re: Wrong result with enum
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 That's an `int` literal. Try enum wLimit = 100_000L; the L suffix makes a `long` literal.
Re: Wrong result with enum
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: 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: 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. 110 is greater than int.max. 11 ```d enum w = 100_000; size_t b = w * w; // size_t b = 10 * 10; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)... Are you on 32-bit OS? I believe `size_t` is 32 bits on 32 bit OS and 64 on a 64-bit OS 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.
Re: Wrong result with enum
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: 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. 110 is greater than int.max. 11 ```d enum w = 100_000; size_t b = w * w; // size_t b = 10 * 10; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)... Are you on 32-bit OS? I believe `size_t` is 32 bits on 32 bit OS and 64 on a 64-bit OS
Re: Wrong result with enum
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: 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. 110 is greater than int.max. 11 ```d enum w = 100_000; size_t b = w * w; // size_t b = 10 * 10; // ??? assert(b == 10_000_000_000); // Assert Failure ``` The w!(int) is not greater than the b!(size_t)...
Re: Wrong result with enum
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. 110 is greater than int.max.
Re: Wrong result with enum
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.
Wrong result with enum
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 } */ ```