diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java index 2e8c2ad761..e33405d12b 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java @@ -9,7 +9,6 @@ import java.math.RoundingMode; import java.text.ParseException; import java.util.ArrayList; import java.util.List; -import java.util.Random; import org.junit.Ignore; import org.junit.Test; @@ -356,91 +355,6 @@ public class DecimalQuantityTest extends TestFmwk { assertNull("Failed health check", fq.checkHealth()); } - @Ignore - @Test - public void testConvertToAccurateDouble() { - // based on https://github.com/google/double-conversion/issues/28 - double[] hardDoubles = { - 1651087494906221570.0, - -5074790912492772E-327, - 83602530019752571E-327, - 2.207817077636718750000000000000, - 1.818351745605468750000000000000, - 3.941719055175781250000000000000, - 3.738609313964843750000000000000, - 3.967735290527343750000000000000, - 1.328025817871093750000000000000, - 3.920967102050781250000000000000, - 1.015235900878906250000000000000, - 1.335227966308593750000000000000, - 1.344520568847656250000000000000, - 2.879127502441406250000000000000, - 3.695838928222656250000000000000, - 1.845344543457031250000000000000, - 3.793952941894531250000000000000, - 3.211402893066406250000000000000, - 2.565971374511718750000000000000, - 0.965156555175781250000000000000, - 2.700004577636718750000000000000, - 0.767097473144531250000000000000, - 1.780448913574218750000000000000, - 2.624839782714843750000000000000, - 1.305290222167968750000000000000, - 3.834922790527343750000000000000, }; - - double[] integerDoubles = { - 51423, - 51423e10, - 4.503599627370496E15, - 6.789512076111555E15, - 9.007199254740991E15, - 9.007199254740992E15 }; - - for (double d : hardDoubles) { - checkDoubleBehavior(d, true, ""); - } - - for (double d : integerDoubles) { - checkDoubleBehavior(d, false, ""); - } - - assertEquals("NaN check failed", - Double.NaN, - new DecimalQuantity_DualStorageBCD(Double.NaN).toDouble()); - assertEquals("Inf check failed", - Double.POSITIVE_INFINITY, - new DecimalQuantity_DualStorageBCD(Double.POSITIVE_INFINITY).toDouble()); - assertEquals("-Inf check failed", - Double.NEGATIVE_INFINITY, - new DecimalQuantity_DualStorageBCD(Double.NEGATIVE_INFINITY).toDouble()); - - // Generate random doubles - String alert = "UNEXPECTED FAILURE: PLEASE REPORT THIS MESSAGE TO THE ICU TEAM: "; - Random rnd = new Random(); - for (int i = 0; i < 10000; i++) { - double d = Double.longBitsToDouble(rnd.nextLong()); - if (Double.isNaN(d) || Double.isInfinite(d)) - continue; - checkDoubleBehavior(d, false, alert); - } - } - - private static void checkDoubleBehavior(double d, boolean explicitRequired, String alert) { - DecimalQuantity_DualStorageBCD fq = new DecimalQuantity_DualStorageBCD(d); - if (explicitRequired) { - assertTrue(alert + "Should be using approximate double", !fq.explicitExactDouble); - } - assertEquals(alert + "Initial construction from hard double", d, fq.toDouble()); - fq.roundToInfinity(); - if (explicitRequired) { - assertTrue(alert + "Should not be using approximate double", fq.explicitExactDouble); - } - assertDoubleEquals(alert + "After conversion to exact BCD (double)", d, fq.toDouble()); - assertBigDecimalEquals(alert + "After conversion to exact BCD (BigDecimal)", - new BigDecimal(Double.toString(d)), - fq.toBigDecimal()); - } - @Test public void testUseApproximateDoubleWhenAble() { Object[][] cases = { diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java new file mode 100644 index 0000000000..e2cabc8e4a --- /dev/null +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java @@ -0,0 +1,124 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html#License +package com.ibm.icu.dev.test.number; + +import java.math.BigDecimal; +import java.util.Random; + +import org.junit.Before; +import org.junit.Test; + +import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD; +import com.ibm.icu.number.NumberFormatter; +import com.ibm.icu.number.Rounder; +import com.ibm.icu.util.ULocale; + +/** + * Tests that are disabled except in exhaustive mode due to runtime. + * + * @author sffc + */ +public class ExhaustiveNumberTest extends TestFmwk { + @Before + public void beforeMethod() { + // Disable this test class except for exhaustive mode. + // To enable exhaustive mode, pass the JVM argument "-DICU.exhaustive=10" + org.junit.Assume.assumeTrue(getExhaustiveness() > 5); + } + + @Test + public void unlimitedRoundingBigDecimal() { + BigDecimal ten10000 = BigDecimal.valueOf(10).pow(10000); + BigDecimal longFraction = ten10000.subtract(BigDecimal.ONE).divide(ten10000); + String expected = longFraction.toPlainString(); + String actual = NumberFormatter.withLocale(ULocale.ENGLISH).rounding(Rounder.unlimited()) + .format(longFraction).toString(); + assertEquals("All digits should be displayed", expected, actual); + } + + @Test + public void testConvertToAccurateDouble() { + // based on https://github.com/google/double-conversion/issues/28 + double[] hardDoubles = { + 1651087494906221570.0, + -5074790912492772E-327, + 83602530019752571E-327, + 2.207817077636718750000000000000, + 1.818351745605468750000000000000, + 3.941719055175781250000000000000, + 3.738609313964843750000000000000, + 3.967735290527343750000000000000, + 1.328025817871093750000000000000, + 3.920967102050781250000000000000, + 1.015235900878906250000000000000, + 1.335227966308593750000000000000, + 1.344520568847656250000000000000, + 2.879127502441406250000000000000, + 3.695838928222656250000000000000, + 1.845344543457031250000000000000, + 3.793952941894531250000000000000, + 3.211402893066406250000000000000, + 2.565971374511718750000000000000, + 0.965156555175781250000000000000, + 2.700004577636718750000000000000, + 0.767097473144531250000000000000, + 1.780448913574218750000000000000, + 2.624839782714843750000000000000, + 1.305290222167968750000000000000, + 3.834922790527343750000000000000, }; + + double[] integerDoubles = { + 51423, + 51423e10, + 4.503599627370496E15, + 6.789512076111555E15, + 9.007199254740991E15, + 9.007199254740992E15 }; + + for (double d : hardDoubles) { + checkDoubleBehavior(d, true, ""); + } + + for (double d : integerDoubles) { + checkDoubleBehavior(d, false, ""); + } + + assertEquals("NaN check failed", + Double.NaN, + new DecimalQuantity_DualStorageBCD(Double.NaN).toDouble()); + assertEquals("Inf check failed", + Double.POSITIVE_INFINITY, + new DecimalQuantity_DualStorageBCD(Double.POSITIVE_INFINITY).toDouble()); + assertEquals("-Inf check failed", + Double.NEGATIVE_INFINITY, + new DecimalQuantity_DualStorageBCD(Double.NEGATIVE_INFINITY).toDouble()); + + // Generate random doubles + String alert = "UNEXPECTED FAILURE: PLEASE REPORT THIS MESSAGE TO THE ICU TEAM: "; + Random rnd = new Random(); + for (int i = 0; i < 100000; i++) { + double d = Double.longBitsToDouble(rnd.nextLong()); + if (Double.isNaN(d) || Double.isInfinite(d)) + continue; + checkDoubleBehavior(d, false, alert); + } + } + + private static void checkDoubleBehavior(double d, boolean explicitRequired, String alert) { + DecimalQuantity_DualStorageBCD fq = new DecimalQuantity_DualStorageBCD(d); + if (explicitRequired) { + assertTrue(alert + "Should be using approximate double", !fq.explicitExactDouble); + } + assertEquals(alert + "Initial construction from hard double", d, fq.toDouble()); + fq.roundToInfinity(); + if (explicitRequired) { + assertTrue(alert + "Should not be using approximate double", fq.explicitExactDouble); + } + DecimalQuantityTest + .assertDoubleEquals(alert + "After conversion to exact BCD (double)", d, fq.toDouble()); + DecimalQuantityTest.assertBigDecimalEquals(alert + "After conversion to exact BCD (BigDecimal)", + new BigDecimal(Double.toString(d)), + fq.toBigDecimal()); + } +} diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java index 58d709f856..968f7a13a5 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java @@ -2009,7 +2009,7 @@ public class NumberFormatterApiTest { } } - private static void assertFormatDescending( + static void assertFormatDescending( String message, String skeleton, UnlocalizedNumberFormatter f, @@ -2019,7 +2019,7 @@ public class NumberFormatterApiTest { assertFormatDescending(message, skeleton, f, locale, inputs, expected); } - private static void assertFormatDescendingBig( + static void assertFormatDescendingBig( String message, String skeleton, UnlocalizedNumberFormatter f, @@ -2029,7 +2029,7 @@ public class NumberFormatterApiTest { assertFormatDescending(message, skeleton, f, locale, inputs, expected); } - private static void assertFormatDescending( + static void assertFormatDescending( String message, String skeleton, UnlocalizedNumberFormatter f, @@ -2062,7 +2062,7 @@ public class NumberFormatterApiTest { } } - private static void assertFormatSingle( + static void assertFormatSingle( String message, String skeleton, UnlocalizedNumberFormatter f, @@ -2088,7 +2088,7 @@ public class NumberFormatterApiTest { } } - private static void assertFormatSingleMeasure( + static void assertFormatSingleMeasure( String message, String skeleton, UnlocalizedNumberFormatter f, @@ -2114,7 +2114,7 @@ public class NumberFormatterApiTest { } } - private static void assertUndefinedSkeleton(UnlocalizedNumberFormatter f) { + static void assertUndefinedSkeleton(UnlocalizedNumberFormatter f) { try { String skeleton = f.toSkeleton(); fail("Expected toSkeleton to fail, but it passed, producing: " + skeleton);