From e1a7ad244f0e231f0efa7dcff868747698da67f0 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Thu, 14 Nov 2013 18:57:06 +0000 Subject: [PATCH] ICU-10545 Added test to verify rounding scientific notation works. X-SVN-Rev: 34660 --- icu4c/source/test/intltest/numfmtst.cpp | 196 +++++++++++++++++++++++- icu4c/source/test/intltest/numfmtst.h | 11 ++ 2 files changed, 206 insertions(+), 1 deletion(-) diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index 095f5f44570..10f5e56a55a 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -132,6 +132,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n TESTCASE_AUTO(TestParseSignsAndMarks); TESTCASE_AUTO(Test10419RoundingWith0FractionDigits); TESTCASE_AUTO(Test10468ApplyPattern); + TESTCASE_AUTO(TestRoundingScientific10542); TESTCASE_AUTO_END; } @@ -7310,7 +7311,7 @@ void NumberFormatTest::Test10419RoundingWith0FractionDigits() { dataerrln("Failure creating DecimalFormat %s", u_errorName(status)); return; } - for (int32_t i = 0; i < sizeof(items) / sizeof(items[0]); ++i) { + for (int32_t i = 0; i < (int32_t) (sizeof(items) / sizeof(items[0])); ++i) { decfmt->setRoundingMode(items[i].mode); decfmt->setMaximumFractionDigits(0); UnicodeString actual; @@ -7340,5 +7341,198 @@ void NumberFormatTest::Test10468ApplyPattern() { } } +void NumberFormatTest::TestRoundingScientific10542() { + UErrorCode status = U_ZERO_ERROR; + DecimalFormat format("0.00E0", status); + + DecimalFormat::ERoundingMode roundingModes[] = { + DecimalFormat::kRoundCeiling, + DecimalFormat::kRoundDown, + DecimalFormat::kRoundFloor, + DecimalFormat::kRoundHalfDown, + DecimalFormat::kRoundHalfEven, + DecimalFormat::kRoundHalfUp, + DecimalFormat::kRoundUp}; + const char *descriptions[] = { + "Round Ceiling", + "Round Down", + "Round Floor", + "Round half down", + "Round half even", + "Round half up", + "Round up"}; + + { + double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3", + "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3", + "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3", + "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3", + "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3", + "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3", + "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } + { + double values[] = {-3006.0, -3005, -3004, 3014, 3015, 3016}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3", + "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3", + "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3", + "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3", + "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3", + "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3", + "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } +/* Commented out for now until we decide how rounding to zero should work, +0 vs. -0 + { + double values[] = {0.0, -0.0}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0", + "0.00E0", "-0.00E0"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } +*/ + { + + double values[] = {1e25, 1e25 + 1e15, 1e25 - 1e15}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "1.00E25", "1.01E25", "1.00E25", + "1.00E25", "1.00E25", "9.99E24", + "1.00E25", "1.00E25", "9.99E24", + "1.00E25", "1.00E25", "1.00E25", + "1.00E25", "1.00E25", "1.00E25", + "1.00E25", "1.00E25", "1.00E25", + "1.00E25", "1.01E25", "1.00E25"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } + { + double values[] = {-1e25, -1e25 + 1e15, -1e25 - 1e15}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "-1.00E25", "-9.99E24", "-1.00E25", + "-1.00E25", "-9.99E24", "-1.00E25", + "-1.00E25", "-1.00E25", "-1.01E25", + "-1.00E25", "-1.00E25", "-1.00E25", + "-1.00E25", "-1.00E25", "-1.00E25", + "-1.00E25", "-1.00E25", "-1.00E25", + "-1.00E25", "-1.00E25", "-1.01E25"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } + { + double values[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "1.00E-25", "1.01E-25", "1.00E-25", + "1.00E-25", "1.00E-25", "9.99E-26", + "1.00E-25", "1.00E-25", "9.99E-26", + "1.00E-25", "1.00E-25", "1.00E-25", + "1.00E-25", "1.00E-25", "1.00E-25", + "1.00E-25", "1.00E-25", "1.00E-25", + "1.00E-25", "1.01E-25", "1.00E-25"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } + { + double values[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35}; + // The order of these expected values correspond to the order of roundingModes and the order of values. + const char *expected[] = { + "-1.00E-25", "-9.99E-26", "-1.00E-25", + "-1.00E-25", "-9.99E-26", "-1.00E-25", + "-1.00E-25", "-1.00E-25", "-1.01E-25", + "-1.00E-25", "-1.00E-25", "-1.00E-25", + "-1.00E-25", "-1.00E-25", "-1.00E-25", + "-1.00E-25", "-1.00E-25", "-1.00E-25", + "-1.00E-25", "-1.00E-25", "-1.01E-25"}; + verifyRounding( + format, + values, + expected, + roundingModes, + descriptions, + (int32_t) (sizeof(values) / sizeof(values[0])), + (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); + } +} + +void NumberFormatTest::verifyRounding( + DecimalFormat& format, + const double *values, + const char * const *expected, + const DecimalFormat::ERoundingMode *roundingModes, + const char * const *descriptions, + int32_t valueSize, + int32_t roundingModeSize) { + for (int32_t i = 0; i < roundingModeSize; ++i) { + format.setRoundingMode(roundingModes[i]); + for (int32_t j = 0; j < valueSize; j++) { + UnicodeString currentExpected(expected[i * valueSize + j]); + currentExpected = currentExpected.unescape(); + UnicodeString actual; + format.format(values[j], actual); + if (currentExpected != actual) { + char buffer[256]; + sprintf( + buffer, + "For %s value %f, expected ", + descriptions[i], + values[j]); + errln(UnicodeString(buffer) + currentExpected + ", got " + actual); + } + } + } +} #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h index 9f67bcd6801..28cf5a2d273 100644 --- a/icu4c/source/test/intltest/numfmtst.h +++ b/icu4c/source/test/intltest/numfmtst.h @@ -177,6 +177,7 @@ class NumberFormatTest: public CalendarTimeZoneTest { void TestParseSignsAndMarks(); void Test10419RoundingWith0FractionDigits(); void Test10468ApplyPattern(); + void TestRoundingScientific10542(); private: UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f); @@ -277,6 +278,16 @@ class NumberFormatTest: public CalendarTimeZoneTest { void checkRounding(DecimalFormat* df, double base, int iterations, double increment); double checkRound(DecimalFormat* df, double iValue, double lastParsed); + + void verifyRounding( + DecimalFormat& format, + const double *values, + const char * const *expected, + const DecimalFormat::ERoundingMode *roundingModes, + const char * const *descriptions, + int32_t valueSize, + int32_t roundingModeSize); + }; #endif /* #if !UCONFIG_NO_FORMATTING */ -- 2.40.0