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.
|
||||
if (fRoundingIncrement != NULL
|
||||
|| (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,
|
||||
precision(FALSE),
|
||||
@ -682,6 +683,13 @@ DecimalFormat::format( double number,
|
||||
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
|
||||
* 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
|
||||
@ -694,13 +702,6 @@ DecimalFormat::format( double 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
|
||||
if (fRoundingIncrement != NULL) {
|
||||
if (isNegative) // For rounding in the correct direction
|
||||
@ -2100,10 +2101,10 @@ int32_t DecimalFormat::getMultiplier() const
|
||||
void
|
||||
DecimalFormat::setMultiplier(int32_t newValue)
|
||||
{
|
||||
// if (newValue <= 0) {
|
||||
// throw new IllegalArgumentException("Bad multiplier: " + newValue);
|
||||
// }
|
||||
if (newValue > 0) {
|
||||
// if (newValue == 0) {
|
||||
// throw new IllegalArgumentException("Bad multiplier: " + newValue);
|
||||
// }
|
||||
if (newValue != 0) {
|
||||
fMultiplier = newValue;
|
||||
}
|
||||
// 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(34,TestCurrencyFormat);
|
||||
CASE(35,TestRounding);
|
||||
CASE(36,TestNonpositiveMultiplier);
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
@ -2409,4 +2410,52 @@ double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double las
|
||||
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 */
|
||||
|
@ -129,6 +129,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
||||
|
||||
/* Port of ICU4J rounding test. */
|
||||
void TestRounding(void);
|
||||
|
||||
void TestNonpositiveMultiplier(void);
|
||||
private:
|
||||
|
||||
static UBool equalValue(const Formattable& a, const Formattable& b);
|
||||
|
Loading…
Reference in New Issue
Block a user