import std.stdio, std.bigint;
void main() {
const mod = 10_000_000_000_000_000;
pragma(msg, typeof(mod));
BigInt value = 2551700137;
writefln("%d", value);
writefln("%d", mod);
value %= mod;
writefln("%d", value);
}
----------
C:\Users\Stewart\Documents\Programming\D\Tests\bugs>dmd bigint_mod.d
const(long)
C:\Users\Stewart\Documents\Programming\D\Tests\bugs>bigint_mod
2551700137
10000000000000000
676780713
----------
Interestingly, if I %= a long or ulong literal or non-const variable instead, I get
----------
d:\dmd2\windows\bin\..\..\src\phobos\std\bigint.d(163): Error: static assert (true && false) is false
bigint_mod.d(10): instantiated from here: opOpAssign!("%",ulong)
----------
and looking at bigint.d I see
static assert(!is(T==long) && !is(T==ulong));
so it appears that doing %= on a long/ulong has been deliberately disabled pending getting it working properly, but const/immutable long/ulong has been overlooked in doing so.
Since BigInt %= BigInt seems to work correctly, how about making it construct a BigInt from the long/ulong and using that? It can later be replaced with an implementation optimised to long/ulong once that has been written and tested.
Comment #1 by clugdbug — 2012-04-23T06:04:31Z
(In reply to comment #0)
> Since BigInt %= BigInt seems to work correctly, how about making it construct a
> BigInt from the long/ulong and using that? It can later be replaced with an
> implementation optimised to long/ulong once that has been written and tested.
It's a template problem, (related to implicit conversion) not a mathematical problem. At the time I wrote the code, I could not find any way to select the correct function in all cases, if I allowed long and ulong.
At least one of the bugs I was hitting was fixed during the last three releases, so it is probably possible to implement it now.
Comment #2 by github-bugzilla — 2012-07-01T19:53:15Z