mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-10273 Plural Rules Fixed Decimal, improve handling of NaN and Infinity
X-SVN-Rev: 34225
This commit is contained in:
parent
bd7fd3318f
commit
4d9fad13ef
4 changed files with 42 additions and 15 deletions
|
@ -1024,6 +1024,17 @@ DecimalFormat::clone() const
|
|||
FixedDecimal
|
||||
DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const {
|
||||
FixedDecimal result;
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (uprv_isNaN(number) || uprv_isPositiveInfinity(fabs(number))) {
|
||||
// For NaN and Infinity the state of the formatter is ignored.
|
||||
result.init(number);
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t minFractionDigits = getMinimumFractionDigits();
|
||||
|
||||
if (fMultiplier == NULL && fScale == 0 && fRoundingIncrement == 0 && areSignificantDigitsUsed() == FALSE &&
|
||||
|
|
|
@ -817,10 +817,12 @@ RuleChain::~RuleChain() {
|
|||
|
||||
UnicodeString
|
||||
RuleChain::select(const FixedDecimal &number) const {
|
||||
for (const RuleChain *rules = this; rules != NULL; rules = rules->fNext) {
|
||||
if (rules->ruleHeader->isFulfilled(number)) {
|
||||
return rules->fKeyword;
|
||||
}
|
||||
if (!number.isNanOrInfinity) {
|
||||
for (const RuleChain *rules = this; rules != NULL; rules = rules->fNext) {
|
||||
if (rules->ruleHeader->isFulfilled(number)) {
|
||||
return rules->fKeyword;
|
||||
}
|
||||
}
|
||||
}
|
||||
return UnicodeString(TRUE, PLURAL_KEYWORD_OTHER, 5);
|
||||
}
|
||||
|
@ -1382,6 +1384,11 @@ void FixedDecimal::init(double n) {
|
|||
void FixedDecimal::init(double n, int32_t v, int64_t f) {
|
||||
isNegative = n < 0;
|
||||
source = fabs(n);
|
||||
isNanOrInfinity = uprv_isNaN(source) || uprv_isPositiveInfinity(source);
|
||||
if (isNanOrInfinity) {
|
||||
v = 0;
|
||||
f = 0;
|
||||
}
|
||||
visibleDecimalDigitCount = v;
|
||||
decimalDigits = f;
|
||||
intValue = (int64_t)source;
|
||||
|
@ -1395,9 +1402,6 @@ void FixedDecimal::init(double n, int32_t v, int64_t f) {
|
|||
}
|
||||
decimalDigitsWithoutTrailingZeros = fdwtz;
|
||||
}
|
||||
if (uprv_isNaN(n)) {
|
||||
isNanOrInfinity = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1405,7 +1409,7 @@ void FixedDecimal::init(double n, int32_t v, int64_t f) {
|
|||
// Note: Do not multiply by 10 each time through loop, rounding cruft can build
|
||||
// up that makes the check for an integer result fail.
|
||||
// A single multiply of the original number works more reliably.
|
||||
static int p10[] = {1, 10, 100, 1000, 10000};
|
||||
static int32_t p10[] = {1, 10, 100, 1000, 10000};
|
||||
UBool FixedDecimal::quickInit(double n) {
|
||||
UBool success = FALSE;
|
||||
n = fabs(n);
|
||||
|
|
|
@ -170,13 +170,19 @@ private:
|
|||
|
||||
};
|
||||
|
||||
/**
|
||||
* class FixedDecimal serves to communicate the properties
|
||||
* of a formatted number from a decimal formatter to PluralRules::select()
|
||||
*
|
||||
* see DecimalFormat::getFixedDecimal()
|
||||
* @internal
|
||||
*/
|
||||
class U_I18N_API FixedDecimal: public UMemory {
|
||||
public:
|
||||
/**
|
||||
* @param n the number
|
||||
* @param v The number of visible fraction digits
|
||||
* @param f The fraction digits.
|
||||
*
|
||||
* @param n the number, e.g. 12.345
|
||||
* @param v The number of visible fraction digits, e.g. 3
|
||||
* @param f The fraction digits, e.g. 345
|
||||
*/
|
||||
FixedDecimal(double n, int32_t v, int64_t f);
|
||||
FixedDecimal(double n, int32_t);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "unicode/localpointer.h"
|
||||
#include "unicode/parseerr.h"
|
||||
|
||||
#include "putilimp.h"
|
||||
#include "plurrule_impl.h"
|
||||
|
||||
#define LENGTHOF(array) ((int32_t)(sizeof(array)/sizeof((array)[0])))
|
||||
|
@ -657,9 +658,14 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() {
|
|||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
|
||||
|
||||
|
||||
|
||||
fd = df->getFixedDecimal(uprv_getInfinity(), status);
|
||||
ASSERT_SUCCESS(status);
|
||||
ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
|
||||
fd = df->getFixedDecimal(0.0, status);
|
||||
ASSERT_EQUAL(FALSE, fd.isNanOrInfinity);
|
||||
fd = df->getFixedDecimal(uprv_getNaN(), status);
|
||||
ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
|
||||
ASSERT_SUCCESS(status);
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
Loading…
Add table
Reference in a new issue