That was my screw-up. Thanks for fixing it. Tim
On 09.09.2014 10:30, Robert Gibson wrote: > > > Hi there, > > I came across a case in BigDecimal division where the dividend ends up > getting mutated, which is rather strange for a seemingly immutable class! > (It's a subset of the cases where the Burnikel-Ziegler algorithm is used, I > haven't done the analysis to find out under which exact conditions it's > triggered.) > > The attached patch - against the JDK8 version - should fix the problem, at > the cost of an extra array copy. Could somebody review and/or comment please? > > Thanks, > Robert > > --- MutableBigInteger.java 2014-09-04 09:42:23.426815000 +0200 > +++ MutableBigInteger.java.patched 2014-09-04 09:46:21.344132000 +0200 > @@ -1261,19 +1261,20 @@ > int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: > sigma = max{T | (2^T)*B < beta^n} > MutableBigInteger bShifted = new MutableBigInteger(b); > bShifted.safeLeftShift(sigma); // step 4a: shift b so its > length is a multiple of n > - safeLeftShift(sigma); // step 4b: shift this by the same > amount > + MutableBigInteger aShifted = new MutableBigInteger (this); > + aShifted.safeLeftShift(sigma); // step 4b: shift a by the > same amount > - // step 5: t is the number of blocks needed to accommodate this > plus one additional bit > - int t = (int) ((bitLength()+n32) / n32); > + // step 5: t is the number of blocks needed to accommodate a > plus one additional bit > + int t = (int) ((aShifted.bitLength()+n32) / n32); > if (t < 2) { > t = 2; > } > - // step 6: conceptually split this into blocks a[t-1], ..., a[0] > - MutableBigInteger a1 = getBlock(t-1, t, n); // the most > significant block of this > + // step 6: conceptually split a into blocks a[t-1], ..., a[0] > + MutableBigInteger a1 = aShifted.getBlock(t-1, t, n); // the > most significant block of a > // step 7: z[t-2] = [a[t-1], a[t-2]] > - MutableBigInteger z = getBlock(t-2, t, n); // the second to > most significant block > + MutableBigInteger z = aShifted.getBlock(t-2, t, n); // the > second to most significant block > z.addDisjoint(a1, n); // z[t-2] > // do schoolbook division on blocks, dividing 2-block numbers by > 1-block numbers > @@ -1284,7 +1285,7 @@ > ri = z.divide2n1n(bShifted, qi); > // step 8b: z = [ri, a[i-1]] > - z = getBlock(i-1, t, n); // a[i-1] > + z = aShifted.getBlock(i-1, t, n); // a[i-1] > z.addDisjoint(ri, n); > quotient.addShifted(qi, i*n); // update q (part of step 9) > } > @@ -1292,7 +1293,7 @@ > ri = z.divide2n1n(bShifted, qi); > quotient.add(qi); > - ri.rightShift(sigma); // step 9: this and b were shifted, so > shift back > + ri.rightShift(sigma); // step 9: a and b were shifted, so shift > back > return ri; > } > } > >