ICU-5491 put back functionality for negative multipliers, fixed up some code to handle them correctly, and added tests.
X-SVN-Rev: 23228
This commit is contained in:
parent
46eb0f1212
commit
6c2161e7bd
@ -641,7 +641,8 @@ DecimalFormat::format(int64_t number,
|
|||||||
// instead, trading off accuracy for range.
|
// instead, trading off accuracy for range.
|
||||||
if (fRoundingIncrement != NULL
|
if (fRoundingIncrement != NULL
|
||||||
|| (fMultiplier != 0 && (number > (U_INT64_MAX / fMultiplier)
|
|| (fMultiplier != 0 && (number > (U_INT64_MAX / fMultiplier)
|
||||||
|| number < (U_INT64_MIN / fMultiplier))))
|
|| number < (U_INT64_MIN / fMultiplier)
|
||||||
|
|| number == U_INT64_MIN && fMultiplier < 0)))
|
||||||
{
|
{
|
||||||
digits.set(((double)number) * fMultiplier,
|
digits.set(((double)number) * fMultiplier,
|
||||||
precision(FALSE),
|
precision(FALSE),
|
||||||
@ -682,6 +683,13 @@ DecimalFormat::format( double number,
|
|||||||
return appendTo;
|
return appendTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do this BEFORE checking to see if value is infinite or negative! Sets the
|
||||||
|
// begin and end index to be length of the string composed of
|
||||||
|
// localized name of Infinite and the positive/negative localized
|
||||||
|
// signs.
|
||||||
|
|
||||||
|
number *= fMultiplier;
|
||||||
|
|
||||||
/* Detecting whether a double is negative is easy with the exception of
|
/* Detecting whether a double is negative is easy with the exception of
|
||||||
* the value -0.0. This is a double which has a zero mantissa (and
|
* the value -0.0. This is a double which has a zero mantissa (and
|
||||||
* exponent), but a negative sign bit. It is semantically distinct from
|
* exponent), but a negative sign bit. It is semantically distinct from
|
||||||
@ -694,13 +702,6 @@ DecimalFormat::format( double number,
|
|||||||
*/
|
*/
|
||||||
UBool isNegative = uprv_isNegative(number);
|
UBool isNegative = uprv_isNegative(number);
|
||||||
|
|
||||||
// Do this BEFORE checking to see if value is infinite! Sets the
|
|
||||||
// begin and end index to be length of the string composed of
|
|
||||||
// localized name of Infinite and the positive/negative localized
|
|
||||||
// signs.
|
|
||||||
|
|
||||||
number *= fMultiplier;
|
|
||||||
|
|
||||||
// Apply rounding after multiplier
|
// Apply rounding after multiplier
|
||||||
if (fRoundingIncrement != NULL) {
|
if (fRoundingIncrement != NULL) {
|
||||||
if (isNegative) // For rounding in the correct direction
|
if (isNegative) // For rounding in the correct direction
|
||||||
@ -2100,10 +2101,10 @@ int32_t DecimalFormat::getMultiplier() const
|
|||||||
void
|
void
|
||||||
DecimalFormat::setMultiplier(int32_t newValue)
|
DecimalFormat::setMultiplier(int32_t newValue)
|
||||||
{
|
{
|
||||||
// if (newValue <= 0) {
|
// if (newValue == 0) {
|
||||||
// throw new IllegalArgumentException("Bad multiplier: " + newValue);
|
// throw new IllegalArgumentException("Bad multiplier: " + newValue);
|
||||||
// }
|
// }
|
||||||
if (newValue > 0) {
|
if (newValue != 0) {
|
||||||
fMultiplier = newValue;
|
fMultiplier = newValue;
|
||||||
}
|
}
|
||||||
// else No way to return an error.
|
// else No way to return an error.
|
||||||
|
@ -85,6 +85,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
|
|||||||
CASE(33,TestHostClone);
|
CASE(33,TestHostClone);
|
||||||
CASE(34,TestCurrencyFormat);
|
CASE(34,TestCurrencyFormat);
|
||||||
CASE(35,TestRounding);
|
CASE(35,TestRounding);
|
||||||
|
CASE(36,TestNonpositiveMultiplier);
|
||||||
default: name = ""; break;
|
default: name = ""; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2409,4 +2410,52 @@ double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double las
|
|||||||
return lastParsed;
|
return lastParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NumberFormatTest::TestNonpositiveMultiplier() {
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
DecimalFormatSymbols US(Locale::getUS(), status);
|
||||||
|
CHECK(status, "DecimalFormatSymbols constructor");
|
||||||
|
DecimalFormat df(UnicodeString("0"), US, status);
|
||||||
|
CHECK(status, "DecimalFormat(0)");
|
||||||
|
|
||||||
|
// test zero multiplier
|
||||||
|
|
||||||
|
int32_t mult = df.getMultiplier();
|
||||||
|
df.setMultiplier(0);
|
||||||
|
if (df.getMultiplier() != mult) {
|
||||||
|
errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test negative multiplier
|
||||||
|
|
||||||
|
df.setMultiplier(-1);
|
||||||
|
if (df.getMultiplier() != -1) {
|
||||||
|
errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(df, "1122.123", -1122.123);
|
||||||
|
expect(df, "-1122.123", 1122.123);
|
||||||
|
expect(df, "1.2", -1.2);
|
||||||
|
expect(df, "-1.2", 1.2);
|
||||||
|
|
||||||
|
// TODO: comment once BigInteger is ported
|
||||||
|
// (right now the big numbers get turned into doubles and lose tons of accuracy)
|
||||||
|
expect(df, U_INT64_MIN, "9223372036854780000");
|
||||||
|
|
||||||
|
// TODO: uncomment (and fix up) once BigInteger is ported and DecimalFormat can handle it
|
||||||
|
// (right now the big numbers get turned into doubles and lose tons of accuracy)
|
||||||
|
//expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
|
||||||
|
//expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
|
||||||
|
//expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
|
||||||
|
//expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
|
||||||
|
|
||||||
|
// TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
|
||||||
|
//expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
|
||||||
|
//expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
|
||||||
|
//expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
|
||||||
|
//expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||||
|
@ -129,6 +129,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
|||||||
|
|
||||||
/* Port of ICU4J rounding test. */
|
/* Port of ICU4J rounding test. */
|
||||||
void TestRounding(void);
|
void TestRounding(void);
|
||||||
|
|
||||||
|
void TestNonpositiveMultiplier(void);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static UBool equalValue(const Formattable& a, const Formattable& b);
|
static UBool equalValue(const Formattable& a, const Formattable& b);
|
||||||
|
Loading…
Reference in New Issue
Block a user