Bug 13963 – BigInt modulo ulong is rejected

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2015-01-10T05:22:00Z
Last change time
2015-02-18T03:41:16Z
Assigned to
nobody
Creator
markus

Comments

Comment #0 by markus — 2015-01-10T05:22:30Z
dmd 2.066.1 import std.bigint; void main() { BigInt x = 1; BigInt y = 1; x %= y; // OK x %= 1; // OK x %= 1U; // OK x %= 1L; // OK x %= 1UL; // OK x = x % y; // OK x = x % 1; // OK x = x % 1U; // OK x = x % 1L; // Error: incompatible types for ((x) % (1L)): 'BigInt' and 'long' x = x % 1UL; // Error: incompatible types for ((x) % (1LU)): 'BigInt' and 'ulong' } This looks similar to issue 13391.
Comment #1 by electrolysis.jp+d — 2015-01-11T07:58:49Z
Comment #2 by github-bugzilla — 2015-01-25T03:42:26Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/f8bb3e4cd8f90af3d9004392f7668759d57005f2 Fix Issue 13963 - BigInt modulo ulong is rejected https://github.com/D-Programming-Language/phobos/commit/3fbb2c33dd7687d8d8538903878f5d60e4362e27 Merge pull request #2864 from e10s/patch-6 Fix Issue 13963 - BigInt modulo ulong is rejected
Comment #3 by markus — 2015-01-25T08:36:29Z
Thanks for the fix, but we still have some problem here: import std.bigint; void main() { import std.typetuple : TypeTuple; import std.stdio : writeln; // assert that "y = x % b" has same value as "x %= b" void checkMod(T)(T a, T b) { BigInt x = a; auto y = x % b; x %= b; //assert(x == y); if (x != y) writeln("BitInt modulo ERROR: ", typeid(T), " ", a, " ", b, " ", x, " ", y); } foreach(T; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong)) { immutable T[] values = [T.min, T.min + 1, 0, T.max - 1, T.max]; foreach(a; values) foreach(b; values) if (b != 0) checkMod!T(a, b); } }
Comment #4 by markus — 2015-01-25T09:37:47Z
This patch seems to fix the issue for me. The unittest will still have to get updated. --- dmd-phobos.git/std/bigint.d 2015-01-25 06:45:36.000000000 +0100 +++ bigint.d 2015-01-25 10:34:57.000000000 +0100 @@ -157,6 +157,8 @@ } // x%y always has the same sign as x. // This is not the same as mathematical mod. + if (data.isZero()) + sign = false; } else static if (op==">>" || op=="<<") { @@ -279,6 +281,14 @@ return r; } } + else static if (is(Unqual!T == uint)) + { + uint u = absUnsign(y); + long rem = BigUint.modInt(data, u); + // x%y always has the same sign as x. + // This is not the same as mathematical mod. + return sign ? -rem : rem; + } else { uint u = absUnsign(y);
Comment #5 by electrolysis.jp+d — 2015-01-25T16:53:36Z
Thank you for your report! However, it's beyond the range of this issue. I hope you will report it as a different one ;) Furthermore, I think the "-0" problem and the uint problem should be treated as individuals.
Comment #6 by markus — 2015-02-01T20:34:59Z
Closing this issue. Fix it or leave it. But see "the perfect is the enemy of the good" in https://github.com/klamonte/cycle/blob/master/docs/no_more_d.md
Comment #7 by electrolysis.jp+d — 2015-02-08T07:48:48Z
Issue 14124 - BigInt %= int can return "-0"
Comment #8 by github-bugzilla — 2015-02-18T03:41:16Z