[Issue 7993] BigInt divide-by-1 error
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Apr 28 03:33:38 PDT 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7993
--- Comment #5 from c.m.brandenburg at gmail.com 2012-04-28 03:34:45 PDT ---
After debugging the code, I discovered the root cause. (Code snippets below.)
BigInt uses BigUint.divInt() for performing the underlying division operation.
BigUint.divInt() has two cases: (1) the divisor is a power of 2, and (2) the
divisor is not a power of 2.
In the case of dividing by 1, the divisor is a power of two and case #1 is
followed (if ((y&(-y))==y)). However, the number of bits to shift is 0. But
multibyteShr() explicitly states that the number of bits to shift must not be 0
(numbits must be in the range 1..31).
By changing BigUint.divInt() to treat y==1 as case #2—not a power of 2—rather
than case #1, the problem is fixed.
Code snippets: this is the runtime code that ships with my DMD/Phobos package.
/usr/include/d/std/internal/math/biguintcore.d:549:
// return x / y
static BigUint divInt(T)(BigUint x, T y) if ( is(T==uint) )
{
uint [] result = new BigDigit[x.data.length];
if ((y&(-y))==y)
{
assert(y!=0, "BigUint division by zero");
// perfect power of 2
uint b = 0;
for (;y!=1; y>>=1)
{
++b;
}
multibyteShr(result, x.data, b);
}
else
{
result[] = x.data[];
uint rem = multibyteDivAssign(result, y, 0);
}
return BigUint(removeLeadingZeros(result));
}
/usr/include/d/std/internal/math/biguintnoasm.d:150
/** dest[] = src[] >> numbits
* numbits must be in the range 1..31
*/
void multibyteShr(uint [] dest, const(uint) [] src, uint numbits)
{
ulong c = 0;
for(ptrdiff_t i = dest.length; i!=0; --i)
{
c += (src[i-1] >>numbits) + (cast(ulong)(src[i-1]) << (64 - numbits));
dest[i-1] = cast(uint)c;
c >>>= 32;
}
}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list