From 02669ad1bc7efe4564ac58e92ebccb693110ccdf Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Fri, 30 Mar 2018 07:22:24 +0000 Subject: [PATCH] ICU-13634 Fixes for NumberFormatTest/TestExponential. X-SVN-Rev: 41177 --- icu4c/source/i18n/fmtable.cpp | 15 ++++++--------- icu4c/source/i18n/number_decimalquantity.cpp | 4 ++++ icu4c/source/i18n/number_decimalquantity.h | 3 +++ icu4c/source/i18n/numparse_parsednumber.cpp | 2 +- .../test/intltest/numbertest_decimalquantity.cpp | 4 +++- icu4c/source/test/intltest/numfmtst.cpp | 7 ++++--- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/icu4c/source/i18n/fmtable.cpp b/icu4c/source/i18n/fmtable.cpp index 862b5f912e5..e4c119aea67 100644 --- a/icu4c/source/i18n/fmtable.cpp +++ b/icu4c/source/i18n/fmtable.cpp @@ -768,17 +768,14 @@ Formattable::adoptDecimalQuantity(DecimalQuantity *dq) { } // Set the value into the Union of simple type values. - // Cannot use the set() functions because they would delete the fDecimalNum value, - // TODO: fDecimalQuantity->fitsInInt() to kLong type. - /* - if (fDecimalQuantity->fitsInInt()) { - fType = kLong; - fValue.fInt64 = fDecimalNum->getLong(); - } else - */ + // Cannot use the set() functions because they would delete the fDecimalNum value. if (fDecimalQuantity->fitsInLong()) { - fType = kInt64; fValue.fInt64 = fDecimalQuantity->toLong(); + if (fValue.fInt64 <= INT32_MAX && fValue.fInt64 >= INT32_MIN) { + fType = kLong; + } else { + fType = kInt64; + } } else { fType = kDouble; fValue.fDouble = fDecimalQuantity->toDouble(); diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp index 1d712b5ce42..a63044f9812 100644 --- a/icu4c/source/i18n/number_decimalquantity.cpp +++ b/icu4c/source/i18n/number_decimalquantity.cpp @@ -202,6 +202,10 @@ void DecimalQuantity::multiplyBy(int32_t multiplicand) { setToDouble(temp); } +void DecimalQuantity::negate() { + flags ^= NEGATIVE_FLAG; +} + int32_t DecimalQuantity::getMagnitude() const { U_ASSERT(precision != 0); return scale + precision - 1; diff --git a/icu4c/source/i18n/number_decimalquantity.h b/icu4c/source/i18n/number_decimalquantity.h index 10f2e669b8a..74c85248c4a 100644 --- a/icu4c/source/i18n/number_decimalquantity.h +++ b/icu4c/source/i18n/number_decimalquantity.h @@ -95,6 +95,9 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory { */ void multiplyBy(int32_t multiplicand); + /** Flips the sign from positive to negative and back. C++-only: not currently needed in Java. */ + void negate(); + /** * Scales the number by a power of ten. For example, if the value is currently "1234.56", calling * this method with delta=-3 will change the value to "1.23456". diff --git a/icu4c/source/i18n/numparse_parsednumber.cpp b/icu4c/source/i18n/numparse_parsednumber.cpp index b9cc54e6272..16da923459e 100644 --- a/icu4c/source/i18n/numparse_parsednumber.cpp +++ b/icu4c/source/i18n/numparse_parsednumber.cpp @@ -108,7 +108,7 @@ void ParsedNumber::populateFormattable(Formattable& output) const { // All other numbers LocalPointer actualQuantity(new DecimalQuantity(quantity)); if (0 != (flags & FLAG_NEGATIVE)) { - actualQuantity->multiplyBy(-1); + actualQuantity->negate(); } output.adoptDecimalQuantity(actualQuantity.orphan()); } diff --git a/icu4c/source/test/intltest/numbertest_decimalquantity.cpp b/icu4c/source/test/intltest/numbertest_decimalquantity.cpp index b260614dff5..2b313808791 100644 --- a/icu4c/source/test/intltest/numbertest_decimalquantity.cpp +++ b/icu4c/source/test/intltest/numbertest_decimalquantity.cpp @@ -296,6 +296,7 @@ void DecimalQuantityTest::testHardDoubleConversion() { } void DecimalQuantityTest::testToDouble() { + IcuTestErrorCode status(*this, "testToDouble"); static const struct TestCase { const char* input; // char* for the decNumber constructor double expected; @@ -304,8 +305,9 @@ void DecimalQuantityTest::testToDouble() { { "-3.142E-271", -3.142e-271 } }; for (auto& cas : cases) { + status.setScope(cas.input); DecimalQuantity q; - q.setToDecNumber({cas.input, -1}); + q.setToDecNumber({cas.input, -1}, status); double actual = q.toDouble(); assertEquals("Doubles should exactly equal", cas.expected, actual); } diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index ee638ea36aa..d042ccd7c86 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -927,7 +927,7 @@ NumberFormatTest::TestExponential(void) #endif } else { - errln((UnicodeString)"FAIL: Non-numeric Formattable returned"); + errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern + " " + s); continue; } if (pos.getIndex() == s.length()) @@ -938,7 +938,8 @@ NumberFormatTest::TestExponential(void) (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) || (!useEpsilon && a != valParse[v+ival])) { - errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]); + errln((UnicodeString)"FAIL: Expected " + valParse[v+ival] + " but got " + a + + " on input " + s); } } else { @@ -965,7 +966,7 @@ NumberFormatTest::TestExponential(void) { logln((UnicodeString)" -parse-> " + a); if (a != lvalParse[v+ilval]) - errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]); + errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval] + " but got " + a); } else errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);