Home | History | Annotate | Download | only in i18n
      1 /*
      2  * Copyright (C) 2015, International Business Machines
      3  * Corporation and others.  All Rights Reserved.
      4  *
      5  * file name: decimfmtimpl.cpp
      6  */
      7 
      8 #include "unicode/utypes.h"
      9 
     10 #if !UCONFIG_NO_FORMATTING
     11 
     12 #include <math.h>
     13 #include "unicode/numfmt.h"
     14 #include "unicode/plurrule.h"
     15 #include "unicode/ustring.h"
     16 #include "decimalformatpattern.h"
     17 #include "decimalformatpatternimpl.h"
     18 #include "decimfmtimpl.h"
     19 #include "fphdlimp.h"
     20 #include "plurrule_impl.h"
     21 #include "valueformatter.h"
     22 #include "visibledigits.h"
     23 
     24 U_NAMESPACE_BEGIN
     25 
     26 static const int32_t kMaxScientificIntegerDigits = 8;
     27 
     28 static const int32_t kFormattingPosPrefix = (1 << 0);
     29 static const int32_t kFormattingNegPrefix = (1 << 1);
     30 static const int32_t kFormattingPosSuffix = (1 << 2);
     31 static const int32_t kFormattingNegSuffix = (1 << 3);
     32 static const int32_t kFormattingSymbols = (1 << 4);
     33 static const int32_t kFormattingCurrency = (1 << 5);
     34 static const int32_t kFormattingUsesCurrency = (1 << 6);
     35 static const int32_t kFormattingPluralRules = (1 << 7);
     36 static const int32_t kFormattingAffixParser = (1 << 8);
     37 static const int32_t kFormattingCurrencyAffixInfo = (1 << 9);
     38 static const int32_t kFormattingAll = (1 << 10) - 1;
     39 static const int32_t kFormattingAffixes =
     40         kFormattingPosPrefix | kFormattingPosSuffix |
     41         kFormattingNegPrefix | kFormattingNegSuffix;
     42 static const int32_t kFormattingAffixParserWithCurrency =
     43         kFormattingAffixParser | kFormattingCurrencyAffixInfo;
     44 
     45 DecimalFormatImpl::DecimalFormatImpl(
     46         NumberFormat *super,
     47         const Locale &locale,
     48         const UnicodeString &pattern,
     49         UErrorCode &status)
     50         : fSuper(super),
     51           fScale(0),
     52           fRoundingMode(DecimalFormat::kRoundHalfEven),
     53           fSymbols(NULL),
     54           fCurrencyUsage(UCURR_USAGE_STANDARD),
     55           fRules(NULL),
     56           fMonetary(FALSE) {
     57     if (U_FAILURE(status)) {
     58         return;
     59     }
     60     fSymbols = new DecimalFormatSymbols(
     61             locale, status);
     62     if (fSymbols == NULL) {
     63         status = U_MEMORY_ALLOCATION_ERROR;
     64         return;
     65     }
     66     UParseError parseError;
     67     applyPattern(pattern, FALSE, parseError, status);
     68     updateAll(status);
     69 }
     70 
     71 DecimalFormatImpl::DecimalFormatImpl(
     72         NumberFormat *super,
     73         const UnicodeString &pattern,
     74         DecimalFormatSymbols *symbolsToAdopt,
     75         UParseError &parseError,
     76         UErrorCode &status)
     77         : fSuper(super),
     78           fScale(0),
     79           fRoundingMode(DecimalFormat::kRoundHalfEven),
     80           fSymbols(symbolsToAdopt),
     81           fCurrencyUsage(UCURR_USAGE_STANDARD),
     82           fRules(NULL),
     83           fMonetary(FALSE) {
     84     applyPattern(pattern, FALSE, parseError, status);
     85     updateAll(status);
     86 }
     87 
     88 DecimalFormatImpl::DecimalFormatImpl(
     89     NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) :
     90           fSuper(super),
     91           fMultiplier(other.fMultiplier),
     92           fScale(other.fScale),
     93           fRoundingMode(other.fRoundingMode),
     94           fMinSigDigits(other.fMinSigDigits),
     95           fMaxSigDigits(other.fMaxSigDigits),
     96           fUseScientific(other.fUseScientific),
     97           fUseSigDigits(other.fUseSigDigits),
     98           fGrouping(other.fGrouping),
     99           fPositivePrefixPattern(other.fPositivePrefixPattern),
    100           fNegativePrefixPattern(other.fNegativePrefixPattern),
    101           fPositiveSuffixPattern(other.fPositiveSuffixPattern),
    102           fNegativeSuffixPattern(other.fNegativeSuffixPattern),
    103           fSymbols(other.fSymbols),
    104           fCurrencyUsage(other.fCurrencyUsage),
    105           fRules(NULL),
    106           fMonetary(other.fMonetary),
    107           fAffixParser(other.fAffixParser),
    108           fCurrencyAffixInfo(other.fCurrencyAffixInfo),
    109           fEffPrecision(other.fEffPrecision),
    110           fEffGrouping(other.fEffGrouping),
    111           fOptions(other.fOptions),
    112           fFormatter(other.fFormatter),
    113           fAffixes(other.fAffixes) {
    114     fSymbols = new DecimalFormatSymbols(*fSymbols);
    115     if (fSymbols == NULL && U_SUCCESS(status)) {
    116         status = U_MEMORY_ALLOCATION_ERROR;
    117     }
    118     if (other.fRules != NULL) {
    119         fRules = new PluralRules(*other.fRules);
    120         if (fRules == NULL && U_SUCCESS(status)) {
    121             status = U_MEMORY_ALLOCATION_ERROR;
    122         }
    123     }
    124 }
    125 
    126 
    127 DecimalFormatImpl &
    128 DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) {
    129     if (U_FAILURE(status) || this == &other) {
    130         return (*this);
    131     }
    132     UObject::operator=(other);
    133     fMultiplier = other.fMultiplier;
    134     fScale = other.fScale;
    135     fRoundingMode = other.fRoundingMode;
    136     fMinSigDigits = other.fMinSigDigits;
    137     fMaxSigDigits = other.fMaxSigDigits;
    138     fUseScientific = other.fUseScientific;
    139     fUseSigDigits = other.fUseSigDigits;
    140     fGrouping = other.fGrouping;
    141     fPositivePrefixPattern = other.fPositivePrefixPattern;
    142     fNegativePrefixPattern = other.fNegativePrefixPattern;
    143     fPositiveSuffixPattern = other.fPositiveSuffixPattern;
    144     fNegativeSuffixPattern = other.fNegativeSuffixPattern;
    145     fCurrencyUsage = other.fCurrencyUsage;
    146     fMonetary = other.fMonetary;
    147     fAffixParser = other.fAffixParser;
    148     fCurrencyAffixInfo = other.fCurrencyAffixInfo;
    149     fEffPrecision = other.fEffPrecision;
    150     fEffGrouping = other.fEffGrouping;
    151     fOptions = other.fOptions;
    152     fFormatter = other.fFormatter;
    153     fAffixes = other.fAffixes;
    154     *fSymbols = *other.fSymbols;
    155     if (fRules != NULL && other.fRules != NULL) {
    156         *fRules = *other.fRules;
    157     } else {
    158         delete fRules;
    159         fRules = other.fRules;
    160         if (fRules != NULL) {
    161             fRules = new PluralRules(*fRules);
    162             if (fRules == NULL) {
    163                 status = U_MEMORY_ALLOCATION_ERROR;
    164                 return *this;
    165             }
    166         }
    167     }
    168     return *this;
    169 }
    170 
    171 UBool
    172 DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const {
    173     if (this == &other) {
    174         return TRUE;
    175     }
    176     return (fMultiplier == other.fMultiplier)
    177             && (fScale == other.fScale)
    178             && (fRoundingMode == other.fRoundingMode)
    179             && (fMinSigDigits == other.fMinSigDigits)
    180             && (fMaxSigDigits == other.fMaxSigDigits)
    181             && (fUseScientific == other.fUseScientific)
    182             && (fUseSigDigits == other.fUseSigDigits)
    183             && fGrouping.equals(other.fGrouping)
    184             && fPositivePrefixPattern.equals(other.fPositivePrefixPattern)
    185             && fNegativePrefixPattern.equals(other.fNegativePrefixPattern)
    186             && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern)
    187             && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern)
    188             && fCurrencyUsage == other.fCurrencyUsage
    189             && fAffixParser.equals(other.fAffixParser)
    190             && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo)
    191             && fEffPrecision.equals(other.fEffPrecision)
    192             && fEffGrouping.equals(other.fEffGrouping)
    193             && fOptions.equals(other.fOptions)
    194             && fFormatter.equals(other.fFormatter)
    195             && fAffixes.equals(other.fAffixes)
    196             && (*fSymbols == *other.fSymbols)
    197             && ((fRules == other.fRules) || (
    198                     (fRules != NULL) && (other.fRules != NULL)
    199                     && (*fRules == *other.fRules)))
    200             && (fMonetary == other.fMonetary);
    201 }
    202 
    203 DecimalFormatImpl::~DecimalFormatImpl() {
    204     delete fSymbols;
    205     delete fRules;
    206 }
    207 
    208 ValueFormatter &
    209 DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const {
    210     if (fUseScientific) {
    211         vf.prepareScientificFormatting(
    212                 fFormatter, fEffPrecision, fOptions);
    213         return vf;
    214     }
    215     vf.prepareFixedDecimalFormatting(
    216             fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantissa);
    217     return vf;
    218 }
    219 
    220 int32_t
    221 DecimalFormatImpl::getPatternScale() const {
    222     UBool usesPercent = fPositivePrefixPattern.usesPercent() ||
    223             fPositiveSuffixPattern.usesPercent() ||
    224             fNegativePrefixPattern.usesPercent() ||
    225             fNegativeSuffixPattern.usesPercent();
    226     if (usesPercent) {
    227         return 2;
    228     }
    229     UBool usesPermill = fPositivePrefixPattern.usesPermill() ||
    230             fPositiveSuffixPattern.usesPermill() ||
    231             fNegativePrefixPattern.usesPermill() ||
    232             fNegativeSuffixPattern.usesPermill();
    233     if (usesPermill) {
    234         return 3;
    235     }
    236     return 0;
    237 }
    238 
    239 void
    240 DecimalFormatImpl::setMultiplierScale(int32_t scale) {
    241     if (scale == 0) {
    242         // Needed to preserve equality. fMultiplier == 0 means
    243         // multiplier is 1.
    244         fMultiplier.set(0);
    245     } else {
    246         fMultiplier.set(1);
    247         fMultiplier.shiftDecimalRight(scale);
    248     }
    249 }
    250 
    251 UnicodeString &
    252 DecimalFormatImpl::format(
    253         int32_t number,
    254         UnicodeString &appendTo,
    255         FieldPosition &pos,
    256         UErrorCode &status) const {
    257     FieldPositionOnlyHandler handler(pos);
    258     return formatInt32(number, appendTo, handler, status);
    259 }
    260 
    261 UnicodeString &
    262 DecimalFormatImpl::format(
    263         int32_t number,
    264         UnicodeString &appendTo,
    265         FieldPositionIterator *posIter,
    266         UErrorCode &status) const {
    267     FieldPositionIteratorHandler handler(posIter, status);
    268     return formatInt32(number, appendTo, handler, status);
    269 }
    270 
    271 template<class T>
    272 UBool DecimalFormatImpl::maybeFormatWithDigitList(
    273         T number,
    274         UnicodeString &appendTo,
    275         FieldPositionHandler &handler,
    276         UErrorCode &status) const {
    277     if (!fMultiplier.isZero()) {
    278         DigitList digits;
    279         digits.set(number);
    280         digits.mult(fMultiplier, status);
    281         digits.shiftDecimalRight(fScale);
    282         formatAdjustedDigitList(digits, appendTo, handler, status);
    283         return TRUE;
    284     }
    285     if (fScale != 0) {
    286         DigitList digits;
    287         digits.set(number);
    288         digits.shiftDecimalRight(fScale);
    289         formatAdjustedDigitList(digits, appendTo, handler, status);
    290         return TRUE;
    291     }
    292     return FALSE;
    293 }
    294 
    295 template<class T>
    296 UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
    297         T number,
    298         VisibleDigitsWithExponent &visibleDigits,
    299         UErrorCode &status) const {
    300     if (!fMultiplier.isZero()) {
    301         DigitList digits;
    302         digits.set(number);
    303         digits.mult(fMultiplier, status);
    304         digits.shiftDecimalRight(fScale);
    305         initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
    306         return TRUE;
    307     }
    308     if (fScale != 0) {
    309         DigitList digits;
    310         digits.set(number);
    311         digits.shiftDecimalRight(fScale);
    312         initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
    313         return TRUE;
    314     }
    315     return FALSE;
    316 }
    317 
    318 UnicodeString &
    319 DecimalFormatImpl::formatInt32(
    320         int32_t number,
    321         UnicodeString &appendTo,
    322         FieldPositionHandler &handler,
    323         UErrorCode &status) const {
    324     if (maybeFormatWithDigitList(number, appendTo, handler, status)) {
    325         return appendTo;
    326     }
    327     ValueFormatter vf;
    328     return fAffixes.formatInt32(
    329             number,
    330             prepareValueFormatter(vf),
    331             handler,
    332             fRules,
    333             appendTo,
    334             status);
    335 }
    336 
    337 UnicodeString &
    338 DecimalFormatImpl::formatInt64(
    339         int64_t number,
    340         UnicodeString &appendTo,
    341         FieldPositionHandler &handler,
    342         UErrorCode &status) const {
    343     if (number >= INT32_MIN && number <= INT32_MAX) {
    344         return formatInt32((int32_t) number, appendTo, handler, status);
    345     }
    346     VisibleDigitsWithExponent digits;
    347     initVisibleDigitsWithExponent(number, digits, status);
    348     return formatVisibleDigitsWithExponent(
    349             digits, appendTo, handler, status);
    350 }
    351 
    352 UnicodeString &
    353 DecimalFormatImpl::formatDouble(
    354         double number,
    355         UnicodeString &appendTo,
    356         FieldPositionHandler &handler,
    357         UErrorCode &status) const {
    358     VisibleDigitsWithExponent digits;
    359     initVisibleDigitsWithExponent(number, digits, status);
    360     return formatVisibleDigitsWithExponent(
    361             digits, appendTo, handler, status);
    362 }
    363 
    364 UnicodeString &
    365 DecimalFormatImpl::format(
    366         double number,
    367         UnicodeString &appendTo,
    368         FieldPosition &pos,
    369         UErrorCode &status) const {
    370     FieldPositionOnlyHandler handler(pos);
    371     return formatDouble(number, appendTo, handler, status);
    372 }
    373 
    374 UnicodeString &
    375 DecimalFormatImpl::format(
    376         const DigitList &number,
    377         UnicodeString &appendTo,
    378         FieldPosition &pos,
    379         UErrorCode &status) const {
    380     DigitList dl(number);
    381     FieldPositionOnlyHandler handler(pos);
    382     return formatDigitList(dl, appendTo, handler, status);
    383 }
    384 
    385 UnicodeString &
    386 DecimalFormatImpl::format(
    387         int64_t number,
    388         UnicodeString &appendTo,
    389         FieldPosition &pos,
    390         UErrorCode &status) const {
    391     FieldPositionOnlyHandler handler(pos);
    392     return formatInt64(number, appendTo, handler, status);
    393 }
    394 
    395 UnicodeString &
    396 DecimalFormatImpl::format(
    397         int64_t number,
    398         UnicodeString &appendTo,
    399         FieldPositionIterator *posIter,
    400         UErrorCode &status) const {
    401     FieldPositionIteratorHandler handler(posIter, status);
    402     return formatInt64(number, appendTo, handler, status);
    403 }
    404 
    405 UnicodeString &
    406 DecimalFormatImpl::format(
    407         double number,
    408         UnicodeString &appendTo,
    409         FieldPositionIterator *posIter,
    410         UErrorCode &status) const {
    411     FieldPositionIteratorHandler handler(posIter, status);
    412     return formatDouble(number, appendTo, handler, status);
    413 }
    414 
    415 UnicodeString &
    416 DecimalFormatImpl::format(
    417         const DigitList &number,
    418         UnicodeString &appendTo,
    419         FieldPositionIterator *posIter,
    420         UErrorCode &status) const {
    421     DigitList dl(number);
    422     FieldPositionIteratorHandler handler(posIter, status);
    423     return formatDigitList(dl, appendTo, handler, status);
    424 }
    425 
    426 UnicodeString &
    427 DecimalFormatImpl::format(
    428         const StringPiece &number,
    429         UnicodeString &appendTo,
    430         FieldPositionIterator *posIter,
    431         UErrorCode &status) const {
    432     DigitList dl;
    433     dl.set(number, status);
    434     FieldPositionIteratorHandler handler(posIter, status);
    435     return formatDigitList(dl, appendTo, handler, status);
    436 }
    437 
    438 UnicodeString &
    439 DecimalFormatImpl::format(
    440         const VisibleDigitsWithExponent &digits,
    441         UnicodeString &appendTo,
    442         FieldPosition &pos,
    443         UErrorCode &status) const {
    444     FieldPositionOnlyHandler handler(pos);
    445     return formatVisibleDigitsWithExponent(
    446             digits, appendTo, handler, status);
    447 }
    448 
    449 UnicodeString &
    450 DecimalFormatImpl::format(
    451         const VisibleDigitsWithExponent &digits,
    452         UnicodeString &appendTo,
    453         FieldPositionIterator *posIter,
    454         UErrorCode &status) const {
    455     FieldPositionIteratorHandler handler(posIter, status);
    456     return formatVisibleDigitsWithExponent(
    457             digits, appendTo, handler, status);
    458 }
    459 
    460 DigitList &
    461 DecimalFormatImpl::adjustDigitList(
    462         DigitList &number, UErrorCode &status) const {
    463     number.setRoundingMode(fRoundingMode);
    464     if (!fMultiplier.isZero()) {
    465         number.mult(fMultiplier, status);
    466     }
    467     if (fScale != 0) {
    468         number.shiftDecimalRight(fScale);
    469     }
    470     number.reduce();
    471     return number;
    472 }
    473 
    474 UnicodeString &
    475 DecimalFormatImpl::formatDigitList(
    476         DigitList &number,
    477         UnicodeString &appendTo,
    478         FieldPositionHandler &handler,
    479         UErrorCode &status) const {
    480     VisibleDigitsWithExponent digits;
    481     initVisibleDigitsWithExponent(number, digits, status);
    482     return formatVisibleDigitsWithExponent(
    483             digits, appendTo, handler, status);
    484 }
    485 
    486 UnicodeString &
    487 DecimalFormatImpl::formatAdjustedDigitList(
    488         DigitList &number,
    489         UnicodeString &appendTo,
    490         FieldPositionHandler &handler,
    491         UErrorCode &status) const {
    492     ValueFormatter vf;
    493     return fAffixes.format(
    494             number,
    495             prepareValueFormatter(vf),
    496             handler,
    497             fRules,
    498             appendTo,
    499             status);
    500 }
    501 
    502 UnicodeString &
    503 DecimalFormatImpl::formatVisibleDigitsWithExponent(
    504         const VisibleDigitsWithExponent &digits,
    505         UnicodeString &appendTo,
    506         FieldPositionHandler &handler,
    507         UErrorCode &status) const {
    508     ValueFormatter vf;
    509     return fAffixes.format(
    510             digits,
    511             prepareValueFormatter(vf),
    512             handler,
    513             fRules,
    514             appendTo,
    515             status);
    516 }
    517 
    518 static FixedDecimal &initFixedDecimal(
    519         const VisibleDigits &digits, FixedDecimal &result) {
    520     result.source = 0.0;
    521     result.isNegative = digits.isNegative();
    522     result.isNanOrInfinity = digits.isNaNOrInfinity();
    523     digits.getFixedDecimal(
    524             result.source, result.intValue, result.decimalDigits,
    525             result.decimalDigitsWithoutTrailingZeros,
    526             result.visibleDecimalDigitCount, result.hasIntegerValue);
    527     return result;
    528 }
    529 
    530 FixedDecimal &
    531 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const {
    532     if (U_FAILURE(status)) {
    533         return result;
    534     }
    535     VisibleDigits digits;
    536     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
    537     return initFixedDecimal(digits, result);
    538 }
    539 
    540 FixedDecimal &
    541 DecimalFormatImpl::getFixedDecimal(
    542         DigitList &number, FixedDecimal &result, UErrorCode &status) const {
    543     if (U_FAILURE(status)) {
    544         return result;
    545     }
    546     VisibleDigits digits;
    547     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
    548     return initFixedDecimal(digits, result);
    549 }
    550 
    551 VisibleDigitsWithExponent &
    552 DecimalFormatImpl::initVisibleDigitsWithExponent(
    553         int64_t number,
    554         VisibleDigitsWithExponent &digits,
    555         UErrorCode &status) const {
    556     if (maybeInitVisibleDigitsFromDigitList(
    557             number, digits, status)) {
    558         return digits;
    559     }
    560     if (fUseScientific) {
    561         fEffPrecision.initVisibleDigitsWithExponent(
    562                 number, digits, status);
    563     } else {
    564         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
    565                 number, digits, status);
    566     }
    567     return digits;
    568 }
    569 
    570 VisibleDigitsWithExponent &
    571 DecimalFormatImpl::initVisibleDigitsWithExponent(
    572         double number,
    573         VisibleDigitsWithExponent &digits,
    574         UErrorCode &status) const {
    575     if (maybeInitVisibleDigitsFromDigitList(
    576             number, digits, status)) {
    577         return digits;
    578     }
    579     if (fUseScientific) {
    580         fEffPrecision.initVisibleDigitsWithExponent(
    581                 number, digits, status);
    582     } else {
    583         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
    584                 number, digits, status);
    585     }
    586     return digits;
    587 }
    588 
    589 VisibleDigitsWithExponent &
    590 DecimalFormatImpl::initVisibleDigitsWithExponent(
    591         DigitList &number,
    592         VisibleDigitsWithExponent &digits,
    593         UErrorCode &status) const {
    594     adjustDigitList(number, status);
    595     return initVisibleDigitsFromAdjusted(number, digits, status);
    596 }
    597 
    598 VisibleDigitsWithExponent &
    599 DecimalFormatImpl::initVisibleDigitsFromAdjusted(
    600         DigitList &number,
    601         VisibleDigitsWithExponent &digits,
    602         UErrorCode &status) const {
    603     if (fUseScientific) {
    604         fEffPrecision.initVisibleDigitsWithExponent(
    605                 number, digits, status);
    606     } else {
    607         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
    608                 number, digits, status);
    609     }
    610     return digits;
    611 }
    612 
    613 DigitList &
    614 DecimalFormatImpl::round(
    615         DigitList &number, UErrorCode &status) const {
    616     if (number.isNaN() || number.isInfinite()) {
    617         return number;
    618     }
    619     adjustDigitList(number, status);
    620     ValueFormatter vf;
    621     prepareValueFormatter(vf);
    622     return vf.round(number, status);
    623 }
    624 
    625 void
    626 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
    627     fMinSigDigits = newValue;
    628     fUseSigDigits = TRUE; // ticket 9936
    629     updatePrecision();
    630 }
    631 
    632 void
    633 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
    634     fMaxSigDigits = newValue;
    635     fUseSigDigits = TRUE; // ticket 9936
    636     updatePrecision();
    637 }
    638 
    639 void
    640 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
    641     fMinSigDigits = min;
    642     fMaxSigDigits = max;
    643     fUseSigDigits = TRUE; // ticket 9936
    644     updatePrecision();
    645 }
    646 
    647 void
    648 DecimalFormatImpl::setScientificNotation(UBool newValue) {
    649     fUseScientific = newValue;
    650     updatePrecision();
    651 }
    652 
    653 void
    654 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
    655     fUseSigDigits = newValue;
    656     updatePrecision();
    657 }
    658 
    659 void
    660 DecimalFormatImpl::setGroupingSize(int32_t newValue) {
    661     fGrouping.fGrouping = newValue;
    662     updateGrouping();
    663 }
    664 
    665 void
    666 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
    667     fGrouping.fGrouping2 = newValue;
    668     updateGrouping();
    669 }
    670 
    671 void
    672 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
    673     fGrouping.fMinGrouping = newValue;
    674     updateGrouping();
    675 }
    676 
    677 void
    678 DecimalFormatImpl::setCurrencyUsage(
    679         UCurrencyUsage currencyUsage, UErrorCode &status) {
    680     fCurrencyUsage = currencyUsage;
    681     updateFormatting(kFormattingCurrency, status);
    682 }
    683 
    684 void
    685 DecimalFormatImpl::setRoundingIncrement(double d) {
    686     if (d > 0.0) {
    687         fEffPrecision.fMantissa.fRoundingIncrement.set(d);
    688     } else {
    689         fEffPrecision.fMantissa.fRoundingIncrement.set(0.0);
    690     }
    691 }
    692 
    693 double
    694 DecimalFormatImpl::getRoundingIncrement() const {
    695     return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
    696 }
    697 
    698 int32_t
    699 DecimalFormatImpl::getMultiplier() const {
    700     if (fMultiplier.isZero()) {
    701         return 1;
    702     }
    703     return (int32_t) fMultiplier.getDouble();
    704 }
    705 
    706 void
    707 DecimalFormatImpl::setMultiplier(int32_t m) {
    708     if (m == 0 || m == 1) {
    709         fMultiplier.set(0);
    710     } else {
    711         fMultiplier.set(m);
    712     }
    713 }
    714 
    715 void
    716 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) {
    717     fPositivePrefixPattern.remove();
    718     fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
    719     UErrorCode status = U_ZERO_ERROR;
    720     updateFormatting(kFormattingPosPrefix, status);
    721 }
    722 
    723 void
    724 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) {
    725     fPositiveSuffixPattern.remove();
    726     fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
    727     UErrorCode status = U_ZERO_ERROR;
    728     updateFormatting(kFormattingPosSuffix, status);
    729 }
    730 
    731 void
    732 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) {
    733     fNegativePrefixPattern.remove();
    734     fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
    735     UErrorCode status = U_ZERO_ERROR;
    736     updateFormatting(kFormattingNegPrefix, status);
    737 }
    738 
    739 void
    740 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) {
    741     fNegativeSuffixPattern.remove();
    742     fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
    743     UErrorCode status = U_ZERO_ERROR;
    744     updateFormatting(kFormattingNegSuffix, status);
    745 }
    746 
    747 UnicodeString &
    748 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
    749     result = fAffixes.fPositivePrefix.getOtherVariant().toString();
    750     return result;
    751 }
    752 
    753 UnicodeString &
    754 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
    755     result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
    756     return result;
    757 }
    758 
    759 UnicodeString &
    760 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
    761     result = fAffixes.fNegativePrefix.getOtherVariant().toString();
    762     return result;
    763 }
    764 
    765 UnicodeString &
    766 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
    767     result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
    768     return result;
    769 }
    770 
    771 void
    772 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) {
    773     if (symbolsToAdopt == NULL) {
    774         return;
    775     }
    776     delete fSymbols;
    777     fSymbols = symbolsToAdopt;
    778     UErrorCode status = U_ZERO_ERROR;
    779     updateFormatting(kFormattingSymbols, status);
    780 }
    781 
    782 void
    783 DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
    784         const UnicodeString &pattern, UErrorCode &status) {
    785     UParseError perror;
    786     applyPattern(pattern, FALSE, perror, status);
    787     updateForApplyPatternFavorCurrencyPrecision(status);
    788 }
    789 
    790 void
    791 DecimalFormatImpl::applyPattern(
    792         const UnicodeString &pattern, UErrorCode &status) {
    793     UParseError perror;
    794     applyPattern(pattern, FALSE, perror, status);
    795     updateForApplyPattern(status);
    796 }
    797 
    798 void
    799 DecimalFormatImpl::applyPattern(
    800         const UnicodeString &pattern,
    801         UParseError &perror, UErrorCode &status) {
    802     applyPattern(pattern, FALSE, perror, status);
    803     updateForApplyPattern(status);
    804 }
    805 
    806 void
    807 DecimalFormatImpl::applyLocalizedPattern(
    808         const UnicodeString &pattern, UErrorCode &status) {
    809     UParseError perror;
    810     applyPattern(pattern, TRUE, perror, status);
    811     updateForApplyPattern(status);
    812 }
    813 
    814 void
    815 DecimalFormatImpl::applyLocalizedPattern(
    816         const UnicodeString &pattern,
    817         UParseError &perror,  UErrorCode &status) {
    818     applyPattern(pattern, TRUE, perror, status);
    819     updateForApplyPattern(status);
    820 }
    821 
    822 void
    823 DecimalFormatImpl::applyPattern(
    824         const UnicodeString &pattern,
    825         UBool localized, UParseError &perror, UErrorCode &status) {
    826     if (U_FAILURE(status)) {
    827         return;
    828     }
    829     DecimalFormatPatternParser patternParser;
    830     if (localized) {
    831         patternParser.useSymbols(*fSymbols);
    832     }
    833     DecimalFormatPattern out;
    834     patternParser.applyPatternWithoutExpandAffix(
    835             pattern, out, perror, status);
    836     if (U_FAILURE(status)) {
    837         return;
    838     }
    839     fUseScientific = out.fUseExponentialNotation;
    840     fUseSigDigits = out.fUseSignificantDigits;
    841     fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits);
    842     fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits);
    843     fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits);
    844     fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits);
    845     fMinSigDigits = out.fMinimumSignificantDigits;
    846     fMaxSigDigits = out.fMaximumSignificantDigits;
    847     fEffPrecision.fMinExponentDigits = out.fMinExponentDigits;
    848     fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown;
    849     fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed);
    850     fGrouping.fGrouping = out.fGroupingSize;
    851     fGrouping.fGrouping2 = out.fGroupingSize2;
    852     fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown;
    853     if (out.fRoundingIncrementUsed) {
    854         fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement;
    855     } else {
    856         fEffPrecision.fMantissa.fRoundingIncrement.clear();
    857     }
    858     fAffixes.fPadChar = out.fPad;
    859     fNegativePrefixPattern = out.fNegPrefixAffix;
    860     fNegativeSuffixPattern = out.fNegSuffixAffix;
    861     fPositivePrefixPattern = out.fPosPrefixAffix;
    862     fPositiveSuffixPattern = out.fPosSuffixAffix;
    863 
    864     // Work around. Pattern parsing code and DecimalFormat code don't agree
    865     // on the definition of field width, so we have to translate from
    866     // pattern field width to decimal format field width here.
    867     fAffixes.fWidth = out.fFormatWidth == 0 ? 0 :
    868             out.fFormatWidth + fPositivePrefixPattern.countChar32()
    869             + fPositiveSuffixPattern.countChar32();
    870     switch (out.fPadPosition) {
    871     case DecimalFormatPattern::kPadBeforePrefix:
    872         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
    873         break;
    874     case DecimalFormatPattern::kPadAfterPrefix:
    875         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
    876         break;
    877     case DecimalFormatPattern::kPadBeforeSuffix:
    878         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
    879         break;
    880     case DecimalFormatPattern::kPadAfterSuffix:
    881         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
    882         break;
    883     default:
    884         break;
    885     }
    886 }
    887 
    888 void
    889 DecimalFormatImpl::updatePrecision() {
    890     if (fUseScientific) {
    891         updatePrecisionForScientific();
    892     } else {
    893         updatePrecisionForFixed();
    894     }
    895 }
    896 
    897 static void updatePrecisionForScientificMinMax(
    898         const DigitInterval &min,
    899         const DigitInterval &max,
    900         DigitInterval &resultMin,
    901         DigitInterval &resultMax,
    902         SignificantDigitInterval &resultSignificant) {
    903     resultMin.setIntDigitCount(0);
    904     resultMin.setFracDigitCount(0);
    905     resultSignificant.clear();
    906     resultMax.clear();
    907 
    908     int32_t maxIntDigitCount = max.getIntDigitCount();
    909     int32_t minIntDigitCount = min.getIntDigitCount();
    910     int32_t maxFracDigitCount = max.getFracDigitCount();
    911     int32_t minFracDigitCount = min.getFracDigitCount();
    912 
    913 
    914     // Not in spec: maxIntDigitCount > 8 assume
    915     // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
    916     // no provision for unsetting maxIntDigitCount which would be useful for
    917     // scientific notation. The best we can do is assume that if
    918     // maxIntDigitCount is the default of 2000000000 or is "big enough" then
    919     // user did not intend to explicitly set it. The 8 was derived emperically
    920     // by extensive testing of legacy code.
    921     if (maxIntDigitCount > 8) {
    922         maxIntDigitCount = minIntDigitCount;
    923     }
    924 
    925     // Per the spec, exponent grouping happens if maxIntDigitCount is more
    926     // than 1 and more than minIntDigitCount.
    927     UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount;
    928     if (bExponentGrouping) {
    929         resultMax.setIntDigitCount(maxIntDigitCount);
    930 
    931         // For exponent grouping minIntDigits is always treated as 1 even
    932         // if it wasn't set to 1!
    933         resultMin.setIntDigitCount(1);
    934     } else {
    935         // Fixed digit count left of decimal. minIntDigitCount doesn't have
    936         // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
    937         // maxIntDigitCount == 1.
    938         int32_t fixedIntDigitCount = maxIntDigitCount;
    939 
    940         // If fixedIntDigitCount is 0 but
    941         // min or max fraction count is 0 too then use 1. This way we can get
    942         // unlimited precision for X.XXXEX
    943         if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) {
    944             fixedIntDigitCount = 1;
    945         }
    946         resultMax.setIntDigitCount(fixedIntDigitCount);
    947         resultMin.setIntDigitCount(fixedIntDigitCount);
    948     }
    949     // Spec says this is how we compute significant digits. 0 means
    950     // unlimited significant digits.
    951     int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount;
    952     if (maxSigDigits > 0) {
    953         int32_t minSigDigits = minIntDigitCount + minFracDigitCount;
    954         resultSignificant.setMin(minSigDigits);
    955         resultSignificant.setMax(maxSigDigits);
    956     }
    957 }
    958 
    959 void
    960 DecimalFormatImpl::updatePrecisionForScientific() {
    961     FixedPrecision *result = &fEffPrecision.fMantissa;
    962     if (fUseSigDigits) {
    963         result->fMax.setFracDigitCount(-1);
    964         result->fMax.setIntDigitCount(1);
    965         result->fMin.setFracDigitCount(0);
    966         result->fMin.setIntDigitCount(1);
    967         result->fSignificant.clear();
    968         extractSigDigits(result->fSignificant);
    969         return;
    970     }
    971     DigitInterval max;
    972     DigitInterval min;
    973     extractMinMaxDigits(min, max);
    974     updatePrecisionForScientificMinMax(
    975             min, max,
    976             result->fMin, result->fMax, result->fSignificant);
    977 }
    978 
    979 void
    980 DecimalFormatImpl::updatePrecisionForFixed() {
    981     FixedPrecision *result = &fEffPrecision.fMantissa;
    982     if (!fUseSigDigits) {
    983         extractMinMaxDigits(result->fMin, result->fMax);
    984         result->fSignificant.clear();
    985     } else {
    986         extractSigDigits(result->fSignificant);
    987         result->fMin.setIntDigitCount(1);
    988         result->fMin.setFracDigitCount(0);
    989         result->fMax.clear();
    990     }
    991 }
    992 
    993 void
    994  DecimalFormatImpl::extractMinMaxDigits(
    995         DigitInterval &min, DigitInterval &max) const {
    996     min.setIntDigitCount(fSuper->getMinimumIntegerDigits());
    997     max.setIntDigitCount(fSuper->getMaximumIntegerDigits());
    998     min.setFracDigitCount(fSuper->getMinimumFractionDigits());
    999     max.setFracDigitCount(fSuper->getMaximumFractionDigits());
   1000 }
   1001 
   1002 void
   1003  DecimalFormatImpl::extractSigDigits(
   1004         SignificantDigitInterval &sig) const {
   1005     sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
   1006     sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
   1007 }
   1008 
   1009 void
   1010 DecimalFormatImpl::updateGrouping() {
   1011     if (fSuper->isGroupingUsed()) {
   1012         fEffGrouping = fGrouping;
   1013     } else {
   1014         fEffGrouping.clear();
   1015     }
   1016 }
   1017 
   1018 void
   1019 DecimalFormatImpl::updateCurrency(UErrorCode &status) {
   1020     updateFormatting(kFormattingCurrency, TRUE, status);
   1021 }
   1022 
   1023 void
   1024 DecimalFormatImpl::updateFormatting(
   1025         int32_t changedFormattingFields,
   1026         UErrorCode &status) {
   1027     updateFormatting(changedFormattingFields, TRUE, status);
   1028 }
   1029 
   1030 void
   1031 DecimalFormatImpl::updateFormatting(
   1032         int32_t changedFormattingFields,
   1033         UBool updatePrecisionBasedOnCurrency,
   1034         UErrorCode &status) {
   1035     if (U_FAILURE(status)) {
   1036         return;
   1037     }
   1038     // Each function updates one field. Order matters. For instance,
   1039     // updatePluralRules comes before updateCurrencyAffixInfo because the
   1040     // fRules field is needed to update the fCurrencyAffixInfo field.
   1041     updateFormattingUsesCurrency(changedFormattingFields);
   1042     updateFormattingFixedPointFormatter(changedFormattingFields);
   1043     updateFormattingAffixParser(changedFormattingFields);
   1044     updateFormattingPluralRules(changedFormattingFields, status);
   1045     updateFormattingCurrencyAffixInfo(
   1046             changedFormattingFields,
   1047             updatePrecisionBasedOnCurrency,
   1048             status);
   1049     updateFormattingLocalizedPositivePrefix(
   1050             changedFormattingFields, status);
   1051     updateFormattingLocalizedPositiveSuffix(
   1052             changedFormattingFields, status);
   1053     updateFormattingLocalizedNegativePrefix(
   1054             changedFormattingFields, status);
   1055     updateFormattingLocalizedNegativeSuffix(
   1056             changedFormattingFields, status);
   1057 }
   1058 
   1059 void
   1060 DecimalFormatImpl::updateFormattingUsesCurrency(
   1061         int32_t &changedFormattingFields) {
   1062     if ((changedFormattingFields & kFormattingAffixes) == 0) {
   1063         // If no affixes changed, don't need to do any work
   1064         return;
   1065     }
   1066     UBool newUsesCurrency =
   1067             fPositivePrefixPattern.usesCurrency() ||
   1068             fPositiveSuffixPattern.usesCurrency() ||
   1069             fNegativePrefixPattern.usesCurrency() ||
   1070             fNegativeSuffixPattern.usesCurrency();
   1071     if (fMonetary != newUsesCurrency) {
   1072         fMonetary = newUsesCurrency;
   1073         changedFormattingFields |= kFormattingUsesCurrency;
   1074     }
   1075 }
   1076 
   1077 void
   1078 DecimalFormatImpl::updateFormattingPluralRules(
   1079         int32_t &changedFormattingFields, UErrorCode &status) {
   1080     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
   1081         // No work to do if both fSymbols and fMonetary
   1082         // fields are unchanged
   1083         return;
   1084     }
   1085     if (U_FAILURE(status)) {
   1086         return;
   1087     }
   1088     PluralRules *newRules = NULL;
   1089     if (fMonetary) {
   1090         newRules = PluralRules::forLocale(fSymbols->getLocale(), status);
   1091         if (U_FAILURE(status)) {
   1092             return;
   1093         }
   1094     }
   1095     // Its ok to say a field has changed when it really hasn't but not
   1096     // the other way around. Here we assume the field changed unless it
   1097     // was NULL before and is still NULL now
   1098     if (fRules != newRules) {
   1099         delete fRules;
   1100         fRules = newRules;
   1101         changedFormattingFields |= kFormattingPluralRules;
   1102     }
   1103 }
   1104 
   1105 void
   1106 DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
   1107         int32_t &changedFormattingFields,
   1108         UBool updatePrecisionBasedOnCurrency,
   1109         UErrorCode &status) {
   1110     if ((changedFormattingFields & (
   1111             kFormattingSymbols | kFormattingCurrency |
   1112             kFormattingUsesCurrency | kFormattingPluralRules)) == 0) {
   1113         // If all these fields are unchanged, no work to do.
   1114         return;
   1115     }
   1116     if (U_FAILURE(status)) {
   1117         return;
   1118     }
   1119     if (!fMonetary) {
   1120         if (fCurrencyAffixInfo.isDefault()) {
   1121             // In this case don't have to do any work
   1122             return;
   1123         }
   1124         fCurrencyAffixInfo.set(NULL, NULL, NULL, status);
   1125         if (U_FAILURE(status)) {
   1126             return;
   1127         }
   1128         changedFormattingFields |= kFormattingCurrencyAffixInfo;
   1129     } else {
   1130         const UChar *currency = fSuper->getCurrency();
   1131         UChar localeCurr[4];
   1132         if (currency[0] == 0) {
   1133             ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status);
   1134             if (U_SUCCESS(status)) {
   1135                 currency = localeCurr;
   1136                 fSuper->NumberFormat::setCurrency(currency, status);
   1137             } else {
   1138                 currency = NULL;
   1139                 status = U_ZERO_ERROR;
   1140             }
   1141         }
   1142         fCurrencyAffixInfo.set(
   1143                 fSymbols->getLocale().getName(), fRules, currency, status);
   1144         if (U_FAILURE(status)) {
   1145             return;
   1146         }
   1147         UBool customCurrencySymbol = FALSE;
   1148         // If DecimalFormatSymbols has custom currency symbol, prefer
   1149         // that over what we just read from the resource bundles
   1150         if (fSymbols->isCustomCurrencySymbol()) {
   1151             fCurrencyAffixInfo.setSymbol(
   1152                     fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
   1153             customCurrencySymbol = TRUE;
   1154         }
   1155         if (fSymbols->isCustomIntlCurrencySymbol()) {
   1156             fCurrencyAffixInfo.setISO(
   1157                     fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
   1158             customCurrencySymbol = TRUE;
   1159         }
   1160         changedFormattingFields |= kFormattingCurrencyAffixInfo;
   1161         if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) {
   1162             FixedPrecision precision;
   1163             CurrencyAffixInfo::adjustPrecision(
   1164                     currency, fCurrencyUsage, precision, status);
   1165             if (U_FAILURE(status)) {
   1166                 return;
   1167             }
   1168             fSuper->NumberFormat::setMinimumFractionDigits(
   1169                     precision.fMin.getFracDigitCount());
   1170             fSuper->NumberFormat::setMaximumFractionDigits(
   1171                     precision.fMax.getFracDigitCount());
   1172             updatePrecision();
   1173             fEffPrecision.fMantissa.fRoundingIncrement =
   1174                     precision.fRoundingIncrement;
   1175         }
   1176 
   1177     }
   1178 }
   1179 
   1180 void
   1181 DecimalFormatImpl::updateFormattingFixedPointFormatter(
   1182         int32_t &changedFormattingFields) {
   1183     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
   1184         // No work to do if fSymbols is unchanged
   1185         return;
   1186     }
   1187     if (fMonetary) {
   1188         fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols);
   1189     } else {
   1190         fFormatter.setDecimalFormatSymbols(*fSymbols);
   1191     }
   1192 }
   1193 
   1194 void
   1195 DecimalFormatImpl::updateFormattingAffixParser(
   1196         int32_t &changedFormattingFields) {
   1197     if ((changedFormattingFields & kFormattingSymbols) == 0) {
   1198         // No work to do if fSymbols is unchanged
   1199         return;
   1200     }
   1201     fAffixParser.setDecimalFormatSymbols(*fSymbols);
   1202     changedFormattingFields |= kFormattingAffixParser;
   1203 }
   1204 
   1205 void
   1206 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
   1207         int32_t &changedFormattingFields, UErrorCode &status) {
   1208     if (U_FAILURE(status)) {
   1209         return;
   1210     }
   1211     if ((changedFormattingFields & (
   1212             kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) {
   1213         // No work to do
   1214         return;
   1215     }
   1216     fAffixes.fPositivePrefix.remove();
   1217     fAffixParser.parse(
   1218             fPositivePrefixPattern,
   1219             fCurrencyAffixInfo,
   1220             fAffixes.fPositivePrefix,
   1221             status);
   1222 }
   1223 
   1224 void
   1225 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
   1226         int32_t &changedFormattingFields, UErrorCode &status) {
   1227     if (U_FAILURE(status)) {
   1228         return;
   1229     }
   1230     if ((changedFormattingFields & (
   1231             kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) {
   1232         // No work to do
   1233         return;
   1234     }
   1235     fAffixes.fPositiveSuffix.remove();
   1236     fAffixParser.parse(
   1237             fPositiveSuffixPattern,
   1238             fCurrencyAffixInfo,
   1239             fAffixes.fPositiveSuffix,
   1240             status);
   1241 }
   1242 
   1243 void
   1244 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
   1245         int32_t &changedFormattingFields, UErrorCode &status) {
   1246     if (U_FAILURE(status)) {
   1247         return;
   1248     }
   1249     if ((changedFormattingFields & (
   1250             kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) {
   1251         // No work to do
   1252         return;
   1253     }
   1254     fAffixes.fNegativePrefix.remove();
   1255     fAffixParser.parse(
   1256             fNegativePrefixPattern,
   1257             fCurrencyAffixInfo,
   1258             fAffixes.fNegativePrefix,
   1259             status);
   1260 }
   1261 
   1262 void
   1263 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
   1264         int32_t &changedFormattingFields, UErrorCode &status) {
   1265     if (U_FAILURE(status)) {
   1266         return;
   1267     }
   1268     if ((changedFormattingFields & (
   1269             kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) {
   1270         // No work to do
   1271         return;
   1272     }
   1273     fAffixes.fNegativeSuffix.remove();
   1274     fAffixParser.parse(
   1275             fNegativeSuffixPattern,
   1276             fCurrencyAffixInfo,
   1277             fAffixes.fNegativeSuffix,
   1278             status);
   1279 }
   1280 
   1281 void
   1282 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
   1283         UErrorCode &status) {
   1284     updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
   1285 }
   1286 
   1287 void
   1288 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
   1289     updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
   1290 }
   1291 
   1292 void
   1293 DecimalFormatImpl::updateAll(UErrorCode &status) {
   1294     updateAll(kFormattingAll, TRUE, status);
   1295 }
   1296 
   1297 void
   1298 DecimalFormatImpl::updateAll(
   1299         int32_t formattingFlags,
   1300         UBool updatePrecisionBasedOnCurrency,
   1301         UErrorCode &status) {
   1302     if (U_FAILURE(status)) {
   1303         return;
   1304     }
   1305     updatePrecision();
   1306     updateGrouping();
   1307     updateFormatting(
   1308             formattingFlags, updatePrecisionBasedOnCurrency, status);
   1309     setMultiplierScale(getPatternScale());
   1310 }
   1311 
   1312 
   1313 static int32_t
   1314 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) {
   1315     if (grouping.fGrouping <= 0) {
   1316         return 0;
   1317     }
   1318     if (grouping.fGrouping2 <= 0) {
   1319         return grouping.fGrouping + 1;
   1320     }
   1321     return grouping.fGrouping + grouping.fGrouping2 + 1;
   1322 }
   1323 
   1324 /**
   1325  * Given a grouping policy, calculates how many digits are needed left of
   1326  * the decimal point to achieve a desired length left of the
   1327  * decimal point.
   1328  * @param grouping the grouping policy
   1329  * @param desiredLength number of characters needed left of decimal point
   1330  * @param minLeftDigits at least this many digits is returned
   1331  * @param leftDigits the number of digits needed stored here
   1332  *  which is >= minLeftDigits.
   1333  * @return true if a perfect fit or false if having leftDigits would exceed
   1334  *   desiredLength
   1335  */
   1336 static UBool
   1337 getLeftDigitsForLeftLength(
   1338         const DigitGrouping &grouping,
   1339         int32_t desiredLength,
   1340         int32_t minLeftDigits,
   1341         int32_t &leftDigits) {
   1342     leftDigits = minLeftDigits;
   1343     int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits);
   1344     while (lengthSoFar < desiredLength) {
   1345         lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1;
   1346         ++leftDigits;
   1347     }
   1348     return (lengthSoFar == desiredLength);
   1349 }
   1350 
   1351 int32_t
   1352 DecimalFormatImpl::computeExponentPatternLength() const {
   1353     if (fUseScientific) {
   1354         return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
   1355     }
   1356     return 0;
   1357 }
   1358 
   1359 int32_t
   1360 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
   1361         int32_t fracDigitCount) const {
   1362     if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
   1363         return 0;
   1364     }
   1365     return fracDigitCount + 1;
   1366 }
   1367 
   1368 UnicodeString&
   1369 DecimalFormatImpl::toNumberPattern(
   1370         UBool hasPadding, int32_t minimumLength, UnicodeString& result) const {
   1371     // Get a grouping policy like the one in this object that does not
   1372     // have minimum grouping since toPattern doesn't support it.
   1373     DigitGrouping grouping(fEffGrouping);
   1374     grouping.fMinGrouping = 0;
   1375 
   1376     // Only for fixed digits, these are the digits that get 0's.
   1377     DigitInterval minInterval;
   1378 
   1379     // Only for fixed digits, these are the digits that get #'s.
   1380     DigitInterval maxInterval;
   1381 
   1382     // Only for significant digits
   1383     int32_t sigMin;
   1384     int32_t sigMax;
   1385 
   1386     // These are all the digits to be displayed. For significant digits,
   1387     // this interval always starts at the 1's place an extends left.
   1388     DigitInterval fullInterval;
   1389 
   1390     // Digit range of rounding increment. If rounding increment is .025.
   1391     // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
   1392     int32_t roundingIncrementLowerExp = 0;
   1393     int32_t roundingIncrementUpperExp = 0;
   1394 
   1395     if (fUseSigDigits) {
   1396         SignificantDigitInterval sigInterval;
   1397         extractSigDigits(sigInterval);
   1398         sigMax = sigInterval.getMax();
   1399         sigMin = sigInterval.getMin();
   1400         fullInterval.setFracDigitCount(0);
   1401         fullInterval.setIntDigitCount(sigMax);
   1402     } else {
   1403         extractMinMaxDigits(minInterval, maxInterval);
   1404         if (fUseScientific) {
   1405            if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) {
   1406                maxInterval.setIntDigitCount(1);
   1407                minInterval.shrinkToFitWithin(maxInterval);
   1408            }
   1409         } else if (hasPadding) {
   1410             // Make max int digits match min int digits for now, we
   1411             // compute necessary padding later.
   1412             maxInterval.setIntDigitCount(minInterval.getIntDigitCount());
   1413         } else {
   1414             // For some reason toPattern adds at least one leading '#'
   1415             maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1);
   1416         }
   1417         if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) {
   1418             roundingIncrementLowerExp =
   1419                     fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent();
   1420             roundingIncrementUpperExp =
   1421                     fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent();
   1422             // We have to include the rounding increment in what we display
   1423             maxInterval.expandToContainDigit(roundingIncrementLowerExp);
   1424             maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1);
   1425         }
   1426         fullInterval = maxInterval;
   1427     }
   1428     // We have to include enough digits to show grouping strategy
   1429     int32_t minLengthToDescribeGrouping =
   1430            getMinimumLengthToDescribeGrouping(grouping);
   1431     if (minLengthToDescribeGrouping > 0) {
   1432         fullInterval.expandToContainDigit(
   1433                 getMinimumLengthToDescribeGrouping(grouping) - 1);
   1434     }
   1435 
   1436     // If we have a minimum length, we have to add digits to the left to
   1437     // depict padding.
   1438     if (hasPadding) {
   1439         // For non scientific notation,
   1440         //  minimumLengthForMantissa = minimumLength
   1441         int32_t minimumLengthForMantissa =
   1442                 minimumLength - computeExponentPatternLength();
   1443         int32_t mininumLengthForMantissaIntPart =
   1444                 minimumLengthForMantissa
   1445                 - countFractionDigitAndDecimalPatternLength(
   1446                         fullInterval.getFracDigitCount());
   1447         // Because of grouping, we may need fewer than expected digits to
   1448         // achieve the length we need.
   1449         int32_t digitsNeeded;
   1450         if (getLeftDigitsForLeftLength(
   1451                 grouping,
   1452                 mininumLengthForMantissaIntPart,
   1453                 fullInterval.getIntDigitCount(),
   1454                 digitsNeeded)) {
   1455 
   1456             // In this case, we achieved the exact length that we want.
   1457             fullInterval.setIntDigitCount(digitsNeeded);
   1458         } else if (digitsNeeded > fullInterval.getIntDigitCount()) {
   1459 
   1460             // Having digitsNeeded digits goes over desired length which
   1461             // means that to have desired length would mean starting on a
   1462             // grouping sepearator e.g ,###,### so add a '#' and use one
   1463             // less digit. This trick gives ####,### but that is the best
   1464             // we can do.
   1465             result.append(kPatternDigit);
   1466             fullInterval.setIntDigitCount(digitsNeeded - 1);
   1467         }
   1468     }
   1469     int32_t maxDigitPos = fullInterval.getMostSignificantExclusive();
   1470     int32_t minDigitPos = fullInterval.getLeastSignificantInclusive();
   1471     for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) {
   1472         if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) {
   1473             result.append(kPatternDecimalSeparator);
   1474         }
   1475         if (fUseSigDigits) {
   1476             // Use digit symbol
   1477             if (i >= sigMax || i < sigMax - sigMin) {
   1478                 result.append(kPatternDigit);
   1479             } else {
   1480                 result.append(kPatternSignificantDigit);
   1481             }
   1482         } else {
   1483             if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) {
   1484                 result.append(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit);
   1485             } else if (minInterval.contains(i)) {
   1486                 result.append(kPatternZeroDigit);
   1487             } else {
   1488                 result.append(kPatternDigit);
   1489             }
   1490         }
   1491         if (grouping.isSeparatorAt(i + 1, i)) {
   1492             result.append(kPatternGroupingSeparator);
   1493         }
   1494         if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) {
   1495             result.append(kPatternDecimalSeparator);
   1496         }
   1497     }
   1498     if (fUseScientific) {
   1499         result.append(kPatternExponent);
   1500         if (fOptions.fExponent.fAlwaysShowSign) {
   1501             result.append(kPatternPlus);
   1502         }
   1503         for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) {
   1504             result.append(kPatternZeroDigit);
   1505         }
   1506     }
   1507     return result;
   1508 }
   1509 
   1510 UnicodeString&
   1511 DecimalFormatImpl::toPattern(UnicodeString& result) const {
   1512     result.remove();
   1513     UnicodeString padSpec;
   1514     if (fAffixes.fWidth > 0) {
   1515         padSpec.append(kPatternPadEscape);
   1516         padSpec.append(fAffixes.fPadChar);
   1517     }
   1518     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
   1519         result.append(padSpec);
   1520     }
   1521     fPositivePrefixPattern.toUserString(result);
   1522     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
   1523         result.append(padSpec);
   1524     }
   1525     toNumberPattern(
   1526             fAffixes.fWidth > 0,
   1527             fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(),
   1528             result);
   1529     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
   1530         result.append(padSpec);
   1531     }
   1532     fPositiveSuffixPattern.toUserString(result);
   1533     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
   1534         result.append(padSpec);
   1535     }
   1536     AffixPattern withNegative;
   1537     withNegative.add(AffixPattern::kNegative);
   1538     withNegative.append(fPositivePrefixPattern);
   1539     if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) ||
   1540             !withNegative.equals(fNegativePrefixPattern)) {
   1541         result.append(kPatternSeparator);
   1542         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
   1543             result.append(padSpec);
   1544         }
   1545         fNegativePrefixPattern.toUserString(result);
   1546         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
   1547             result.append(padSpec);
   1548         }
   1549         toNumberPattern(
   1550                 fAffixes.fWidth > 0,
   1551                 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(),
   1552                 result);
   1553         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
   1554             result.append(padSpec);
   1555         }
   1556         fNegativeSuffixPattern.toUserString(result);
   1557         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
   1558             result.append(padSpec);
   1559         }
   1560     }
   1561     return result;
   1562 }
   1563 
   1564 int32_t
   1565 DecimalFormatImpl::getOldFormatWidth() const {
   1566     if (fAffixes.fWidth == 0) {
   1567         return 0;
   1568     }
   1569     return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
   1570 }
   1571 
   1572 const UnicodeString &
   1573 DecimalFormatImpl::getConstSymbol(
   1574         DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
   1575    return fSymbols->getConstSymbol(symbol);
   1576 }
   1577 
   1578 UBool
   1579 DecimalFormatImpl::isParseFastpath() const {
   1580     AffixPattern negative;
   1581     negative.add(AffixPattern::kNegative);
   1582 
   1583     return fAffixes.fWidth == 0 &&
   1584     fPositivePrefixPattern.countChar32() == 0 &&
   1585     fNegativePrefixPattern.equals(negative) &&
   1586     fPositiveSuffixPattern.countChar32() == 0 &&
   1587     fNegativeSuffixPattern.countChar32() == 0;
   1588 }
   1589 
   1590 
   1591 U_NAMESPACE_END
   1592 
   1593 #endif /* #if !UCONFIG_NO_FORMATTING */
   1594 
   1595