ICU-13574 Replacing DigitList with DecimalQuantity through most of the code base.
X-SVN-Rev: 41064
This commit is contained in:
parent
3681a6803b
commit
94427dc200
@ -9,11 +9,229 @@
|
||||
// Helpful in toString methods and elsewhere.
|
||||
#define UNISTR_FROM_STRING_EXPLICIT
|
||||
|
||||
#include "unicode/decimfmt.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
using namespace icu::number::impl;
|
||||
using ERoundingMode = icu::DecimalFormat::ERoundingMode;
|
||||
using EPadPosition = icu::DecimalFormat::EPadPosition;
|
||||
|
||||
|
||||
DecimalFormat::DecimalFormat(UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const UnicodeString& pattern, UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt,
|
||||
UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt,
|
||||
UNumberFormatStyle style, UErrorCode& status) {}
|
||||
|
||||
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {}
|
||||
|
||||
DecimalFormat&
|
||||
DecimalFormat::setAttribute(UNumberFormatAttribute attr, int32_t newvalue, UErrorCode& status) {}
|
||||
|
||||
int32_t DecimalFormat::getAttribute(UNumberFormatAttribute attr, UErrorCode& status) const {}
|
||||
|
||||
void DecimalFormat::setGroupingUsed(UBool newValue) {}
|
||||
|
||||
void DecimalFormat::setParseIntegerOnly(UBool value) {}
|
||||
|
||||
void DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt,
|
||||
UParseError& parseError, UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const UnicodeString& pattern, const DecimalFormatSymbols& symbols,
|
||||
UErrorCode& status) {}
|
||||
|
||||
DecimalFormat::DecimalFormat(const DecimalFormat& source) {}
|
||||
|
||||
DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) {}
|
||||
|
||||
DecimalFormat::~DecimalFormat() = default;
|
||||
|
||||
Format* DecimalFormat::clone() const {}
|
||||
|
||||
UBool DecimalFormat::operator==(const Format& other) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString&
|
||||
DecimalFormat::format(double number, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString&
|
||||
DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& pos) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString&
|
||||
DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString&
|
||||
DecimalFormat::format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString&
|
||||
DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const {}
|
||||
|
||||
void
|
||||
DecimalFormat::parse(const UnicodeString& text, Formattable& result, ParsePosition& parsePosition) const {}
|
||||
|
||||
CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, ParsePosition& pos) const {}
|
||||
|
||||
const DecimalFormatSymbols* DecimalFormat::getDecimalFormatSymbols(void) const {}
|
||||
|
||||
void DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) {}
|
||||
|
||||
void DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) {}
|
||||
|
||||
const CurrencyPluralInfo* DecimalFormat::getCurrencyPluralInfo(void) const {}
|
||||
|
||||
void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) {}
|
||||
|
||||
void DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) {}
|
||||
|
||||
UnicodeString& DecimalFormat::getPositivePrefix(UnicodeString& result) const {}
|
||||
|
||||
void DecimalFormat::setPositivePrefix(const UnicodeString& newValue) {}
|
||||
|
||||
UnicodeString& DecimalFormat::getNegativePrefix(UnicodeString& result) const {}
|
||||
|
||||
void DecimalFormat::setNegativePrefix(const UnicodeString& newValue) {}
|
||||
|
||||
UnicodeString& DecimalFormat::getPositiveSuffix(UnicodeString& result) const {}
|
||||
|
||||
void DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) {}
|
||||
|
||||
UnicodeString& DecimalFormat::getNegativeSuffix(UnicodeString& result) const {}
|
||||
|
||||
void DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) {}
|
||||
|
||||
int32_t DecimalFormat::getMultiplier(void) const {}
|
||||
|
||||
void DecimalFormat::setMultiplier(int32_t newValue) {}
|
||||
|
||||
double DecimalFormat::getRoundingIncrement(void) const {}
|
||||
|
||||
void DecimalFormat::setRoundingIncrement(double newValue) {}
|
||||
|
||||
ERoundingMode DecimalFormat::getRoundingMode(void) const {}
|
||||
|
||||
void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {}
|
||||
|
||||
int32_t DecimalFormat::getFormatWidth(void) const {}
|
||||
|
||||
void DecimalFormat::setFormatWidth(int32_t width) {}
|
||||
|
||||
UnicodeString DecimalFormat::getPadCharacterString() const {}
|
||||
|
||||
void DecimalFormat::setPadCharacter(const UnicodeString& padChar) {}
|
||||
|
||||
EPadPosition DecimalFormat::getPadPosition(void) const {}
|
||||
|
||||
void DecimalFormat::setPadPosition(EPadPosition padPos) {}
|
||||
|
||||
UBool DecimalFormat::isScientificNotation(void) const {}
|
||||
|
||||
void DecimalFormat::setScientificNotation(UBool useScientific) {}
|
||||
|
||||
int8_t DecimalFormat::getMinimumExponentDigits(void) const {}
|
||||
|
||||
void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {}
|
||||
|
||||
UBool DecimalFormat::isExponentSignAlwaysShown(void) const {}
|
||||
|
||||
void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {}
|
||||
|
||||
int32_t DecimalFormat::getGroupingSize(void) const {}
|
||||
|
||||
void DecimalFormat::setGroupingSize(int32_t newValue) {}
|
||||
|
||||
int32_t DecimalFormat::getSecondaryGroupingSize(void) const {}
|
||||
|
||||
void DecimalFormat::setSecondaryGroupingSize(int32_t newValue) {}
|
||||
|
||||
int32_t DecimalFormat::getMinimumGroupingDigits() const {}
|
||||
|
||||
void DecimalFormat::setMinimumGroupingDigits(int32_t newValue) {}
|
||||
|
||||
UBool DecimalFormat::isDecimalSeparatorAlwaysShown(void) const {}
|
||||
|
||||
void DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) {}
|
||||
|
||||
UBool DecimalFormat::isDecimalPatternMatchRequired(void) const {}
|
||||
|
||||
void DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) {}
|
||||
|
||||
UnicodeString& DecimalFormat::toPattern(UnicodeString& result) const {}
|
||||
|
||||
UnicodeString& DecimalFormat::toLocalizedPattern(UnicodeString& result) const {}
|
||||
|
||||
void
|
||||
DecimalFormat::applyPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status) {}
|
||||
|
||||
void DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) {}
|
||||
|
||||
void DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UParseError& parseError,
|
||||
UErrorCode& status) {}
|
||||
|
||||
void DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status) {}
|
||||
|
||||
void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {}
|
||||
|
||||
void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {}
|
||||
|
||||
void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {}
|
||||
|
||||
void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {}
|
||||
|
||||
int32_t DecimalFormat::getMinimumSignificantDigits() const {}
|
||||
|
||||
int32_t DecimalFormat::getMaximumSignificantDigits() const {}
|
||||
|
||||
void DecimalFormat::setMinimumSignificantDigits(int32_t min) {}
|
||||
|
||||
void DecimalFormat::setMaximumSignificantDigits(int32_t max) {}
|
||||
|
||||
UBool DecimalFormat::areSignificantDigitsUsed() const {}
|
||||
|
||||
void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {}
|
||||
|
||||
void DecimalFormat::setCurrency(const char16_t* theCurrency, UErrorCode& ec) {}
|
||||
|
||||
void DecimalFormat::setCurrency(const char16_t* theCurrency) {}
|
||||
|
||||
void DecimalFormat::setCurrencyUsage(UCurrencyUsage newUsage, UErrorCode* ec) {}
|
||||
|
||||
UCurrencyUsage DecimalFormat::getCurrencyUsage() const {}
|
||||
|
||||
number::LocalizedNumberFormatter DecimalFormat::toNumberFormatter() const {}
|
||||
|
||||
UClassID DecimalFormat::getStaticClassID() {}
|
||||
|
||||
UClassID DecimalFormat::getDynamicClassID() const {}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "decNumber.h"
|
||||
#include "digitlst.h"
|
||||
#include "fmtableimp.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// class Formattable
|
||||
@ -40,6 +40,8 @@ U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
|
||||
|
||||
using number::impl::DecimalQuantity;
|
||||
|
||||
|
||||
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
|
||||
|
||||
@ -103,7 +105,7 @@ void Formattable::init() {
|
||||
fValue.fInt64 = 0;
|
||||
fType = kLong;
|
||||
fDecimalStr = NULL;
|
||||
fDecimalNum = NULL;
|
||||
fDecimalQuantity = NULL;
|
||||
fBogus.setToBogus();
|
||||
}
|
||||
|
||||
@ -257,8 +259,8 @@ Formattable::operator=(const Formattable& source)
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if (source.fDecimalNum != NULL) {
|
||||
fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
|
||||
if (source.fDecimalQuantity != NULL) {
|
||||
fDecimalQuantity = new DecimalQuantity(*source.fDecimalQuantity);
|
||||
}
|
||||
if (source.fDecimalStr != NULL) {
|
||||
fDecimalStr = new CharString(*source.fDecimalStr, status);
|
||||
@ -356,14 +358,9 @@ void Formattable::dispose()
|
||||
|
||||
delete fDecimalStr;
|
||||
fDecimalStr = NULL;
|
||||
|
||||
FmtStackData *stackData = (FmtStackData*)fStackData;
|
||||
if(fDecimalNum != &(stackData->stackDecimalNum)) {
|
||||
delete fDecimalNum;
|
||||
} else {
|
||||
fDecimalNum->~DigitList(); // destruct, don't deallocate
|
||||
}
|
||||
fDecimalNum = NULL;
|
||||
|
||||
delete fDecimalQuantity;
|
||||
fDecimalQuantity = NULL;
|
||||
}
|
||||
|
||||
Formattable *
|
||||
@ -465,8 +462,8 @@ Formattable::getInt64(UErrorCode& status) const
|
||||
} else if (fValue.fDouble < (double)U_INT64_MIN) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return U_INT64_MIN;
|
||||
} else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalNum != NULL) {
|
||||
int64_t val = fDecimalNum->getInt64();
|
||||
} else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalQuantity != NULL) {
|
||||
int64_t val = fDecimalQuantity->toLong();
|
||||
if (val != 0) {
|
||||
return val;
|
||||
} else {
|
||||
@ -714,27 +711,27 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
|
||||
|
||||
CharString *Formattable::internalGetCharString(UErrorCode &status) {
|
||||
if(fDecimalStr == NULL) {
|
||||
if (fDecimalNum == NULL) {
|
||||
if (fDecimalQuantity == NULL) {
|
||||
// No decimal number for the formattable yet. Which means the value was
|
||||
// set directly by the user as an int, int64 or double. If the value came
|
||||
// from parsing, or from the user setting a decimal number, fDecimalNum
|
||||
// would already be set.
|
||||
//
|
||||
fDecimalNum = new DigitList; // TODO: use internal digit list
|
||||
if (fDecimalNum == NULL) {
|
||||
fDecimalQuantity = new DecimalQuantity(); // TODO: use internal digit list
|
||||
if (fDecimalQuantity == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (fType) {
|
||||
case kDouble:
|
||||
fDecimalNum->set(this->getDouble());
|
||||
fDecimalQuantity->setToDouble(this->getDouble());
|
||||
break;
|
||||
case kLong:
|
||||
fDecimalNum->set(this->getLong());
|
||||
fDecimalQuantity->setToInt(this->getLong());
|
||||
break;
|
||||
case kInt64:
|
||||
fDecimalNum->set(this->getInt64());
|
||||
fDecimalQuantity->setToLong(this->getInt64());
|
||||
break;
|
||||
default:
|
||||
// The formattable's value is not a numeric type.
|
||||
@ -743,55 +740,48 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
|
||||
}
|
||||
}
|
||||
|
||||
fDecimalStr = new CharString;
|
||||
fDecimalStr = new CharString();
|
||||
if (fDecimalStr == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
fDecimalNum->getDecimal(*fDecimalStr, status);
|
||||
UnicodeString result = fDecimalQuantity->toNumberString();
|
||||
for (int32_t i=0; i<result.length(); i++) {
|
||||
fDecimalStr->append(static_cast<char>(result[i]), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fDecimalStr;
|
||||
}
|
||||
|
||||
|
||||
DigitList *
|
||||
Formattable::getInternalDigitList() {
|
||||
FmtStackData *stackData = (FmtStackData*)fStackData;
|
||||
if(fDecimalNum != &(stackData->stackDecimalNum)) {
|
||||
delete fDecimalNum;
|
||||
fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
|
||||
} else {
|
||||
fDecimalNum->clear();
|
||||
}
|
||||
return fDecimalNum;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
void
|
||||
Formattable::adoptDigitList(DigitList *dl) {
|
||||
if(fDecimalNum==dl) {
|
||||
fDecimalNum = NULL; // don't delete
|
||||
}
|
||||
dispose();
|
||||
|
||||
fDecimalNum = dl;
|
||||
|
||||
if(dl==NULL) { // allow adoptDigitList(NULL) to clear
|
||||
return;
|
||||
}
|
||||
Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
|
||||
if (fDecimalQuantity != NULL) {
|
||||
delete fDecimalQuantity;
|
||||
}
|
||||
fDecimalQuantity = dq;
|
||||
if (dq == NULL) { // allow adoptDigitList(NULL) to clear
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the value into the Union of simple type values.
|
||||
// Cannot use the set() functions because they would delete the fDecimalNum value,
|
||||
|
||||
if (fDecimalNum->fitsIntoLong(FALSE)) {
|
||||
// TODO: fDecimalQuantity->fitsInInt() to kLong type.
|
||||
/*
|
||||
if (fDecimalQuantity->fitsIntoLong(FALSE)) {
|
||||
fType = kLong;
|
||||
fValue.fInt64 = fDecimalNum->getLong();
|
||||
} else if (fDecimalNum->fitsIntoInt64(FALSE)) {
|
||||
} else
|
||||
*/
|
||||
if (fDecimalQuantity->fitsInLong()) {
|
||||
fType = kInt64;
|
||||
fValue.fInt64 = fDecimalNum->getInt64();
|
||||
fValue.fInt64 = fDecimalQuantity->toLong();
|
||||
} else {
|
||||
fType = kDouble;
|
||||
fValue.fDouble = fDecimalNum->getDouble();
|
||||
fValue.fDouble = fDecimalQuantity->toDouble();
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,24 +794,12 @@ Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
|
||||
}
|
||||
dispose();
|
||||
|
||||
// Copy the input string and nul-terminate it.
|
||||
// The decNumber library requires nul-terminated input. StringPiece input
|
||||
// is not guaranteed nul-terminated. Too bad.
|
||||
// CharString automatically adds the nul.
|
||||
DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
|
||||
if (dnum == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
dnum->set(CharString(numberString, status).toStringPiece(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete dnum;
|
||||
return; // String didn't contain a decimal number.
|
||||
}
|
||||
adoptDigitList(dnum);
|
||||
DecimalQuantity* dq = new DecimalQuantity();
|
||||
dq->setToDecNumber(numberString);
|
||||
adoptDecimalQuantity(dq);
|
||||
|
||||
// Note that we do not hang on to the caller's input string.
|
||||
// If we are asked for the string, we will regenerate one from fDecimalNum.
|
||||
// If we are asked for the string, we will regenerate one from fDecimalQuantity.
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef FMTABLEIMP_H
|
||||
#define FMTABLEIMP_H
|
||||
|
||||
#include "digitlst.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
@ -20,7 +20,7 @@ U_NAMESPACE_BEGIN
|
||||
* @internal
|
||||
*/
|
||||
struct FmtStackData {
|
||||
DigitList stackDecimalNum; // 128
|
||||
icu::number::impl::DecimalQuantity stackDecimalNum; // 128
|
||||
//CharString stackDecimalStr; // 64
|
||||
// -----
|
||||
// 192 total
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "util.h"
|
||||
#include "uvector.h"
|
||||
#include "visibledigits.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// class MessageFormat
|
||||
@ -1961,13 +1962,12 @@ UnicodeString MessageFormat::PluralSelectorProvider::select(void *ctx, double nu
|
||||
context.formatter->format(context.number, context.numberString, ec);
|
||||
auto* decFmt = dynamic_cast<const DecimalFormat *>(context.formatter);
|
||||
if(decFmt != NULL) {
|
||||
const IFixedDecimal& dec = decFmt->toNumberFormatter()
|
||||
.formatDouble(context.number.getDouble(ec), ec)
|
||||
.getFixedDecimal(ec);
|
||||
number::impl::DecimalQuantity dq;
|
||||
decFmt->formatToDecimalQuantity(number, dq, ec);
|
||||
if (U_FAILURE(ec)) {
|
||||
return UnicodeString(FALSE, OTHER_STRING, 5);
|
||||
}
|
||||
return rules->select(dec);
|
||||
return rules->select(dq);
|
||||
} else {
|
||||
return rules->select(number);
|
||||
}
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "utypeinfo.h" // for 'typeid' to work
|
||||
|
||||
#include "nfsubs.h"
|
||||
#include "digitlst.h"
|
||||
#include "fmtableimp.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
#if U_HAVE_RBNF
|
||||
|
||||
@ -47,6 +47,8 @@ static const UChar gGreaterGreaterThan[] =
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
using number::impl::DecimalQuantity;
|
||||
|
||||
class SameValueSubstitution : public NFSubstitution {
|
||||
public:
|
||||
SameValueSubstitution(int32_t pos,
|
||||
@ -1069,13 +1071,12 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
|
||||
// numberToFormat /= 10;
|
||||
// }
|
||||
|
||||
DigitList dl;
|
||||
dl.set(number);
|
||||
dl.roundFixedPoint(20); // round to 20 fraction digits.
|
||||
dl.reduce(); // Removes any trailing zeros.
|
||||
DecimalQuantity dl;
|
||||
dl.setToDouble(number);
|
||||
dl.roundToMagnitude(-20, UNUM_ROUND_HALFEVEN, status); // round to 20 fraction digits.
|
||||
|
||||
UBool pad = FALSE;
|
||||
for (int32_t didx = dl.getCount()-1; didx>=dl.getDecimalAt(); didx--) {
|
||||
for (int32_t didx = dl.getLowerDisplayMagnitude(); didx<0; didx++) {
|
||||
// Loop iterates over fraction digits, starting with the LSD.
|
||||
// include both real digits from the number, and zeros
|
||||
// to the left of the MSD but to the right of the decimal point.
|
||||
@ -1142,7 +1143,7 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
||||
int32_t digit;
|
||||
// double p10 = 0.1;
|
||||
|
||||
DigitList dl;
|
||||
DecimalQuantity dl;
|
||||
NumberFormat* fmt = NULL;
|
||||
while (workText.length() > 0 && workPos.getIndex() != 0) {
|
||||
workPos.setIndex(0);
|
||||
@ -1170,7 +1171,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
||||
}
|
||||
|
||||
if (workPos.getIndex() != 0) {
|
||||
dl.append((char)('0' + digit));
|
||||
// TODO(sffc): Make sure this is doing what it is supposed to do.
|
||||
dl.appendDigit(static_cast<int8_t>(digit), 0, true);
|
||||
// result += digit * p10;
|
||||
// p10 /= 10;
|
||||
parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
|
||||
@ -1183,7 +1185,7 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
||||
}
|
||||
delete fmt;
|
||||
|
||||
result = dl.getCount() == 0 ? 0 : dl.getDouble();
|
||||
result = dl.toDouble();
|
||||
result = composeRuleValue(result, baseValue);
|
||||
resVal.setDouble(result);
|
||||
return TRUE;
|
||||
|
@ -241,6 +241,10 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
|
||||
/** Visible for testing */
|
||||
inline bool isExplicitExactDouble() { return explicitExactDouble; };
|
||||
|
||||
bool operator==(const DecimalQuantity& other) const;
|
||||
|
||||
bool operator!=(const DecimalQuantity& other) const;
|
||||
|
||||
/**
|
||||
* Bogus flag for when a DecimalQuantity is stored on the stack.
|
||||
*/
|
||||
|
@ -51,10 +51,10 @@
|
||||
#include "uassert.h"
|
||||
#include "umutex.h"
|
||||
#include "mutex.h"
|
||||
#include "digitlst.h"
|
||||
#include <float.h>
|
||||
#include "sharednumberformat.h"
|
||||
#include "unifiedcache.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
//#define FMT_DEBUG
|
||||
|
||||
@ -524,7 +524,7 @@ ArgExtractor::ArgExtractor(const NumberFormat& /*nf*/, const Formattable& obj, U
|
||||
ArgExtractor::~ArgExtractor() {
|
||||
}
|
||||
|
||||
UnicodeString& NumberFormat::format(const DigitList &number,
|
||||
UnicodeString& NumberFormat::format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {
|
||||
@ -534,7 +534,7 @@ UnicodeString& NumberFormat::format(const DigitList &number,
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
double dnum = number.getDouble();
|
||||
double dnum = number.toDouble();
|
||||
format(dnum, appendTo, posIter, status);
|
||||
return appendTo;
|
||||
}
|
||||
@ -542,7 +542,7 @@ UnicodeString& NumberFormat::format(const DigitList &number,
|
||||
|
||||
|
||||
UnicodeString&
|
||||
NumberFormat::format(const DigitList &number,
|
||||
NumberFormat::format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode &status) const {
|
||||
@ -552,7 +552,7 @@ NumberFormat::format(const DigitList &number,
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
double dnum = number.getDouble();
|
||||
double dnum = number.toDouble();
|
||||
format(dnum, appendTo, pos, status);
|
||||
return appendTo;
|
||||
}
|
||||
@ -578,7 +578,7 @@ NumberFormat::format(const Formattable& obj,
|
||||
return cloneFmt->format(*n, appendTo, pos, status);
|
||||
}
|
||||
|
||||
if (n->isNumeric() && n->getDigitList() != NULL) {
|
||||
if (n->isNumeric() && n->getDecimalQuantity() != NULL) {
|
||||
// Decimal Number. We will have a DigitList available if the value was
|
||||
// set to a decimal number, or if the value originated with a parse.
|
||||
//
|
||||
@ -587,7 +587,7 @@ NumberFormat::format(const Formattable& obj,
|
||||
// know about DigitList to continue to operate as they had.
|
||||
//
|
||||
// DecimalFormat overrides the DigitList formatting functions.
|
||||
format(*n->getDigitList(), appendTo, pos, status);
|
||||
format(*n->getDecimalQuantity(), appendTo, pos, status);
|
||||
} else {
|
||||
switch (n->getType()) {
|
||||
case Formattable::kDouble:
|
||||
@ -633,9 +633,9 @@ NumberFormat::format(const Formattable& obj,
|
||||
return cloneFmt->format(*n, appendTo, posIter, status);
|
||||
}
|
||||
|
||||
if (n->isNumeric() && n->getDigitList() != NULL) {
|
||||
if (n->isNumeric() && n->getDecimalQuantity() != NULL) {
|
||||
// Decimal Number
|
||||
format(*n->getDigitList(), appendTo, posIter, status);
|
||||
format(*n->getDecimalQuantity(), appendTo, posIter, status);
|
||||
} else {
|
||||
switch (n->getType()) {
|
||||
case Formattable::kDouble:
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "digitlst.h"
|
||||
#include "hash.h"
|
||||
#include "locutil.h"
|
||||
#include "mutex.h"
|
||||
@ -37,12 +36,14 @@
|
||||
#include "unifiedcache.h"
|
||||
#include "digitinterval.h"
|
||||
#include "visibledigits.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
using namespace icu::pluralimpl;
|
||||
using icu::number::impl::DecimalQuantity;
|
||||
|
||||
static const UChar PLURAL_KEYWORD_OTHER[]={LOW_O,LOW_T,LOW_H,LOW_E,LOW_R,0};
|
||||
static const UChar PLURAL_DEFAULT_RULE[]={LOW_O,LOW_T,LOW_H,LOW_E,LOW_R,COLON,SPACE,LOW_N,0};
|
||||
@ -254,11 +255,10 @@ PluralRules::select(const Formattable& obj, const NumberFormat& fmt, UErrorCode&
|
||||
if (U_SUCCESS(status)) {
|
||||
const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
|
||||
if (decFmt != NULL) {
|
||||
const IFixedDecimal& dec = decFmt->toNumberFormatter()
|
||||
.formatDouble(obj.getDouble(status), status)
|
||||
.getFixedDecimal(status);
|
||||
number::impl::DecimalQuantity dq;
|
||||
decFmt->formatToDecimalQuantity(obj, dq, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return select(dec);
|
||||
return select(dq);
|
||||
}
|
||||
} else {
|
||||
double number = obj.getDouble(status);
|
||||
@ -1477,14 +1477,14 @@ FixedDecimal::FixedDecimal() {
|
||||
FixedDecimal::FixedDecimal(const UnicodeString &num, UErrorCode &status) {
|
||||
CharString cs;
|
||||
cs.appendInvariantChars(num, status);
|
||||
DigitList dl;
|
||||
dl.set(cs.toStringPiece(), status);
|
||||
DecimalQuantity dl;
|
||||
dl.setToDecNumber(cs.toStringPiece());
|
||||
if (U_FAILURE(status)) {
|
||||
init(0, 0, 0);
|
||||
return;
|
||||
}
|
||||
int32_t decimalPoint = num.indexOf(DOT);
|
||||
double n = dl.getDouble();
|
||||
double n = dl.toDouble();
|
||||
if (decimalPoint == -1) {
|
||||
init(n, 0, 0);
|
||||
} else {
|
||||
|
@ -248,6 +248,10 @@ class U_I18N_API IFixedDecimal {
|
||||
virtual bool isNaN() const = 0;
|
||||
|
||||
virtual bool isInfinite() const = 0;
|
||||
|
||||
virtual bool hasIntegerValue() {
|
||||
return getPluralOperand(PLURAL_OPERAND_N) == getPluralOperand(PLURAL_OPERAND_I);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "standardplural.h"
|
||||
#include "visibledigits.h"
|
||||
#include "uassert.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
@ -151,13 +152,12 @@ StandardPlural::Form QuantityFormatter::selectPlural(
|
||||
UnicodeString pluralKeyword;
|
||||
const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
|
||||
if (decFmt != NULL) {
|
||||
const IFixedDecimal& dec = decFmt->toNumberFormatter()
|
||||
.formatDouble(number.getDouble(status), status)
|
||||
.getFixedDecimal(status);
|
||||
number::impl::DecimalQuantity dq;
|
||||
decFmt->formatToDecimalQuantity(number, dq, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return StandardPlural::OTHER;
|
||||
}
|
||||
pluralKeyword = rules.select(dec);
|
||||
pluralKeyword = rules.select(dq);
|
||||
decFmt->format(number, formattedNumber, pos, status);
|
||||
} else {
|
||||
if (number.getType() == Formattable::kDouble) {
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "patternprops.h"
|
||||
#include "uresimp.h"
|
||||
#include "nfrs.h"
|
||||
#include "digitlst.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
// debugging
|
||||
// #define RBNF_DEBUG
|
||||
@ -68,6 +68,8 @@ static const UChar gSemiPercent[] =
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
using number::impl::DecimalQuantity;
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedNumberFormat)
|
||||
|
||||
/*
|
||||
@ -1109,21 +1111,21 @@ RuleBasedNumberFormat::findRuleSet(const UnicodeString& name, UErrorCode& status
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
RuleBasedNumberFormat::format(const DigitList &number,
|
||||
RuleBasedNumberFormat::format(const DecimalQuantity &number,
|
||||
UnicodeString &appendTo,
|
||||
FieldPositionIterator *posIter,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
DigitList copy(number);
|
||||
if (copy.fitsIntoInt64(false)) {
|
||||
format(((DigitList &)number).getInt64(), appendTo, posIter, status);
|
||||
DecimalQuantity copy(number);
|
||||
if (copy.fitsInLong()) {
|
||||
format(((DecimalQuantity &)number).toLong(), appendTo, posIter, status);
|
||||
}
|
||||
else {
|
||||
copy.roundAtExponent(0);
|
||||
if (copy.fitsIntoInt64(false)) {
|
||||
format(number.getDouble(), appendTo, posIter, status);
|
||||
copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status);
|
||||
if (copy.fitsInLong()) {
|
||||
format(number.toLong(), appendTo, posIter, status);
|
||||
}
|
||||
else {
|
||||
// We're outside of our normal range that this framework can handle.
|
||||
@ -1132,7 +1134,7 @@ RuleBasedNumberFormat::format(const DigitList &number,
|
||||
// TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J.
|
||||
NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status);
|
||||
Formattable f;
|
||||
f.adoptDigitList(new DigitList(number));
|
||||
f.adoptDecimalQuantity(new DecimalQuantity(number));
|
||||
decimalFormat->format(f, appendTo, posIter, status);
|
||||
delete decimalFormat;
|
||||
}
|
||||
@ -1142,21 +1144,21 @@ RuleBasedNumberFormat::format(const DigitList &number,
|
||||
|
||||
|
||||
UnicodeString&
|
||||
RuleBasedNumberFormat::format(const DigitList &number,
|
||||
RuleBasedNumberFormat::format(const DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
DigitList copy(number);
|
||||
if (copy.fitsIntoInt64(false)) {
|
||||
format(((DigitList &)number).getInt64(), appendTo, pos, status);
|
||||
DecimalQuantity copy(number);
|
||||
if (copy.fitsInLong()) {
|
||||
format(((DecimalQuantity &)number).toLong(), appendTo, pos, status);
|
||||
}
|
||||
else {
|
||||
copy.roundAtExponent(0);
|
||||
if (copy.fitsIntoInt64(false)) {
|
||||
format(number.getDouble(), appendTo, pos, status);
|
||||
copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status);
|
||||
if (copy.fitsInLong()) {
|
||||
format(number.toLong(), appendTo, pos, status);
|
||||
}
|
||||
else {
|
||||
// We're outside of our normal range that this framework can handle.
|
||||
@ -1165,7 +1167,7 @@ RuleBasedNumberFormat::format(const DigitList &number,
|
||||
// TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J.
|
||||
NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status);
|
||||
Formattable f;
|
||||
f.adoptDigitList(new DigitList(number));
|
||||
f.adoptDecimalQuantity(new DecimalQuantity(number));
|
||||
decimalFormat->format(f, appendTo, pos, status);
|
||||
delete decimalFormat;
|
||||
}
|
||||
@ -1270,11 +1272,13 @@ RuleBasedNumberFormat::format(double number,
|
||||
{
|
||||
int32_t startPos = toAppendTo.length();
|
||||
if (getRoundingMode() != DecimalFormat::ERoundingMode::kRoundUnnecessary && !uprv_isNaN(number) && !uprv_isInfinite(number)) {
|
||||
DigitList digitList;
|
||||
digitList.set(number);
|
||||
digitList.setRoundingMode(getRoundingMode());
|
||||
digitList.roundFixedPoint(getMaximumFractionDigits());
|
||||
number = digitList.getDouble();
|
||||
DecimalQuantity digitList;
|
||||
digitList.setToDouble(number);
|
||||
digitList.roundToMagnitude(
|
||||
-getMaximumFractionDigits(),
|
||||
static_cast<UNumberFormatRoundingMode>(getRoundingMode()),
|
||||
status);
|
||||
number = digitList.toDouble();
|
||||
}
|
||||
rs.format(number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo, status);
|
||||
@ -1310,9 +1314,9 @@ RuleBasedNumberFormat::format(int64_t number, NFRuleSet *ruleSet, UnicodeString&
|
||||
NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status);
|
||||
Formattable f;
|
||||
FieldPosition pos(FieldPosition::DONT_CARE);
|
||||
DigitList *digitList = new DigitList();
|
||||
digitList->set(number);
|
||||
f.adoptDigitList(digitList);
|
||||
DecimalQuantity *digitList = new DecimalQuantity();
|
||||
digitList->setToLong(number);
|
||||
f.adoptDecimalQuantity(digitList);
|
||||
decimalFormat->format(f, toAppendTo, pos, status);
|
||||
delete decimalFormat;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
* Destructor.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual ~CompactDecimalFormat();
|
||||
~CompactDecimalFormat() U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
@ -86,289 +86,8 @@ public:
|
||||
*/
|
||||
CompactDecimalFormat& operator=(const CompactDecimalFormat& rhs);
|
||||
|
||||
/**
|
||||
* Clone this Format object polymorphically. The caller owns the
|
||||
* result and should delete it when done.
|
||||
*
|
||||
* @return a polymorphic copy of this CompactDecimalFormat.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual Format* clone() const;
|
||||
|
||||
/**
|
||||
* Return TRUE if the given Format objects are semantically equal.
|
||||
* Objects of different subclasses are considered unequal.
|
||||
*
|
||||
* @param other the object to be compared with.
|
||||
* @return TRUE if the given Format objects are semantically equal.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual UBool operator==(const Format& other) const;
|
||||
|
||||
|
||||
using DecimalFormat::format;
|
||||
|
||||
/**
|
||||
* Format a double or long number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual UnicodeString& format(double number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos) const;
|
||||
|
||||
/**
|
||||
* Format a double or long number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @param status
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(double number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* Format a double or long number using base-10 representation.
|
||||
* Currently sets status to U_UNSUPPORTED_ERROR.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* Can be NULL.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(double number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a long number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @stable ICU 56
|
||||
*/
|
||||
virtual UnicodeString& format(int32_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos) const;
|
||||
|
||||
/**
|
||||
* Format a long number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(int32_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* Format a long number using base-10 representation.
|
||||
* Currently sets status to U_UNSUPPORTED_ERROR
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* Can be NULL.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(int32_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format an int64 number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual UnicodeString& format(int64_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos) const;
|
||||
|
||||
/**
|
||||
* Format an int64 number using base-10 representation.
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(int64_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* Format an int64 number using base-10 representation.
|
||||
* Currently sets status to U_UNSUPPORTED_ERROR
|
||||
*
|
||||
* @param number The value to be formatted.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* Can be NULL.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(int64_t number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR
|
||||
* The syntax of the unformatted number is a "numeric string"
|
||||
* as defined in the Decimal Arithmetic Specification, available at
|
||||
* http://speleotrove.com/decimal
|
||||
*
|
||||
* @param number The unformatted number, as a string.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* Can be NULL.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(StringPiece number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number. Currently sets status to U_UNSUPPORTED_ERROR.
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* CompactDecimalFormat does not support parsing. This implementation
|
||||
* does nothing.
|
||||
* @param text Unused.
|
||||
* @param result Does not change.
|
||||
* @param parsePosition Does not change.
|
||||
* @see Formattable
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual void parse(const UnicodeString& text,
|
||||
Formattable& result,
|
||||
ParsePosition& parsePosition) const;
|
||||
|
||||
/**
|
||||
* CompactDecimalFormat does not support parsing. This implementation
|
||||
* sets status to U_UNSUPPORTED_ERROR
|
||||
*
|
||||
* @param text Unused.
|
||||
* @param result Does not change.
|
||||
* @param status Always set to U_UNSUPPORTED_ERROR.
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual void parse(const UnicodeString& text,
|
||||
Formattable& result,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Parses text from the given string as a currency amount. Unlike
|
||||
* the parse() method, this method will attempt to parse a generic
|
||||
* currency name, searching for a match of this object's locale's
|
||||
* currency display names, or for a 3-letter ISO currency code.
|
||||
* This method will fail if this format is not a currency format,
|
||||
* that is, if it does not contain the currency pattern symbol
|
||||
* (U+00A4) in its prefix or suffix. This implementation always returns
|
||||
* NULL.
|
||||
*
|
||||
* @param text the string to parse
|
||||
* @param pos input-output position; on input, the position within text
|
||||
* to match; must have 0 <= pos.getIndex() < text.length();
|
||||
* on output, the position after the last matched character.
|
||||
* If the parse fails, the position in unchanged upon output.
|
||||
* @return if parse succeeds, a pointer to a newly-created CurrencyAmount
|
||||
* object (owned by the caller) containing information about
|
||||
* the parsed currency; if parse fails, this is NULL.
|
||||
* @internal
|
||||
*/
|
||||
virtual CurrencyAmount* parseCurrency(const UnicodeString& text,
|
||||
ParsePosition& pos) const;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for
|
||||
* comparing to a return value from getDynamicClassID(). For example:
|
||||
@ -394,17 +113,6 @@ public:
|
||||
* @stable ICU 51
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
private:
|
||||
|
||||
const UHashtable* _unitsByVariant;
|
||||
const double* _divisors;
|
||||
PluralRules* _pluralRules;
|
||||
|
||||
// Default constructor not implemented.
|
||||
CompactDecimalFormat(const DecimalFormat &, const UHashtable* unitsByVariant, const double* divisors, PluralRules* pluralRules);
|
||||
|
||||
UBool eqHelper(const CompactDecimalFormat& that) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -67,6 +67,12 @@ class DecimalFormatImpl;
|
||||
class PluralRules;
|
||||
class VisibleDigitsWithExponent;
|
||||
|
||||
namespace number {
|
||||
namespace impl {
|
||||
class DecimalQuantity;
|
||||
}
|
||||
}
|
||||
|
||||
// explicit template instantiation. see digitlst.h
|
||||
// (When building DLLs for Windows this is required.)
|
||||
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
|
||||
@ -1084,11 +1090,11 @@ public:
|
||||
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The number is a DecimalQuantity wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param number The number, a DecimalQuantity format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
@ -1097,50 +1103,18 @@ public:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
UnicodeString& format(const DigitList &number,
|
||||
UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* @param number The number
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
* On output: the offsets of the alignment field.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const VisibleDigitsWithExponent &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* @param number The number
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
* of fields generated by this format call.
|
||||
* @param status Output param filled with success/failure status.
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const VisibleDigitsWithExponent &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The number is a DecimalQuantity wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param number The number, a DecimalQuantity format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
@ -1149,7 +1123,7 @@ public:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
UnicodeString& format(const DigitList &number,
|
||||
UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
@ -1967,6 +1941,25 @@ public:
|
||||
*/
|
||||
UCurrencyUsage getCurrencyUsage() const;
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Format a number and save it into the given DecimalQuantity.
|
||||
* Internal, not intended for public use.
|
||||
* @internal
|
||||
*/
|
||||
void formatToDecimalQuantity(double number, number::impl::DecimalQuantity& output,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Get a DecimalQuantity corresponding to a formattable as it would be
|
||||
* formatted by this DecimalFormat.
|
||||
* Internal, not intended for public use.
|
||||
* @internal
|
||||
*/
|
||||
void formatToDecimalQuantity(const Formattable& number, number::impl::DecimalQuantity& output,
|
||||
UErrorCode& status) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts this DecimalFormat to a NumberFormatter. Starting in ICU 60,
|
||||
* NumberFormatter is the recommended way to format numbers.
|
||||
|
@ -33,7 +33,11 @@
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class CharString;
|
||||
class DigitList;
|
||||
namespace number {
|
||||
namespace impl {
|
||||
class DecimalQuantity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \def UNUM_INTERNAL_STACKARRAY_SIZE
|
||||
@ -649,24 +653,19 @@ public:
|
||||
* Internal function, do not use.
|
||||
* TODO: figure out how to make this be non-public.
|
||||
* NumberFormat::format(Formattable, ...
|
||||
* needs to get at the DigitList, if it exists, for
|
||||
* needs to get at the DecimalQuantity, if it exists, for
|
||||
* big decimal formatting.
|
||||
* @internal
|
||||
*/
|
||||
DigitList *getDigitList() const { return fDecimalNum;}
|
||||
number::impl::DecimalQuantity *getDecimalQuantity() const { return fDecimalQuantity;}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
DigitList *getInternalDigitList();
|
||||
|
||||
/**
|
||||
* Adopt, and set value from, a DigitList
|
||||
* Adopt, and set value from, a DecimalQuantity
|
||||
* Internal Function, do not use.
|
||||
* @param dl the Digit List to be adopted
|
||||
* @param dl the DecimalQuantity to be adopted
|
||||
* @internal
|
||||
*/
|
||||
void adoptDigitList(DigitList *dl);
|
||||
void adoptDecimalQuantity(number::impl::DecimalQuantity *dq);
|
||||
|
||||
/**
|
||||
* Internal function to return the CharString pointer.
|
||||
@ -706,9 +705,7 @@ private:
|
||||
|
||||
CharString *fDecimalStr;
|
||||
|
||||
DigitList *fDecimalNum;
|
||||
|
||||
char fStackData[UNUM_INTERNAL_STACKARRAY_SIZE]; // must be big enough for DigitList
|
||||
number::impl::DecimalQuantity *fDecimalQuantity;
|
||||
|
||||
Type fType;
|
||||
UnicodeString fBogus; // Bogus string when it's needed.
|
||||
|
@ -558,13 +558,13 @@ public:
|
||||
public:
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The number is a DecimalQuantity wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that. Subclasses of NumberFormat that want
|
||||
* to specifically handle big decimal numbers must override this method.
|
||||
* class DecimalFormat does so.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param number The number, a DecimalQuantity format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param posIter On return, can be used to iterate over positions
|
||||
@ -573,20 +573,20 @@ public:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
virtual UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Format a decimal number.
|
||||
* The number is a DigitList wrapper onto a floating point decimal number.
|
||||
* The number is a DecimalQuantity wrapper onto a floating point decimal number.
|
||||
* The default implementation in NumberFormat converts the decimal number
|
||||
* to a double and formats that. Subclasses of NumberFormat that want
|
||||
* to specifically handle big decimal numbers must override this method.
|
||||
* class DecimalFormat does so.
|
||||
*
|
||||
* @param number The number, a DigitList format Decimal Floating Point.
|
||||
* @param number The number, a DecimalQuantity format Decimal Floating Point.
|
||||
* @param appendTo Output parameter to receive result.
|
||||
* Result is appended to existing contents.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
@ -595,7 +595,7 @@ public:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
virtual UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
@ -884,7 +884,7 @@ protected:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
virtual UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const;
|
||||
@ -906,7 +906,7 @@ protected:
|
||||
* @return Reference to 'appendTo' parameter.
|
||||
* @internal
|
||||
*/
|
||||
virtual UnicodeString& format(const DigitList &number,
|
||||
virtual UnicodeString& format(const number::impl::DecimalQuantity &number,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "putilimp.h"
|
||||
#include "plurrule_impl.h"
|
||||
#include <stdio.h>
|
||||
#include <number_decimalquantity.h>
|
||||
|
||||
// This is an API test, not a unit test. It doesn't test very many cases, and doesn't
|
||||
// try to test the full functionality. It just calls each function in the class and
|
||||
@ -613,171 +614,172 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() {
|
||||
if (status == U_MISSING_RESOURCE_ERROR) {
|
||||
return;
|
||||
}
|
||||
FixedDecimal fd = df->getFixedDecimal(44, status);
|
||||
number::impl::DecimalQuantity fd;
|
||||
df->formatToDecimalQuantity(44, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(44, fd.source);
|
||||
ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(44, fd.getPluralOperand(PLURAL_OPERAND_N));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(-44, status);
|
||||
df->formatToDecimalQuantity(-44, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(44, fd.source);
|
||||
ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(44, fd.getPluralOperand(PLURAL_OPERAND_N));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(123.456, status);
|
||||
df->formatToDecimalQuantity(123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(456, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(123, fd.intValue); // i
|
||||
ASSERT_EQUAL(123.456, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(123.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(-123.456, status);
|
||||
df->formatToDecimalQuantity(-123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(456, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(123, fd.intValue); // i
|
||||
ASSERT_EQUAL(123.456, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(123.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
// test max int digits
|
||||
df->setMaximumIntegerDigits(2);
|
||||
fd = df->getFixedDecimal(123.456, status);
|
||||
df->formatToDecimalQuantity(123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(456, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(23, fd.intValue); // i
|
||||
ASSERT_EQUAL(23.456, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(23.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(-123.456, status);
|
||||
df->formatToDecimalQuantity(-123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(456, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(23, fd.intValue); // i
|
||||
ASSERT_EQUAL(23.456, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(456, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(23.456, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
// test max fraction digits
|
||||
df->setMaximumIntegerDigits(2000000000);
|
||||
df->setMaximumFractionDigits(2);
|
||||
fd = df->getFixedDecimal(123.456, status);
|
||||
df->formatToDecimalQuantity(123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(46, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(123, fd.intValue); // i
|
||||
ASSERT_EQUAL(123.46, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(123.46, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(-123.456, status);
|
||||
df->formatToDecimalQuantity(-123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(46, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(123, fd.intValue); // i
|
||||
ASSERT_EQUAL(123.46, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(46, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(123.46, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
// test esoteric rounding
|
||||
df->setMaximumFractionDigits(6);
|
||||
df->setRoundingIncrement(7.3);
|
||||
|
||||
fd = df->getFixedDecimal(30.0, status);
|
||||
df->formatToDecimalQuantity(30.0, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(20, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(29, fd.intValue); // i
|
||||
ASSERT_EQUAL(29.2, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(20, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(29, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(29.2, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(-30.0, status);
|
||||
df->formatToDecimalQuantity(-30.0, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
|
||||
ASSERT_EQUAL(20, fd.decimalDigits); // f
|
||||
ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
|
||||
ASSERT_EQUAL(29, fd.intValue); // i
|
||||
ASSERT_EQUAL(29.2, fd.source); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V)); // v
|
||||
ASSERT_EQUAL(20, fd.getPluralOperand(PLURAL_OPERAND_F)); // f
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_T)); // t
|
||||
ASSERT_EQUAL(29, fd.getPluralOperand(PLURAL_OPERAND_I)); // i
|
||||
ASSERT_EQUAL(29.2, fd.getPluralOperand(PLURAL_OPERAND_N)); // n
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(123.456, status);
|
||||
df->formatToDecimalQuantity(123.456, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(123, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(123.01, status);
|
||||
df->formatToDecimalQuantity(123.01, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(123, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(123.06, status);
|
||||
df->formatToDecimalQuantity(123.06, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(1, fd.decimalDigits);
|
||||
ASSERT_EQUAL(1, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(123, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(123, status);
|
||||
df->formatToDecimalQuantity(123, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(123, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(123, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(1.23, status);
|
||||
df->formatToDecimalQuantity(1.23, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(4, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(2300, fd.decimalDigits);
|
||||
ASSERT_EQUAL(23, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(1, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(4, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(2300, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(23, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fd = df->getFixedDecimal(uprv_getInfinity(), status);
|
||||
df->formatToDecimalQuantity(uprv_getInfinity(), fd, status);
|
||||
TEST_ASSERT_STATUS(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_EQUAL(TRUE, fd.isNaN() || fd.isInfinite());
|
||||
df->formatToDecimalQuantity(0.0, fd, status);
|
||||
ASSERT_EQUAL(FALSE, fd.isNaN() || fd.isInfinite());
|
||||
df->formatToDecimalQuantity(uprv_getNaN(), fd, status);
|
||||
ASSERT_EQUAL(TRUE, fd.isNaN() || fd.isInfinite());
|
||||
TEST_ASSERT_STATUS(status);
|
||||
|
||||
// Test Big Decimal input.
|
||||
@ -788,135 +790,141 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() {
|
||||
TEST_ASSERT_STATUS(status);
|
||||
Formattable fable("12.34", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(34, fd.decimalDigits);
|
||||
ASSERT_EQUAL(34, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(12, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(34, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(34, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fable.setDecimalNumber("12.345678901234567890123456789", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(345678901234567890LL, fd.decimalDigits);
|
||||
ASSERT_EQUAL(34567890123456789LL, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(12, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(345678901234567890LL, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(34567890123456789LL, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
// On field overflow, Integer part is truncated on the left, fraction part on the right.
|
||||
fable.setDecimalNumber("123456789012345678901234567890.123456789012345678901234567890", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(123456789012345678LL, fd.decimalDigits);
|
||||
ASSERT_EQUAL(123456789012345678LL, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(345678901234567890LL, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(123456789012345678LL, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(123456789012345678LL, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(345678901234567890LL, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
// Digits way to the right of the decimal but within the format's precision aren't truncated
|
||||
fable.setDecimalNumber("1.0000000000000000000012", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(12, fd.decimalDigits);
|
||||
ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(1, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
// Digits beyond the precision of the format are rounded away
|
||||
fable.setDecimalNumber("1.000000000000000000000012", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(1, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
// Negative numbers come through
|
||||
fable.setDecimalNumber("-1.0000000000000000000012", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(12, fd.decimalDigits);
|
||||
ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(1, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative);
|
||||
ASSERT_EQUAL(22, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(12, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(1, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(TRUE, fd.isNegative());
|
||||
|
||||
// MinFractionDigits from format larger than from number.
|
||||
fable.setDecimalNumber("1000000000000000000000.3", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(30, fd.decimalDigits);
|
||||
ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(100000000000000000LL, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(30, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(100000000000000000LL, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fable.setDecimalNumber("1000000000000000050000.3", status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(30, fd.decimalDigits);
|
||||
ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(50000LL, fd.intValue);
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(30, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(3, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(50000LL, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
// Test some int64_t values that are out of the range of a double
|
||||
fable.setInt64(4503599627370496LL);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(4503599627370496LL, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(4503599627370496LL, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fable.setInt64(4503599627370497LL);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(4503599627370497LL, fd.intValue);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
ASSERT_EQUAL(4503599627370497LL, fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
fable.setInt64(9223372036854775807LL);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
fd = df->getFixedDecimal(fable, status);
|
||||
df->formatToDecimalQuantity(fable, fd, status);
|
||||
TEST_ASSERT_STATUS(status);
|
||||
ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
|
||||
ASSERT_EQUAL(0, fd.decimalDigits);
|
||||
ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
|
||||
ASSERT_EQUAL(2, fd.getPluralOperand(PLURAL_OPERAND_V));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_F));
|
||||
ASSERT_EQUAL(0, fd.getPluralOperand(PLURAL_OPERAND_T));
|
||||
// note: going through DigitList path to FixedDecimal, which is trimming
|
||||
// int64_t fields to 18 digits. See ticket Ticket #10374
|
||||
// ASSERT_EQUAL(223372036854775807LL, fd.intValue);
|
||||
if (!(fd.intValue == 223372036854775807LL || fd.intValue == 9223372036854775807LL)) {
|
||||
dataerrln("File %s, Line %d, fd.intValue = %lld", __FILE__, __LINE__, fd.intValue);
|
||||
// ASSERT_EQUAL(223372036854775807LL, fd.getPluralOperand(PLURAL_OPERAND_I);
|
||||
if (!(
|
||||
fd.getPluralOperand(PLURAL_OPERAND_I) == 223372036854775807LL ||
|
||||
fd.getPluralOperand(PLURAL_OPERAND_I) == 9223372036854775807LL)) {
|
||||
dataerrln(
|
||||
"File %s, Line %d, fd.getPluralOperand(PLURAL_OPERAND_I = %lld",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
fd.getPluralOperand(PLURAL_OPERAND_I));
|
||||
}
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative);
|
||||
ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
|
||||
ASSERT_EQUAL(FALSE, fd.isNegative());
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "charstr.h"
|
||||
#include "cstring.h"
|
||||
#include "cmemory.h"
|
||||
#include "digitlst.h"
|
||||
|
||||
static NumberFormatTestTuple *gNullPtr = NULL;
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "unicode/measfmt.h"
|
||||
#include "unicode/curramt.h"
|
||||
#include "unicode/strenum.h"
|
||||
#include "digitlst.h"
|
||||
#include "textfile.h"
|
||||
#include "tokiter.h"
|
||||
#include "charstr.h"
|
||||
@ -40,6 +39,7 @@
|
||||
#include "numberformattesttuple.h"
|
||||
#include "datadrivennumberformattestsuite.h"
|
||||
#include "unicode/msgfmt.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
#if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390)
|
||||
// These should not be macros. If they are,
|
||||
@ -62,6 +62,7 @@ namespace std {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using icu::number::impl::DecimalQuantity;
|
||||
|
||||
class NumberFormatTestDataDriven : public DataDrivenNumberFormatTestSuite {
|
||||
protected:
|
||||
@ -83,34 +84,34 @@ UBool isParseCurrencyPass(
|
||||
UErrorCode &status);
|
||||
};
|
||||
|
||||
static DigitList &strToDigitList(
|
||||
static DecimalQuantity &strToDigitList(
|
||||
const UnicodeString &str,
|
||||
DigitList &digitList,
|
||||
DecimalQuantity &digitList,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return digitList;
|
||||
}
|
||||
if (str == "NaN") {
|
||||
digitList.set(uprv_getNaN());
|
||||
digitList.setToDouble(uprv_getNaN());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "-Inf") {
|
||||
digitList.set(-1*uprv_getInfinity());
|
||||
digitList.setToDouble(-1*uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "Inf") {
|
||||
digitList.set(uprv_getInfinity());
|
||||
digitList.setToDouble(uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
CharString formatValue;
|
||||
formatValue.appendInvariantChars(str, status);
|
||||
digitList.set(StringPiece(formatValue.data()), status, 0);
|
||||
digitList.setToDecNumber(StringPiece(formatValue.data()));
|
||||
return digitList;
|
||||
}
|
||||
|
||||
static UnicodeString &format(
|
||||
const DecimalFormat &fmt,
|
||||
const DigitList &digitList,
|
||||
const DecimalQuantity &digitList,
|
||||
UnicodeString &appendTo,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
@ -315,7 +316,7 @@ UBool NumberFormatTestDataDriven::isFormatPass(
|
||||
if (appendErrorMessage.length() > 0) {
|
||||
return FALSE;
|
||||
}
|
||||
DigitList digitList;
|
||||
DecimalQuantity digitList;
|
||||
strToDigitList(tuple.format, digitList, status);
|
||||
{
|
||||
UnicodeString appendTo;
|
||||
@ -330,7 +331,7 @@ UBool NumberFormatTestDataDriven::isFormatPass(
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
double doubleVal = digitList.getDouble();
|
||||
double doubleVal = digitList.toDouble();
|
||||
{
|
||||
UnicodeString appendTo;
|
||||
format(*fmtPtr, doubleVal, appendTo, status);
|
||||
@ -345,7 +346,7 @@ UBool NumberFormatTestDataDriven::isFormatPass(
|
||||
}
|
||||
}
|
||||
if (!uprv_isNaN(doubleVal) && !uprv_isInfinite(doubleVal) && doubleVal == uprv_floor(doubleVal)) {
|
||||
int64_t intVal = digitList.getInt64();
|
||||
int64_t intVal = digitList.toLong();
|
||||
{
|
||||
UnicodeString appendTo;
|
||||
format(*fmtPtr, intVal, appendTo, status);
|
||||
@ -446,13 +447,13 @@ UBool NumberFormatTestDataDriven::isParsePass(
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
DigitList expected;
|
||||
DecimalQuantity expected;
|
||||
strToDigitList(tuple.output, expected, status);
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("Error parsing.");
|
||||
return FALSE;
|
||||
}
|
||||
if (expected != *result.getDigitList()) {
|
||||
if (expected != *result.getDecimalQuantity()) {
|
||||
appendErrorMessage.append(UnicodeString("Expected: ") + tuple.output + ", but got: " + resultStr + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
@ -490,13 +491,13 @@ UBool NumberFormatTestDataDriven::isParseCurrencyPass(
|
||||
appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
|
||||
return TRUE; // TRUE because failure handling is in the test suite
|
||||
}
|
||||
DigitList expected;
|
||||
DecimalQuantity expected;
|
||||
strToDigitList(tuple.output, expected, status);
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("Error parsing.");
|
||||
return FALSE;
|
||||
}
|
||||
if (expected != *currAmt->getNumber().getDigitList()) {
|
||||
if (expected != *currAmt->getNumber().getDecimalQuantity()) {
|
||||
appendErrorMessage.append(UnicodeString("Expected: ") + tuple.output + ", but got: " + resultStr + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
@ -7024,9 +7025,9 @@ void NumberFormatTest::TestDecimal() {
|
||||
dataerrln("Unable to create NumberFormat");
|
||||
} else {
|
||||
UnicodeString formattedResult;
|
||||
DigitList dl;
|
||||
DecimalQuantity dl;
|
||||
StringPiece num("123.4566666666666666666666666666666666621E+40");
|
||||
dl.set(num, status);
|
||||
dl.setToDecNumber(num);
|
||||
ASSERT_SUCCESS(status);
|
||||
fmtr->format(dl, formattedResult, NULL, status);
|
||||
ASSERT_SUCCESS(status);
|
||||
@ -7034,7 +7035,7 @@ void NumberFormatTest::TestDecimal() {
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
num.set("666.666");
|
||||
dl.set(num, status);
|
||||
dl.setToDecNumber(num);
|
||||
FieldPosition pos(NumberFormat::FRACTION_FIELD);
|
||||
ASSERT_SUCCESS(status);
|
||||
formattedResult.remove();
|
||||
@ -8671,14 +8672,6 @@ void NumberFormatTest::Test11868() {
|
||||
}
|
||||
}
|
||||
|
||||
void NumberFormatTest::Test10727_RoundingZero() {
|
||||
DigitList d;
|
||||
d.set(-0.0);
|
||||
assertFalse("", d.isPositive());
|
||||
d.round(3);
|
||||
assertFalse("", d.isPositive());
|
||||
}
|
||||
|
||||
void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
|
||||
{
|
||||
const UChar USD[] = {0x55, 0x53, 0x44, 0x0};
|
||||
|
@ -24,10 +24,12 @@
|
||||
#include "unicode/stringpiece.h"
|
||||
|
||||
#include "cmemory.h"
|
||||
#include "digitlst.h"
|
||||
#include "plurrule_impl.h"
|
||||
#include "plurults.h"
|
||||
#include "uhash.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
using icu::number::impl::DecimalQuantity;
|
||||
|
||||
void setupResult(const int32_t testSource[], char result[], int32_t* max);
|
||||
UBool checkEqual(const PluralRules &test, char *result, int32_t max);
|
||||
@ -633,14 +635,14 @@ void PluralRulesTest::checkSelect(const LocalPointer<PluralRules> &rules, UError
|
||||
}
|
||||
|
||||
// DigitList is a convenient way to parse the decimal number string and get a double.
|
||||
DigitList dl;
|
||||
dl.set(StringPiece(num), status);
|
||||
DecimalQuantity dl;
|
||||
dl.setToDecNumber(StringPiece(num));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("file %s, line %d, ICU error status: %s.", __FILE__, line, u_errorName(status));
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
double numDbl = dl.getDouble();
|
||||
double numDbl = dl.toDouble();
|
||||
const char *decimalPoint = strchr(num, '.');
|
||||
int fractionDigitCount = decimalPoint == NULL ? 0 : (num + strlen(num) - 1) - decimalPoint;
|
||||
int fractionDigits = fractionDigitCount == 0 ? 0 : atoi(decimalPoint + 1);
|
||||
|
@ -215,7 +215,6 @@ UObject *UObjectTest::testClassNoClassID(UObject *obj, const char *className, co
|
||||
#include "rbt_data.h"
|
||||
#include "nultrans.h"
|
||||
#include "anytrans.h"
|
||||
#include "digitlst.h"
|
||||
#include "esctrn.h"
|
||||
#include "funcrepl.h"
|
||||
#include "servnotf.h"
|
||||
|
Loading…
Reference in New Issue
Block a user