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
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.