number *= multiplier;
synchronized (digitList) {
digitList.set(number, precision(true));
+ // Issue 11808
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
return subformat(number, result, fieldPosition, isNegative, true, parseAttr);
}
}
// number.
synchronized (digitList) {
digitList.set(number, precision(true));
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
return subformat(number.intValue(), result, fieldPosition, number.signum() < 0, true,
parseAttr);
}
synchronized (digitList) {
digitList.set(number, precision(false), !useExponentialNotation &&
!areSignificantDigitsUsed());
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0,
false, parseAttr);
}
synchronized (digitList) {
digitList.set(number, precision(false), !useExponentialNotation &&
!areSignificantDigitsUsed());
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0,
false, false);
}
/*
*******************************************************************************
- * Copyright (C) 1996-2011, International Business Machines Corporation and *
+ * Copyright (C) 1996-2015, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
// DDDDDE+/-DDDDD.
String rep = Double.toString(source);
+ didRound = false;
+
set(rep, MAX_LONG_DIGITS);
if (fixedPoint) {
digits[0] = (byte) '1';
++decimalAt;
maximumDigits = 0; // Adjust the count
+ didRound = true;
break;
}
++digits[maximumDigits];
+ didRound = true;
if (digits[maximumDigits] <= '9') break;
// digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
}
}
}
+ // Value to indicate that rounding was done.
+ private boolean didRound = false;
+
+ /**
+ * Indicates if last digit set was rounded or not.
+ * true indicates it was rounded.
+ * false indicates rounding has not been done.
+ */
+ public boolean wasRounded() {
+ return didRound;
+ }
+
/**
* Utility routine to set the value of the digit list from a long
*/
// which is outside the legal range of a long, but which can
// be represented by DigitList.
// [NEW] Faster implementation
+ didRound = false;
+
if (source <= 0) {
if (source == Long.MIN_VALUE) {
decimalAt = count = MAX_LONG_DIGITS;
String stringDigits = source.toString();
count = decimalAt = stringDigits.length();
-
+ didRound = false;
+
// Don't copy trailing zeros
while (count > 1 && stringDigits.charAt(count - 1) == '0') --count;
//| }
//| }
+ didRound = false;
+
// The maxDigits here could also be Integer.MAX_VALUE
set(stringDigits, stringDigits.length());
new NumberFormatTestTuple().toString();
}
+ // Testing for Issue 11808.
+ public void TestRoundUnnecessarytIssue11808 () {
+ DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance();
+ StringBuffer result = new StringBuffer("");
+ df.setRoundingMode(BigDecimal.ROUND_UNNECESSARY);
+ df.applyPattern("00.0#E0");
+
+ try {
+ df.format(99999.0, result, new FieldPosition(0));
+ fail("Missing ArithmeticException for double: " + result);
+ } catch (ArithmeticException expected) {
+ // The exception should be thrown, since rounding is needed.
+ }
+
+ try {
+ result = df.format(99999, result, new FieldPosition(0));
+ fail("Missing ArithmeticException for int: " + result);
+ } catch (ArithmeticException expected) {
+ // The exception should be thrown, since rounding is needed.
+ }
+
+ try {
+ result = df.format(new BigInteger("999999"), result, new FieldPosition(0));
+ fail("Missing ArithmeticException for BigInteger: " + result);
+ } catch (ArithmeticException expected) {
+ // The exception should be thrown, since rounding is needed.
+ }
+
+ try {
+ result = df.format(new BigDecimal("99999"), result, new FieldPosition(0));
+ fail("Missing ArithmeticException for BigDecimal: " + result);
+ } catch (ArithmeticException expected) {
+ // The exception should be thrown, since rounding is needed.
+ }
+
+ try {
+ result = df.format(new BigDecimal("-99999"), result, new FieldPosition(0));
+ fail("Missing ArithmeticException for BigDecimal: " + result);
+ } catch (ArithmeticException expected) {
+ // The exception should be thrown, since rounding is needed.
+ }
+ }
}