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