8057793: BigDecimal is no longer effectively immutable
Summary: Modify MutableBigInteger.divideAndRemainderBurnikelZiegler() to copy the instance (this) to a new MutableBigInteger to use as the dividend.
Reviewed-by: darcy
Contributed-by: robbiexgibson@yahoo.com
--- a/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java Sat Sep 13 13:26:18 2014 -0400
+++ b/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java Mon Sep 15 13:05:04 2014 -0700
@@ -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;
}
}
--- a/jdk/test/java/math/BigDecimal/ZeroScalingTests.java Sat Sep 13 13:26:18 2014 -0400
+++ b/jdk/test/java/math/BigDecimal/ZeroScalingTests.java Mon Sep 15 13:05:04 2014 -0700
@@ -23,8 +23,10 @@
/*
* @test
- * @bug 4902952 4905407 4916149
- * @summary Tests that the scale of zero is propagated properly and has the proper effect.
+ * @bug 4902952 4905407 4916149 8057793
+ * @summary Tests that the scale of zero is propagated properly and has the
+ * proper effect and that setting the scale to zero does not mutate the
+ * BigDecimal.
* @author Joseph D. Darcy
*/
@@ -445,6 +447,16 @@
return failures;
}
+ static int setScaleDoesNotMutateTest() {
+ BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689"
+ + ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704");
+ if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
public static void main(String argv[]) {
int failures = 0;
@@ -455,6 +467,7 @@
failures += setScaleTests();
failures += toEngineeringStringTests();
failures += ulpTests();
+ failures += setScaleDoesNotMutateTest();
if (failures > 0 ) {
throw new RuntimeException("Incurred " + failures + " failures" +