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