From ffa2ff393ef90f3c89309fad1c07f15eef724a29 Mon Sep 17 00:00:00 2001 From: darcy Date: Mon, 5 Sep 2011 08:04:04 -0700 Subject: [PATCH] 7086710: java/util/Formatter/Basic.java failing after 7082971 Reviewed-by: alanb --- src/share/classes/java/math/BigDecimal.java | 44 ++++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/share/classes/java/math/BigDecimal.java b/src/share/classes/java/math/BigDecimal.java index c685f5731..369d9dfa9 100644 --- a/src/share/classes/java/math/BigDecimal.java +++ b/src/share/classes/java/math/BigDecimal.java @@ -904,12 +904,13 @@ public class BigDecimal extends Number implements Comparable { throw new NumberFormatException("Infinite or NaN"); // Translate the double into sign, exponent and significand, according // to the formulae in JLS, Section 20.10.22. - int sign = (val >= 0.0 ? 1 : -1); // Preserving sign of zero doesn't matter - int exponent = Math.getExponent(val); long valBits = Double.doubleToLongBits(val); - long significand = (exponent == (Double.MIN_EXPONENT-1) - ? (valBits & ((1L << 52) - 1)) << 1 - : (valBits & ((1L << 52) - 1)) | (1L << 52)); + int sign = ((valBits >> 63) == 0 ? 1 : -1); + int exponent = (int) ((valBits >> 52) & 0x7ffL); + long significand = (exponent == 0 + ? (valBits & ((1L << 52) - 1)) << 1 + : (valBits & ((1L << 52) - 1)) | (1L << 52)); + exponent -= 1075; // At this point, val == sign * significand * 2**exponent. /* @@ -933,9 +934,7 @@ public class BigDecimal extends Number implements Comparable { BigInteger intVal; long compactVal = sign * significand; if (exponent == 0) { - // If the exponent is zero, the significant fits in a long - assert compactVal != INFLATED; - intVal = null; + intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null; } else { if (exponent < 0) { intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal); @@ -4162,15 +4161,30 @@ public class BigDecimal extends Number implements Comparable { return qsign < 0; default: // Some kind of half-way rounding - if (roundingMode == ROUND_HALF_DOWN || - cmpFracHalf < 0 ) // We're closer to higher digit + assert roundingMode >= ROUND_HALF_UP && + roundingMode <= ROUND_HALF_EVEN: "Unexpected rounding mode" + RoundingMode.valueOf(roundingMode); + + if (cmpFracHalf < 0 ) // We're closer to higher digit return false; - else if (roundingMode == ROUND_HALF_UP || - cmpFracHalf > 0 ) // We're closer to lower digit + else if (cmpFracHalf > 0 ) // We're closer to lower digit return true; - else - // roundingMode == ROUND_HALF_EVEN, true iff quotient is odd - return oddQuot; + else { // half-way + assert cmpFracHalf == 0; + + switch(roundingMode) { + case ROUND_HALF_DOWN: + return false; + + case ROUND_HALF_UP: + return true; + + case ROUND_HALF_EVEN: + return oddQuot; + + default: + throw new AssertionError("Unexpected rounding mode" + roundingMode); + } + } } } -- GitLab