X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/f3c0d7a59d99c2a94c6b8822291f0e42be3773c9..c5116b9f5a666b9d59f443b3770acd6ef64dc6c3:/icuSources/i18n/nfsubs.cpp diff --git a/icuSources/i18n/nfsubs.cpp b/icuSources/i18n/nfsubs.cpp index 688d1090..7bc4da8b 100644 --- a/icuSources/i18n/nfsubs.cpp +++ b/icuSources/i18n/nfsubs.cpp @@ -19,8 +19,9 @@ #include "utypeinfo.h" // for 'typeid' to work #include "nfsubs.h" -#include "digitlst.h" #include "fmtableimp.h" +#include "putilimp.h" +#include "number_decimalquantity.h" #if U_HAVE_RBNF @@ -47,6 +48,8 @@ static const UChar gGreaterGreaterThan[] = U_NAMESPACE_BEGIN +using number::impl::DecimalQuantity; + class SameValueSubstitution : public NFSubstitution { public: SameValueSubstitution(int32_t pos, @@ -111,7 +114,7 @@ public: return newRuleValue * divisor; } - virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; } + virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast(divisor); } virtual UChar tokenChar() const { return (UChar)0x003c; } // '<' @@ -148,20 +151,21 @@ public: virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const; virtual int64_t transformNumber(int64_t number) const { return number % divisor; } - virtual double transformNumber(double number) const { return uprv_fmod(number, divisor); } + virtual double transformNumber(double number) const { return uprv_fmod(number, static_cast(divisor)); } virtual UBool doParse(const UnicodeString& text, ParsePosition& parsePosition, double baseValue, double upperBound, UBool lenientParse, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const; virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { - return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue; + return oldRuleValue - uprv_fmod(oldRuleValue, static_cast(divisor)) + newRuleValue; } - virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; } + virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast(divisor); } virtual UBool isModulusSubstitution() const { return TRUE; } @@ -221,6 +225,7 @@ public: double baseValue, double upperBound, UBool lenientParse, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const; virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; } @@ -292,6 +297,7 @@ public: double baseValue, double upperBound, UBool /*lenientParse*/, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const; virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue / oldRuleValue; } @@ -689,6 +695,7 @@ NFSubstitution::doParse(const UnicodeString& text, double baseValue, double upperBound, UBool lenientParse, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const { #ifdef RBNF_DEBUG @@ -709,7 +716,7 @@ NFSubstitution::doParse(const UnicodeString& text, // on), then also try parsing the text using a default- // constructed NumberFormat if (ruleSet != NULL) { - ruleSet->parse(text, parsePosition, upperBound, result); + ruleSet->parse(text, parsePosition, upperBound, nonNumericalExecutedRuleMask, result); if (lenientParse && !ruleSet->isFractionRuleSet() && parsePosition.getIndex() == 0) { UErrorCode status = U_ZERO_ERROR; NumberFormat* fmt = NumberFormat::createInstance(status); @@ -949,18 +956,19 @@ ModulusSubstitution::doParse(const UnicodeString& text, double baseValue, double upperBound, UBool lenientParse, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const { // if this isn't a >>> substitution, we can just use the // inherited parse() routine to do the parsing if (ruleToUse == NULL) { - return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, result); + return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, nonNumericalExecutedRuleMask, result); // but if it IS a >>> substitution, we have to do it here: we // use the specific rule's doParse() method, and then we have to // do some of the other work of NFRuleSet.parse() } else { - ruleToUse->doParse(text, parsePosition, FALSE, upperBound, result); + ruleToUse->doParse(text, parsePosition, FALSE, upperBound, nonNumericalExecutedRuleMask, result); if (parsePosition.getIndex() != 0) { UErrorCode status = U_ZERO_ERROR; @@ -1082,13 +1090,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. @@ -1097,7 +1104,7 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser } else { pad = TRUE; } - int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0; + int64_t digit = dl.getDigit(didx); getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status); } @@ -1136,12 +1143,13 @@ FractionalPartSubstitution::doParse(const UnicodeString& text, double baseValue, double /*upperBound*/, UBool lenientParse, + uint32_t nonNumericalExecutedRuleMask, Formattable& resVal) const { // if we're not in byDigits mode, we can just use the inherited // doParse() if (!byDigits) { - return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, resVal); + return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, nonNumericalExecutedRuleMask, resVal); // if we ARE in byDigits mode, parse the text one digit at a time // using this substitution's owning rule set (we do this by setting @@ -1154,12 +1162,13 @@ FractionalPartSubstitution::doParse(const UnicodeString& text, int32_t digit; // double p10 = 0.1; - DigitList dl; + DecimalQuantity dl; + int32_t totalDigits = 0; NumberFormat* fmt = NULL; while (workText.length() > 0 && workPos.getIndex() != 0) { workPos.setIndex(0); Formattable temp; - getRuleSet()->parse(workText, workPos, 10, temp); + getRuleSet()->parse(workText, workPos, 10, nonNumericalExecutedRuleMask, temp); UErrorCode status = U_ZERO_ERROR; digit = temp.getLong(status); // digit = temp.getType() == Formattable::kLong ? @@ -1182,7 +1191,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text, } if (workPos.getIndex() != 0) { - dl.append((char)('0' + digit)); + dl.appendDigit(static_cast(digit), 0, true); + totalDigits++; // result += digit * p10; // p10 /= 10; parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex()); @@ -1195,7 +1205,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text, } delete fmt; - result = dl.getCount() == 0 ? 0 : dl.getDouble(); + dl.adjustMagnitude(-totalDigits); + result = dl.toDouble(); result = composeRuleValue(result, baseValue); resVal.setDouble(result); return TRUE; @@ -1267,6 +1278,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text, double baseValue, double upperBound, UBool /*lenientParse*/, + uint32_t nonNumericalExecutedRuleMask, Formattable& result) const { // we don't have to do anything special to do the parsing here, @@ -1285,7 +1297,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text, while (workText.length() > 0 && workPos.getIndex() != 0) { workPos.setIndex(0); - getRuleSet()->parse(workText, workPos, 1, temp); // parse zero or nothing at all + getRuleSet()->parse(workText, workPos, 1, nonNumericalExecutedRuleMask, temp); // parse zero or nothing at all if (workPos.getIndex() == 0) { // we failed, either there were no more zeros, or the number was formatted with digits // either way, we're done @@ -1307,7 +1319,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text, } // we've parsed off the zeros, now let's parse the rest from our current position - NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, result); + NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, nonNumericalExecutedRuleMask, result); if (withZeros) { // any base value will do in this case. is there a way to