OpenJDK / amber / amber
changeset 10430:f338d4485f5c
7086710: java/util/Formatter/Basic.java failing after 7082971
Reviewed-by: alanb
author | darcy |
---|---|
date | Mon, 05 Sep 2011 08:04:04 -0700 |
parents | d274e775b258 |
children | 448fc54a8e23 d6723ee39ebf |
files | jdk/src/share/classes/java/math/BigDecimal.java |
diffstat | 1 files changed, 29 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/java/math/BigDecimal.java Mon Sep 05 11:28:23 2011 +0100 +++ b/jdk/src/share/classes/java/math/BigDecimal.java Mon Sep 05 08:04:04 2011 -0700 @@ -904,12 +904,13 @@ 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 @@ 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 @@ 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); + } + } } }