summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java17
-rw-r--r--icu/src/main/native/NativeDecimalFormat.cpp9
-rw-r--r--luni/src/test/java/java/text/DecimalFormatTest.java99
-rw-r--r--text/src/main/java/java/text/DecimalFormat.java57
-rw-r--r--text/src/main/java/java/text/Format.java4
-rw-r--r--text/src/main/java/java/text/NumberFormat.java26
-rw-r--r--text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java431
7 files changed, 518 insertions, 125 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
index d1da72f..d46c2ec 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
@@ -20,6 +20,7 @@ import com.ibm.icu4jni.util.LocaleData;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.DecimalFormatSymbols;
@@ -570,6 +571,21 @@ public class NativeDecimalFormat {
}
}
+ public void setRoundingMode(RoundingMode roundingMode, double roundingIncrement) {
+ final int nativeRoundingMode;
+ switch (roundingMode) {
+ case CEILING: nativeRoundingMode = 0; break;
+ case FLOOR: nativeRoundingMode = 1; break;
+ case DOWN: nativeRoundingMode = 2; break;
+ case UP: nativeRoundingMode = 3; break;
+ case HALF_EVEN: nativeRoundingMode = 4; break;
+ case HALF_DOWN: nativeRoundingMode = 5; break;
+ case HALF_UP: nativeRoundingMode = 6; break;
+ default: throw new AssertionError();
+ }
+ setRoundingMode(addr, nativeRoundingMode, roundingIncrement);
+ }
+
private static native void applyPatternImpl(int addr, boolean localized, String pattern);
private static native int cloneDecimalFormatImpl(int addr);
private static native void closeDecimalFormatImpl(int addr);
@@ -589,6 +605,7 @@ public class NativeDecimalFormat {
String nan, char patternSeparator, char percent, char perMill, char zeroDigit);
private static native void setSymbol(int addr, int symbol, String str);
private static native void setAttribute(int addr, int symbol, int i);
+ private static native void setRoundingMode(int addr, int roundingMode, double roundingIncrement);
private static native void setTextAttribute(int addr, int symbol, String str);
private static native String toPatternImpl(int addr, boolean localized);
}
diff --git a/icu/src/main/native/NativeDecimalFormat.cpp b/icu/src/main/native/NativeDecimalFormat.cpp
index 413ffdd..b62e5b1 100644
--- a/icu/src/main/native/NativeDecimalFormat.cpp
+++ b/icu/src/main/native/NativeDecimalFormat.cpp
@@ -103,10 +103,16 @@ static jint openDecimalFormatImpl(JNIEnv* env, jclass clazz, jstring pattern0,
return static_cast<jint>(reinterpret_cast<uintptr_t>(fmt));
}
-static void closeDecimalFormatImpl(JNIEnv *env, jclass clazz, jint addr) {
+static void closeDecimalFormatImpl(JNIEnv* env, jclass, jint addr) {
delete toDecimalFormat(addr);
}
+static void setRoundingMode(JNIEnv* env, jclass, jint addr, jint mode, jdouble increment) {
+ DecimalFormat* fmt = toDecimalFormat(addr);
+ fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode>(mode));
+ fmt->setRoundingIncrement(increment);
+}
+
static void setSymbol(JNIEnv* env, jclass, jint addr, jint symbol, jstring s) {
const UChar* chars = env->GetStringChars(s, NULL);
const int32_t charCount = env->GetStringLength(s);
@@ -593,6 +599,7 @@ static JNINativeMethod gMethods[] = {
{"setAttribute", "(III)V", (void*) setAttribute},
{"setDecimalFormatSymbols", "(ILjava/lang/String;CCCLjava/lang/String;Ljava/lang/String;CCLjava/lang/String;CCCC)V", (void*) setDecimalFormatSymbols},
{"setSymbol", "(IILjava/lang/String;)V", (void*) setSymbol},
+ {"setRoundingMode", "(IID)V", (void*) setRoundingMode},
{"setTextAttribute", "(IILjava/lang/String;)V", (void*) setTextAttribute},
{"toPatternImpl", "(IZ)Ljava/lang/String;", (void*) toPatternImpl},
};
diff --git a/luni/src/test/java/java/text/DecimalFormatTest.java b/luni/src/test/java/java/text/DecimalFormatTest.java
index 6b2eb3d..c3a2721 100644
--- a/luni/src/test/java/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/java/text/DecimalFormatTest.java
@@ -19,10 +19,21 @@ package java.text;
import junit.framework.Test;
import junit.framework.TestSuite;
+import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.util.Locale;
public class DecimalFormatTest extends junit.framework.TestCase {
+ public void test_setMaximumFractionDigitsAffectsRoundingMode() throws Exception {
+ DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ df.setMaximumFractionDigits(0);
+ df.setRoundingMode(RoundingMode.HALF_UP);
+ assertEquals("-0", df.format(-0.2));
+ df.setMaximumFractionDigits(1);
+ assertEquals("-0.2", df.format(-0.2));
+ }
+
// Android fails this test, truncating to 127 digits.
public void test_setMaximumIntegerDigits() throws Exception {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
@@ -34,4 +45,92 @@ public class DecimalFormatTest extends junit.framework.TestCase {
assertEquals(309, numberFormat.format(123).length());
assertEquals(309, numberFormat.format(BigInteger.valueOf(123)).length());
}
+
+ // Regression test for http://b/1897917: BigDecimal does not take into account multiplier.
+ public void testBigDecimalBug1897917() {
+ // For example. the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%:
+ NumberFormat pf = NumberFormat.getPercentInstance();
+ assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
+
+ // Test long decimal formatted in PercentInstance with various fractions.
+ String longDec = "11.2345678901234567890123456789012345678901234567890";
+ BigDecimal bd = new BigDecimal(longDec);
+ assertBigDecimalWithFraction(bd, "1,123.46%", 2);
+ assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
+ assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
+ assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
+ assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
+
+ // Test trailing zeros.
+ assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
+ assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
+ assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
+ assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
+ "9,990,000,000,000,000,000,000,000,000,000,000");
+ }
+
+ public void testBigDecimalTestBigIntWithMultiplier() {
+ // Big integer tests.
+ assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0,
+ "1,234,567,890,123,450");
+ assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
+ "123,456,789,012,345,678,900");
+ assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
+ "987,654,321,098,765,432,109,876,543,210");
+
+ assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0,
+ "-1,234,567,890,123,450");
+ assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
+ "-123,456,789,012,345,678,900");
+ assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
+ "-987,654,321,098,765,432,109,876,543,210");
+ }
+
+ public void testBigDecimalICUConsistency() {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
+ df.setMaximumFractionDigits(2);
+ df.setMultiplier(2);
+ assertEquals(df.format(BigDecimal.valueOf(0.16)),
+ df.format(BigDecimal.valueOf(0.16).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.0293)),
+ df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.006)),
+ df.format(BigDecimal.valueOf(0.006).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.00283)),
+ df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1.60)),
+ df.format(BigDecimal.valueOf(1.60).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(15)),
+ df.format(BigDecimal.valueOf(15).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(170)),
+ df.format(BigDecimal.valueOf(170).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(234.56)),
+ df.format(BigDecimal.valueOf(234.56).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0)),
+ df.format(BigDecimal.valueOf(0).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-1)),
+ df.format(BigDecimal.valueOf(-1).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-10000)),
+ df.format(BigDecimal.valueOf(-10000).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-0.001)),
+ df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
+ df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
+ df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+ }
+
+ private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
+ NumberFormat pf = NumberFormat.getPercentInstance();
+ pf.setMaximumFractionDigits(fraction);
+ assertEquals(expectedResult, pf.format(bd));
+ }
+
+ private void assertDecFmtWithMultiplierAndFraction(String value, int multiplier, int fraction, String expectedResult) {
+ DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
+ df.setMultiplier(multiplier);
+ df.setMaximumFractionDigits(fraction);
+ BigDecimal d = new BigDecimal(value);
+ assertEquals(expectedResult, df.format(d));
+ }
}
diff --git a/text/src/main/java/java/text/DecimalFormat.java b/text/src/main/java/java/text/DecimalFormat.java
index 65d4d48..07047b2 100644
--- a/text/src/main/java/java/text/DecimalFormat.java
+++ b/text/src/main/java/java/text/DecimalFormat.java
@@ -27,6 +27,7 @@ import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Currency;
@@ -553,6 +554,8 @@ public class DecimalFormat extends NumberFormat {
private transient NativeDecimalFormat dform;
+ private transient RoundingMode roundingMode = RoundingMode.HALF_EVEN;
+
/**
* Constructs a new {@code DecimalFormat} for formatting and parsing numbers
* for the default locale.
@@ -709,6 +712,21 @@ public class DecimalFormat extends NumberFormat {
@Override
public StringBuffer format(double value, StringBuffer buffer, FieldPosition position) {
+ // All float/double/Float/Double formatting ends up here...
+ if (roundingMode == RoundingMode.UNNECESSARY) {
+ // ICU4C doesn't support this rounding mode, so we have to fake it.
+ try {
+ setRoundingMode(RoundingMode.UP);
+ String upResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+ setRoundingMode(RoundingMode.DOWN);
+ String downResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+ if (!upResult.equals(downResult)) {
+ throw new ArithmeticException("rounding mode UNNECESSARY but rounding required");
+ }
+ } finally {
+ setRoundingMode(RoundingMode.UNNECESSARY);
+ }
+ }
return dform.format(value, buffer, position);
}
@@ -1040,6 +1058,8 @@ public class DecimalFormat extends NumberFormat {
public void setMaximumFractionDigits(int value) {
super.setMaximumFractionDigits(value);
dform.setMaximumFractionDigits(getMaximumFractionDigits());
+ // Changing the maximum fraction digits needs to update ICU4C's rounding configuration.
+ setRoundingMode(roundingMode);
}
/**
@@ -1176,11 +1196,10 @@ public class DecimalFormat extends NumberFormat {
new ObjectStreamField("negSuffixPattern", String.class), //$NON-NLS-1$
new ObjectStreamField("multiplier", int.class), //$NON-NLS-1$
new ObjectStreamField("groupingSize", byte.class), //$NON-NLS-1$
- // BEGIN android-added
new ObjectStreamField("groupingUsed", boolean.class), //$NON-NLS-1$
- // END android-added
new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class), //$NON-NLS-1$
new ObjectStreamField("parseBigDecimal", boolean.class), //$NON-NLS-1$
+ new ObjectStreamField("roundingMode", RoundingMode.class), //$NON-NLS-1$
new ObjectStreamField("symbols", DecimalFormatSymbols.class), //$NON-NLS-1$
new ObjectStreamField("useExponentialNotation", boolean.class), //$NON-NLS-1$
new ObjectStreamField("minExponentDigits", byte.class), //$NON-NLS-1$
@@ -1220,6 +1239,7 @@ public class DecimalFormat extends NumberFormat {
fields.put("decimalSeparatorAlwaysShown", dform
.isDecimalSeparatorAlwaysShown());
fields.put("parseBigDecimal", parseBigDecimal);
+ fields.put("roundingMode", roundingMode);
fields.put("symbols", symbols);
fields.put("useExponentialNotation", false);
fields.put("minExponentDigits", (byte) 0);
@@ -1227,7 +1247,7 @@ public class DecimalFormat extends NumberFormat {
fields.put("minimumIntegerDigits", dform.getMinimumIntegerDigits());
fields.put("maximumFractionDigits", dform.getMaximumFractionDigits());
fields.put("minimumFractionDigits", dform.getMinimumFractionDigits());
- fields.put("serialVersionOnStream", 3);
+ fields.put("serialVersionOnStream", 4);
stream.writeFields();
}
@@ -1243,9 +1263,7 @@ public class DecimalFormat extends NumberFormat {
* if some class of serialized objects or fields cannot be found
*/
@SuppressWarnings("nls")
- private void readObject(ObjectInputStream stream) throws IOException,
- ClassNotFoundException {
-
+ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
// BEGIN android-changed
ObjectInputStream.GetField fields = stream.readFields();
this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
@@ -1260,6 +1278,8 @@ public class DecimalFormat extends NumberFormat {
dform.setGroupingUsed(fields.get("groupingUsed", true));
dform.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown", false));
+ setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN));
+
final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
@@ -1285,4 +1305,29 @@ public class DecimalFormat extends NumberFormat {
}
// END android-changed
}
+
+ /**
+ * Returns the {@code RoundingMode} used by this {@code NumberFormat}.
+ * @since 1.6
+ * @hide
+ */
+ public RoundingMode getRoundingMode() {
+ return roundingMode;
+ }
+
+ /**
+ * Sets the {@code RoundingMode} used by this {@code NumberFormat}.
+ * @since 1.6
+ * @hide
+ */
+ public void setRoundingMode(RoundingMode roundingMode) {
+ if (roundingMode == null) {
+ throw new NullPointerException();
+ }
+ this.roundingMode = roundingMode;
+ if (roundingMode != RoundingMode.UNNECESSARY) { // ICU4C doesn't support UNNECESSARY.
+ double roundingIncrement = 1.0 / Math.pow(10, Math.max(0, getMaximumFractionDigits()));
+ dform.setRoundingMode(roundingMode, roundingIncrement);
+ }
+ }
}
diff --git a/text/src/main/java/java/text/Format.java b/text/src/main/java/java/text/Format.java
index 18b0490..ff62856 100644
--- a/text/src/main/java/java/text/Format.java
+++ b/text/src/main/java/java/text/Format.java
@@ -66,9 +66,9 @@ public abstract class Format implements Serializable, Cloneable {
private static final long serialVersionUID = -299282585814624189L;
/**
- * Constructs a new {@code Format} instance.
+ * Used by subclasses. This was public in Java 5.
*/
- public Format() {
+ protected Format() {
}
/**
diff --git a/text/src/main/java/java/text/NumberFormat.java b/text/src/main/java/java/text/NumberFormat.java
index 0ad6ac4..2bf898d 100644
--- a/text/src/main/java/java/text/NumberFormat.java
+++ b/text/src/main/java/java/text/NumberFormat.java
@@ -27,6 +27,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.util.Currency;
import java.util.Locale;
@@ -164,9 +165,9 @@ public abstract class NumberFormat extends Format {
maximumFractionDigits = 3, minimumFractionDigits = 0;
/**
- * Constructs a new instance of {@code NumberFormat}.
+ * Used by subclasses. This was public in Java 5.
*/
- public NumberFormat() {
+ protected NumberFormat() {
}
/**
@@ -896,4 +897,25 @@ public abstract class NumberFormat extends Format {
}
}
+ /**
+ * Returns the {@code RoundingMode} used by this {@code NumberFormat}. The default
+ * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+ * Subclasses for which a rounding mode is meaningful are expected to override this method.
+ * @since 1.6
+ * @hide
+ */
+ public RoundingMode getRoundingMode() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the {@code RoundingMode} used by this {@code NumberFormat}. The default
+ * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+ * Subclasses for which a rounding mode is meaningful are expected to override this method.
+ * @since 1.6
+ * @hide
+ */
+ public void setRoundingMode(RoundingMode roundingMode) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
index 92aaf71..d7f0eaa 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
@@ -35,6 +35,7 @@ import java.io.ObjectInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.text.AttributedCharacterIterator;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
@@ -2563,119 +2564,321 @@ public class DecimalFormatTest extends TestCase {
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance();
format.setDecimalFormatSymbols(null);
}
-
- private void assertBigDecimalWithFraction(
- BigDecimal bd,
- String expectedResult,
- int fraction) {
- NumberFormat pf = NumberFormat.getPercentInstance();
- pf.setMaximumFractionDigits(fraction);
- assertEquals(expectedResult, pf.format(bd));
- }
-
- private void assertDecFmtWithMultiplierAndFraction(
- String value,
- int multiplier,
- int fraction,
- String expectedResult) {
-
- DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
- df.setMultiplier(multiplier);
- df.setMaximumFractionDigits(fraction);
- BigDecimal d = new BigDecimal(value);
- assertEquals(expectedResult, df.format(d));
- }
-
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- notes = "Regression test for some existing bugs and crashes",
- method = "format",
- args = { String.class, Object[].class }
- )
- public void testBigDecimalBug1897917() {
- // Bug1897917 : BigDecimal does not take into account multiplier.
- // So the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%.
-
- NumberFormat pf = NumberFormat.getPercentInstance();
-
- // Test bug 1897917 case.
- assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
-
- // Test long decimal formatted in PercentInstance with various fractions.
- String longDec = "11.2345678901234567890123456789012345678901234567890";
- BigDecimal bd = new BigDecimal(longDec);
- assertBigDecimalWithFraction(bd, "1,123.46%", 2);
- assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
- assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
- assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
- assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
-
- // Test trailing zeros.
- assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
- assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
- assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
- assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
- "9,990,000,000,000,000,000,000,000,000,000,000");
- }
-
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- notes = "Regression test for some existing bugs and crashes",
- method = "format",
- args = { String.class, Object[].class }
- )
- public void testBigDecimalTestBigIntWithMultiplier() {
- // Big integer tests.
- assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0, "1,234,567,890,123,450");
- assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
- "123,456,789,012,345,678,900");
- assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
- "987,654,321,098,765,432,109,876,543,210");
-
- assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0, "-1,234,567,890,123,450");
- assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
- "-123,456,789,012,345,678,900");
- assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
- "-987,654,321,098,765,432,109,876,543,210");
- }
-
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- notes = "Regression test for some existing bugs and crashes",
- method = "format",
- args = { String.class, Object[].class }
- )
- public void testBigDecimalICUConsistency() {
- DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
- df.setMaximumFractionDigits(2);
- df.setMultiplier(2);
- assertEquals(df.format(BigDecimal.valueOf(0.16)),
- df.format(BigDecimal.valueOf(0.16).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(0.0293)),
- df.format(BigDecimal.valueOf(0.0293).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(0.006)),
- df.format(BigDecimal.valueOf(0.006).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(0.00283)),
- df.format(BigDecimal.valueOf(0.00283).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(1.60)),
- df.format(BigDecimal.valueOf(1.60).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(15)),
- df.format(BigDecimal.valueOf(15).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(170)),
- df.format(BigDecimal.valueOf(170).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(234.56)),
- df.format(BigDecimal.valueOf(234.56).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(0)),
- df.format(BigDecimal.valueOf(0).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(-1)),
- df.format(BigDecimal.valueOf(-1).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(-10000)),
- df.format(BigDecimal.valueOf(-10000).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(-0.001)),
- df.format(BigDecimal.valueOf(-0.001).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
- df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
- assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
- df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+
+ // BEGIN android-added: brought back from the harmony java6 branch.
+ public void test_SetRoudingMode_Ljava_math_RoundingMode() {
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ // ignore the fraction part of a given value
+ decimalFormat.setMaximumFractionDigits(0);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ String result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.6);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+
+ // BEGIN android-changed: we're RI-compatible.
+ // the following assertion will fail on RI implementation, since the
+ // implementation of ICU and RI are not identical.
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+ // END android-changed
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+
+ try {
+ // when rounding is needed but RoundingMode is set to RoundingMode.UNNECESSARY, throw ArithmeticException
+ result = decimalFormat.format(5.5);
+ fail("ArithmeticException expected: RoundingMode.UNNECESSARY");
+ } catch (ArithmeticException e) {
+ // expected
+ }
+
+ result = decimalFormat.format(1.0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+
+ result = decimalFormat.format(-1.0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
+
+ try {
+ // when the given RoundingMode is null, throw NullPointerException
+ decimalFormat.setRoundingMode(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // set MaxFractionDigits to 3, test different DecimalFormat format
+ // function with differnt RoundingMode
+ decimalFormat.setMaximumFractionDigits(3);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+
+ result = decimalFormat.format(11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.566", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "11.566", result);
+
+ result = decimalFormat.format(-11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11.565", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11.565", result);
+
+ result = decimalFormat.format(-11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11.565", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-11.566", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-11.566", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.566", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-11.566", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.566", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "11.566", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-11.566", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+ result = decimalFormat.format(-11.565);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-11.565", result);
+
+ result = decimalFormat.format(11.565);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "11.565", result);
+
+ // when setting MaxFractionDigits to negative value -2, default it as
+ // zero, test different DecimalFormat format
+ // function with differnt RoundingMode
+ decimalFormat.setMaximumFractionDigits(-2);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.6);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+
+ result = decimalFormat.format(1.0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+
+ result = decimalFormat.format(-1.0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
}
}