1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 * Copyright (C) 2015, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 * file name: decimfmtimpl.cpp
10 #include "unicode/utypes.h"
12 #if !UCONFIG_NO_FORMATTING
15 #include "unicode/numfmt.h"
16 #include "unicode/plurrule.h"
17 #include "unicode/ustring.h"
18 #include "decimalformatpattern.h"
19 #include "decimalformatpatternimpl.h"
20 #include "decimfmtimpl.h"
22 #include "plurrule_impl.h"
23 #include "valueformatter.h"
24 #include "visibledigits.h"
28 static const int32_t kMaxScientificIntegerDigits
= 8;
30 static const int32_t kFormattingPosPrefix
= (1 << 0);
31 static const int32_t kFormattingNegPrefix
= (1 << 1);
32 static const int32_t kFormattingPosSuffix
= (1 << 2);
33 static const int32_t kFormattingNegSuffix
= (1 << 3);
34 static const int32_t kFormattingSymbols
= (1 << 4);
35 static const int32_t kFormattingCurrency
= (1 << 5);
36 static const int32_t kFormattingUsesCurrency
= (1 << 6);
37 static const int32_t kFormattingPluralRules
= (1 << 7);
38 static const int32_t kFormattingAffixParser
= (1 << 8);
39 static const int32_t kFormattingCurrencyAffixInfo
= (1 << 9);
40 static const int32_t kFormattingAll
= (1 << 10) - 1;
41 static const int32_t kFormattingAffixes
=
42 kFormattingPosPrefix
| kFormattingPosSuffix
|
43 kFormattingNegPrefix
| kFormattingNegSuffix
;
44 static const int32_t kFormattingAffixParserWithCurrency
=
45 kFormattingAffixParser
| kFormattingCurrencyAffixInfo
;
47 DecimalFormatImpl::DecimalFormatImpl(
50 const UnicodeString
&pattern
,
54 fRoundingMode(DecimalFormat::kRoundHalfEven
),
56 fCurrencyUsage(UCURR_USAGE_STANDARD
),
59 if (U_FAILURE(status
)) {
62 fSymbols
= new DecimalFormatSymbols(
64 if (fSymbols
== NULL
) {
65 status
= U_MEMORY_ALLOCATION_ERROR
;
68 UParseError parseError
;
69 applyPattern(pattern
, FALSE
, parseError
, status
);
73 DecimalFormatImpl::DecimalFormatImpl(
75 const UnicodeString
&pattern
,
76 DecimalFormatSymbols
*symbolsToAdopt
,
77 UParseError
&parseError
,
81 fRoundingMode(DecimalFormat::kRoundHalfEven
),
82 fSymbols(symbolsToAdopt
),
83 fCurrencyUsage(UCURR_USAGE_STANDARD
),
86 applyPattern(pattern
, FALSE
, parseError
, status
);
90 DecimalFormatImpl::DecimalFormatImpl(
91 NumberFormat
*super
, const DecimalFormatImpl
&other
, UErrorCode
&status
) :
93 fMultiplier(other
.fMultiplier
),
95 fRoundingMode(other
.fRoundingMode
),
96 fMinSigDigits(other
.fMinSigDigits
),
97 fMaxSigDigits(other
.fMaxSigDigits
),
98 fUseScientific(other
.fUseScientific
),
99 fUseSigDigits(other
.fUseSigDigits
),
100 fGrouping(other
.fGrouping
),
101 fPositivePrefixPattern(other
.fPositivePrefixPattern
),
102 fNegativePrefixPattern(other
.fNegativePrefixPattern
),
103 fPositiveSuffixPattern(other
.fPositiveSuffixPattern
),
104 fNegativeSuffixPattern(other
.fNegativeSuffixPattern
),
105 fSymbols(other
.fSymbols
),
106 fCurrencyUsage(other
.fCurrencyUsage
),
108 fMonetary(other
.fMonetary
),
109 fAffixParser(other
.fAffixParser
),
110 fCurrencyAffixInfo(other
.fCurrencyAffixInfo
),
111 fEffPrecision(other
.fEffPrecision
),
112 fEffGrouping(other
.fEffGrouping
),
113 fOptions(other
.fOptions
),
114 fFormatter(other
.fFormatter
),
115 fAffixes(other
.fAffixes
),
116 fFormatFullPrecision(other
.fFormatFullPrecision
) {
117 fSymbols
= new DecimalFormatSymbols(*fSymbols
);
118 if (fSymbols
== NULL
&& U_SUCCESS(status
)) {
119 status
= U_MEMORY_ALLOCATION_ERROR
;
121 if (other
.fRules
!= NULL
) {
122 fRules
= new PluralRules(*other
.fRules
);
123 if (fRules
== NULL
&& U_SUCCESS(status
)) {
124 status
= U_MEMORY_ALLOCATION_ERROR
;
131 DecimalFormatImpl::assign(const DecimalFormatImpl
&other
, UErrorCode
&status
) {
132 if (U_FAILURE(status
) || this == &other
) {
135 UObject::operator=(other
);
136 fMultiplier
= other
.fMultiplier
;
137 fScale
= other
.fScale
;
138 fRoundingMode
= other
.fRoundingMode
;
139 fMinSigDigits
= other
.fMinSigDigits
;
140 fMaxSigDigits
= other
.fMaxSigDigits
;
141 fUseScientific
= other
.fUseScientific
;
142 fUseSigDigits
= other
.fUseSigDigits
;
143 fGrouping
= other
.fGrouping
;
144 fPositivePrefixPattern
= other
.fPositivePrefixPattern
;
145 fNegativePrefixPattern
= other
.fNegativePrefixPattern
;
146 fPositiveSuffixPattern
= other
.fPositiveSuffixPattern
;
147 fNegativeSuffixPattern
= other
.fNegativeSuffixPattern
;
148 fCurrencyUsage
= other
.fCurrencyUsage
;
149 fMonetary
= other
.fMonetary
;
150 fAffixParser
= other
.fAffixParser
;
151 fCurrencyAffixInfo
= other
.fCurrencyAffixInfo
;
152 fEffPrecision
= other
.fEffPrecision
;
153 fEffGrouping
= other
.fEffGrouping
;
154 fOptions
= other
.fOptions
;
155 fFormatter
= other
.fFormatter
;
156 fAffixes
= other
.fAffixes
;
157 fFormatFullPrecision
= other
.fFormatFullPrecision
;
158 *fSymbols
= *other
.fSymbols
;
159 if (fRules
!= NULL
&& other
.fRules
!= NULL
) {
160 *fRules
= *other
.fRules
;
163 fRules
= other
.fRules
;
164 if (fRules
!= NULL
) {
165 fRules
= new PluralRules(*fRules
);
166 if (fRules
== NULL
) {
167 status
= U_MEMORY_ALLOCATION_ERROR
;
176 DecimalFormatImpl::operator==(const DecimalFormatImpl
&other
) const {
177 if (this == &other
) {
180 return (fMultiplier
== other
.fMultiplier
)
181 && (fScale
== other
.fScale
)
182 && (fRoundingMode
== other
.fRoundingMode
)
183 && (fMinSigDigits
== other
.fMinSigDigits
)
184 && (fMaxSigDigits
== other
.fMaxSigDigits
)
185 && (fUseScientific
== other
.fUseScientific
)
186 && (fUseSigDigits
== other
.fUseSigDigits
)
187 && fGrouping
.equals(other
.fGrouping
)
188 && fPositivePrefixPattern
.equals(other
.fPositivePrefixPattern
)
189 && fNegativePrefixPattern
.equals(other
.fNegativePrefixPattern
)
190 && fPositiveSuffixPattern
.equals(other
.fPositiveSuffixPattern
)
191 && fNegativeSuffixPattern
.equals(other
.fNegativeSuffixPattern
)
192 && fCurrencyUsage
== other
.fCurrencyUsage
193 && fAffixParser
.equals(other
.fAffixParser
)
194 && fCurrencyAffixInfo
.equals(other
.fCurrencyAffixInfo
)
195 && fEffPrecision
.equals(other
.fEffPrecision
)
196 && fEffGrouping
.equals(other
.fEffGrouping
)
197 && fOptions
.equals(other
.fOptions
)
198 && fFormatter
.equals(other
.fFormatter
)
199 && fAffixes
.equals(other
.fAffixes
)
200 && (*fSymbols
== *other
.fSymbols
)
201 && ((fRules
== other
.fRules
) || (
202 (fRules
!= NULL
) && (other
.fRules
!= NULL
)
203 && (*fRules
== *other
.fRules
)))
204 && (fMonetary
== other
.fMonetary
)
205 && (fFormatFullPrecision
== other
.fFormatFullPrecision
);
208 DecimalFormatImpl::~DecimalFormatImpl() {
214 DecimalFormatImpl::prepareValueFormatter(ValueFormatter
&vf
) const {
215 if (fUseScientific
) {
216 vf
.prepareScientificFormatting(
217 fFormatter
, fEffPrecision
, fOptions
);
220 vf
.prepareFixedDecimalFormatting(
221 fFormatter
, fEffGrouping
, fEffPrecision
.fMantissa
, fOptions
.fMantissa
);
226 DecimalFormatImpl::getPatternScale() const {
227 UBool usesPercent
= fPositivePrefixPattern
.usesPercent() ||
228 fPositiveSuffixPattern
.usesPercent() ||
229 fNegativePrefixPattern
.usesPercent() ||
230 fNegativeSuffixPattern
.usesPercent();
234 UBool usesPermill
= fPositivePrefixPattern
.usesPermill() ||
235 fPositiveSuffixPattern
.usesPermill() ||
236 fNegativePrefixPattern
.usesPermill() ||
237 fNegativeSuffixPattern
.usesPermill();
245 DecimalFormatImpl::setMultiplierScale(int32_t scale
) {
247 // Needed to preserve equality. fMultiplier == 0 means
249 fMultiplier
.set((int32_t)0);
251 fMultiplier
.set((int32_t)1);
252 fMultiplier
.shiftDecimalRight(scale
);
257 DecimalFormatImpl::format(
259 UnicodeString
&appendTo
,
261 UErrorCode
&status
) const {
262 FieldPositionOnlyHandler
handler(pos
);
263 return formatInt32(number
, appendTo
, handler
, status
);
267 DecimalFormatImpl::format(
269 UnicodeString
&appendTo
,
270 FieldPositionIterator
*posIter
,
271 UErrorCode
&status
) const {
272 FieldPositionIteratorHandler
handler(posIter
, status
);
273 return formatInt32(number
, appendTo
, handler
, status
);
277 UBool
DecimalFormatImpl::maybeFormatWithDigitList(
279 UnicodeString
&appendTo
,
280 FieldPositionHandler
&handler
,
281 UErrorCode
&status
) const {
282 if (!fMultiplier
.isZero()) {
285 digits
.mult(fMultiplier
, status
);
286 digits
.shiftDecimalRight(fScale
);
287 formatAdjustedDigitList(digits
, appendTo
, handler
, status
);
293 digits
.shiftDecimalRight(fScale
);
294 formatAdjustedDigitList(digits
, appendTo
, handler
, status
);
301 UBool
DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
303 VisibleDigitsWithExponent
&visibleDigits
,
304 UErrorCode
&status
) const {
306 // for <rdar://problem/39240173>, don't need to do the following
307 // below since we don't take those paths; should we anyway?
308 // digits.fFormatFullPrecision = fFormatFullPrecision;
309 if (!fMultiplier
.isZero()) {
312 digits
.mult(fMultiplier
, status
);
313 digits
.shiftDecimalRight(fScale
);
314 initVisibleDigitsFromAdjusted(digits
, visibleDigits
, status
);
320 digits
.shiftDecimalRight(fScale
);
321 initVisibleDigitsFromAdjusted(digits
, visibleDigits
, status
);
328 DecimalFormatImpl::formatInt32(
330 UnicodeString
&appendTo
,
331 FieldPositionHandler
&handler
,
332 UErrorCode
&status
) const {
333 if (maybeFormatWithDigitList(number
, appendTo
, handler
, status
)) {
337 return fAffixes
.formatInt32(
339 prepareValueFormatter(vf
),
347 DecimalFormatImpl::formatInt64(
349 UnicodeString
&appendTo
,
350 FieldPositionHandler
&handler
,
351 UErrorCode
&status
) const {
352 if (number
>= INT32_MIN
&& number
<= INT32_MAX
) {
353 return formatInt32((int32_t) number
, appendTo
, handler
, status
);
355 VisibleDigitsWithExponent digits
;
356 initVisibleDigitsWithExponent(number
, digits
, status
);
357 return formatVisibleDigitsWithExponent(
358 digits
, appendTo
, handler
, status
);
362 DecimalFormatImpl::formatDouble(
364 UnicodeString
&appendTo
,
365 FieldPositionHandler
&handler
,
366 UErrorCode
&status
) const {
367 VisibleDigitsWithExponent digits
;
368 initVisibleDigitsWithExponent(number
, digits
, status
);
369 return formatVisibleDigitsWithExponent(
370 digits
, appendTo
, handler
, status
);
374 DecimalFormatImpl::format(
376 UnicodeString
&appendTo
,
378 UErrorCode
&status
) const {
379 FieldPositionOnlyHandler
handler(pos
);
380 return formatDouble(number
, appendTo
, handler
, status
);
384 DecimalFormatImpl::format(
385 const DigitList
&number
,
386 UnicodeString
&appendTo
,
388 UErrorCode
&status
) const {
389 DigitList
dl(number
);
390 FieldPositionOnlyHandler
handler(pos
);
391 return formatDigitList(dl
, appendTo
, handler
, status
);
395 DecimalFormatImpl::format(
397 UnicodeString
&appendTo
,
399 UErrorCode
&status
) const {
400 FieldPositionOnlyHandler
handler(pos
);
401 return formatInt64(number
, appendTo
, handler
, status
);
405 DecimalFormatImpl::format(
407 UnicodeString
&appendTo
,
408 FieldPositionIterator
*posIter
,
409 UErrorCode
&status
) const {
410 FieldPositionIteratorHandler
handler(posIter
, status
);
411 return formatInt64(number
, appendTo
, handler
, status
);
415 DecimalFormatImpl::format(
417 UnicodeString
&appendTo
,
418 FieldPositionIterator
*posIter
,
419 UErrorCode
&status
) const {
420 FieldPositionIteratorHandler
handler(posIter
, status
);
421 return formatDouble(number
, appendTo
, handler
, status
);
425 DecimalFormatImpl::format(
426 const DigitList
&number
,
427 UnicodeString
&appendTo
,
428 FieldPositionIterator
*posIter
,
429 UErrorCode
&status
) const {
430 DigitList
dl(number
);
431 FieldPositionIteratorHandler
handler(posIter
, status
);
432 return formatDigitList(dl
, appendTo
, handler
, status
);
436 DecimalFormatImpl::format(
438 UnicodeString
&appendTo
,
439 FieldPositionIterator
*posIter
,
440 UErrorCode
&status
) const {
442 dl
.set(number
, status
);
443 FieldPositionIteratorHandler
handler(posIter
, status
);
444 return formatDigitList(dl
, appendTo
, handler
, status
);
448 DecimalFormatImpl::format(
449 const VisibleDigitsWithExponent
&digits
,
450 UnicodeString
&appendTo
,
452 UErrorCode
&status
) const {
453 FieldPositionOnlyHandler
handler(pos
);
454 return formatVisibleDigitsWithExponent(
455 digits
, appendTo
, handler
, status
);
459 DecimalFormatImpl::format(
460 const VisibleDigitsWithExponent
&digits
,
461 UnicodeString
&appendTo
,
462 FieldPositionIterator
*posIter
,
463 UErrorCode
&status
) const {
464 FieldPositionIteratorHandler
handler(posIter
, status
);
465 return formatVisibleDigitsWithExponent(
466 digits
, appendTo
, handler
, status
);
470 DecimalFormatImpl::adjustDigitList(
471 DigitList
&number
, UErrorCode
&status
) const {
472 number
.setRoundingMode(fRoundingMode
);
473 if (!fMultiplier
.isZero()) {
474 number
.mult(fMultiplier
, status
);
477 number
.shiftDecimalRight(fScale
);
484 DecimalFormatImpl::formatDigitList(
486 UnicodeString
&appendTo
,
487 FieldPositionHandler
&handler
,
488 UErrorCode
&status
) const {
489 VisibleDigitsWithExponent digits
;
490 initVisibleDigitsWithExponent(number
, digits
, status
);
491 return formatVisibleDigitsWithExponent(
492 digits
, appendTo
, handler
, status
);
496 DecimalFormatImpl::formatAdjustedDigitList(
498 UnicodeString
&appendTo
,
499 FieldPositionHandler
&handler
,
500 UErrorCode
&status
) const {
502 return fAffixes
.format(
504 prepareValueFormatter(vf
),
512 DecimalFormatImpl::formatVisibleDigitsWithExponent(
513 const VisibleDigitsWithExponent
&digits
,
514 UnicodeString
&appendTo
,
515 FieldPositionHandler
&handler
,
516 UErrorCode
&status
) const {
518 return fAffixes
.format(
520 prepareValueFormatter(vf
),
527 static FixedDecimal
&initFixedDecimal(
528 const VisibleDigits
&digits
, FixedDecimal
&result
) {
530 result
.isNegative
= digits
.isNegative();
531 result
._isNaN
= digits
.isNaN();
532 result
._isInfinite
= digits
.isInfinite();
533 digits
.getFixedDecimal(
534 result
.source
, result
.intValue
, result
.decimalDigits
,
535 result
.decimalDigitsWithoutTrailingZeros
,
536 result
.visibleDecimalDigitCount
, result
._hasIntegerValue
);
541 DecimalFormatImpl::getFixedDecimal(double number
, FixedDecimal
&result
, UErrorCode
&status
) const {
542 if (U_FAILURE(status
)) {
545 VisibleDigits digits
;
546 fEffPrecision
.fMantissa
.initVisibleDigits(number
, digits
, status
);
547 return initFixedDecimal(digits
, result
);
551 DecimalFormatImpl::getFixedDecimal(
552 DigitList
&number
, FixedDecimal
&result
, UErrorCode
&status
) const {
553 if (U_FAILURE(status
)) {
556 VisibleDigits digits
;
557 fEffPrecision
.fMantissa
.initVisibleDigits(number
, digits
, status
);
558 return initFixedDecimal(digits
, result
);
561 VisibleDigitsWithExponent
&
562 DecimalFormatImpl::initVisibleDigitsWithExponent(
564 VisibleDigitsWithExponent
&digits
,
565 UErrorCode
&status
) const {
566 if (maybeInitVisibleDigitsFromDigitList(
567 number
, digits
, status
)) {
570 if (fUseScientific
) {
571 fEffPrecision
.initVisibleDigitsWithExponent(
572 number
, digits
, status
);
574 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
575 number
, digits
, status
);
580 VisibleDigitsWithExponent
&
581 DecimalFormatImpl::initVisibleDigitsWithExponent(
583 VisibleDigitsWithExponent
&digits
,
584 UErrorCode
&status
) const {
585 if (maybeInitVisibleDigitsFromDigitList(
586 number
, digits
, status
)) {
589 if (fUseScientific
) {
590 fEffPrecision
.initVisibleDigitsWithExponent(
591 number
, digits
, status
);
593 digits
.setFormatFullPrecision(fFormatFullPrecision
); // Apple
594 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
595 number
, digits
, status
);
600 VisibleDigitsWithExponent
&
601 DecimalFormatImpl::initVisibleDigitsWithExponent(
603 VisibleDigitsWithExponent
&digits
,
604 UErrorCode
&status
) const {
605 adjustDigitList(number
, status
);
606 return initVisibleDigitsFromAdjusted(number
, digits
, status
);
609 VisibleDigitsWithExponent
&
610 DecimalFormatImpl::initVisibleDigitsFromAdjusted(
612 VisibleDigitsWithExponent
&digits
,
613 UErrorCode
&status
) const {
614 if (fUseScientific
) {
615 fEffPrecision
.initVisibleDigitsWithExponent(
616 number
, digits
, status
);
618 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
619 number
, digits
, status
);
625 DecimalFormatImpl::round(
626 DigitList
&number
, UErrorCode
&status
) const {
627 if (number
.isNaN() || number
.isInfinite()) {
630 adjustDigitList(number
, status
);
632 prepareValueFormatter(vf
);
633 return vf
.round(number
, status
);
637 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue
) {
638 fMinSigDigits
= newValue
;
639 fUseSigDigits
= TRUE
; // ticket 9936
644 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue
) {
645 fMaxSigDigits
= newValue
;
646 fUseSigDigits
= TRUE
; // ticket 9936
651 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min
, int32_t max
) {
654 fUseSigDigits
= TRUE
; // ticket 9936
659 DecimalFormatImpl::setScientificNotation(UBool newValue
) {
660 fUseScientific
= newValue
;
665 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue
) {
666 fUseSigDigits
= newValue
;
671 DecimalFormatImpl::setGroupingSize(int32_t newValue
) {
672 fGrouping
.fGrouping
= newValue
;
677 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue
) {
678 fGrouping
.fGrouping2
= newValue
;
683 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue
) {
684 fGrouping
.fMinGrouping
= newValue
;
689 DecimalFormatImpl::setCurrencyUsage(
690 UCurrencyUsage currencyUsage
, UErrorCode
&status
) {
691 fCurrencyUsage
= currencyUsage
;
692 updateFormatting(kFormattingCurrency
, status
);
696 DecimalFormatImpl::setRoundingIncrement(double d
) {
698 fEffPrecision
.fMantissa
.fRoundingIncrement
.set(d
);
700 fEffPrecision
.fMantissa
.fRoundingIncrement
.set(0.0);
705 DecimalFormatImpl::getRoundingIncrement() const {
706 return fEffPrecision
.fMantissa
.fRoundingIncrement
.getDouble();
710 DecimalFormatImpl::getMultiplier() const {
711 if (fMultiplier
.isZero()) {
714 return (int32_t) fMultiplier
.getDouble();
718 DecimalFormatImpl::setMultiplier(int32_t m
) {
719 if (m
== 0 || m
== 1) {
720 fMultiplier
.set((int32_t)0);
727 DecimalFormatImpl::setPositivePrefix(const UnicodeString
&str
) {
728 fPositivePrefixPattern
.remove();
729 fPositivePrefixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
730 UErrorCode status
= U_ZERO_ERROR
;
731 updateFormatting(kFormattingPosPrefix
, status
);
735 DecimalFormatImpl::setPositiveSuffix(const UnicodeString
&str
) {
736 fPositiveSuffixPattern
.remove();
737 fPositiveSuffixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
738 UErrorCode status
= U_ZERO_ERROR
;
739 updateFormatting(kFormattingPosSuffix
, status
);
743 DecimalFormatImpl::setNegativePrefix(const UnicodeString
&str
) {
744 fNegativePrefixPattern
.remove();
745 fNegativePrefixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
746 UErrorCode status
= U_ZERO_ERROR
;
747 updateFormatting(kFormattingNegPrefix
, status
);
751 DecimalFormatImpl::setNegativeSuffix(const UnicodeString
&str
) {
752 fNegativeSuffixPattern
.remove();
753 fNegativeSuffixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
754 UErrorCode status
= U_ZERO_ERROR
;
755 updateFormatting(kFormattingNegSuffix
, status
);
759 DecimalFormatImpl::getPositivePrefix(UnicodeString
&result
) const {
760 result
= fAffixes
.fPositivePrefix
.getOtherVariant().toString();
765 DecimalFormatImpl::getPositiveSuffix(UnicodeString
&result
) const {
766 result
= fAffixes
.fPositiveSuffix
.getOtherVariant().toString();
771 DecimalFormatImpl::getNegativePrefix(UnicodeString
&result
) const {
772 result
= fAffixes
.fNegativePrefix
.getOtherVariant().toString();
777 DecimalFormatImpl::getNegativeSuffix(UnicodeString
&result
) const {
778 result
= fAffixes
.fNegativeSuffix
.getOtherVariant().toString();
783 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols
*symbolsToAdopt
) {
784 if (symbolsToAdopt
== NULL
) {
788 fSymbols
= symbolsToAdopt
;
789 UErrorCode status
= U_ZERO_ERROR
;
790 updateFormatting(kFormattingSymbols
, status
);
794 DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
795 const UnicodeString
&pattern
, UErrorCode
&status
) {
797 applyPattern(pattern
, FALSE
, perror
, status
);
798 updateForApplyPatternFavorCurrencyPrecision(status
);
802 DecimalFormatImpl::applyPattern(
803 const UnicodeString
&pattern
, UErrorCode
&status
) {
805 applyPattern(pattern
, FALSE
, perror
, status
);
806 updateForApplyPattern(status
);
810 DecimalFormatImpl::applyPattern(
811 const UnicodeString
&pattern
,
812 UParseError
&perror
, UErrorCode
&status
) {
813 applyPattern(pattern
, FALSE
, perror
, status
);
814 updateForApplyPattern(status
);
818 DecimalFormatImpl::applyLocalizedPattern(
819 const UnicodeString
&pattern
, UErrorCode
&status
) {
821 applyPattern(pattern
, TRUE
, perror
, status
);
822 updateForApplyPattern(status
);
826 DecimalFormatImpl::applyLocalizedPattern(
827 const UnicodeString
&pattern
,
828 UParseError
&perror
, UErrorCode
&status
) {
829 applyPattern(pattern
, TRUE
, perror
, status
);
830 updateForApplyPattern(status
);
834 DecimalFormatImpl::applyPattern(
835 const UnicodeString
&pattern
,
836 UBool localized
, UParseError
&perror
, UErrorCode
&status
) {
837 if (U_FAILURE(status
)) {
840 DecimalFormatPatternParser patternParser
;
842 patternParser
.useSymbols(*fSymbols
);
844 DecimalFormatPattern out
;
845 patternParser
.applyPatternWithoutExpandAffix(
846 pattern
, out
, perror
, status
);
847 if (U_FAILURE(status
)) {
850 fUseScientific
= out
.fUseExponentialNotation
;
851 fUseSigDigits
= out
.fUseSignificantDigits
;
852 fSuper
->NumberFormat::setMinimumIntegerDigits(out
.fMinimumIntegerDigits
);
853 fSuper
->NumberFormat::setMaximumIntegerDigits(out
.fMaximumIntegerDigits
);
854 fSuper
->NumberFormat::setMinimumFractionDigits(out
.fMinimumFractionDigits
);
855 fSuper
->NumberFormat::setMaximumFractionDigits(out
.fMaximumFractionDigits
);
856 fMinSigDigits
= out
.fMinimumSignificantDigits
;
857 fMaxSigDigits
= out
.fMaximumSignificantDigits
;
858 fEffPrecision
.fMinExponentDigits
= out
.fMinExponentDigits
;
859 fOptions
.fExponent
.fAlwaysShowSign
= out
.fExponentSignAlwaysShown
;
860 fSuper
->NumberFormat::setGroupingUsed(out
.fGroupingUsed
);
861 fGrouping
.fGrouping
= out
.fGroupingSize
;
862 fGrouping
.fGrouping2
= out
.fGroupingSize2
;
863 fOptions
.fMantissa
.fAlwaysShowDecimal
= out
.fDecimalSeparatorAlwaysShown
;
864 if (out
.fRoundingIncrementUsed
) {
865 fEffPrecision
.fMantissa
.fRoundingIncrement
= out
.fRoundingIncrement
;
867 fEffPrecision
.fMantissa
.fRoundingIncrement
.clear();
869 fAffixes
.fPadChar
= out
.fPad
;
870 fNegativePrefixPattern
= out
.fNegPrefixAffix
;
871 fNegativeSuffixPattern
= out
.fNegSuffixAffix
;
872 fPositivePrefixPattern
= out
.fPosPrefixAffix
;
873 fPositiveSuffixPattern
= out
.fPosSuffixAffix
;
875 // Work around. Pattern parsing code and DecimalFormat code don't agree
876 // on the definition of field width, so we have to translate from
877 // pattern field width to decimal format field width here.
878 fAffixes
.fWidth
= out
.fFormatWidth
== 0 ? 0 :
879 out
.fFormatWidth
+ fPositivePrefixPattern
.countChar32()
880 + fPositiveSuffixPattern
.countChar32();
881 switch (out
.fPadPosition
) {
882 case DecimalFormatPattern::kPadBeforePrefix
:
883 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadBeforePrefix
;
885 case DecimalFormatPattern::kPadAfterPrefix
:
886 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadAfterPrefix
;
888 case DecimalFormatPattern::kPadBeforeSuffix
:
889 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadBeforeSuffix
;
891 case DecimalFormatPattern::kPadAfterSuffix
:
892 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadAfterSuffix
;
900 DecimalFormatImpl::updatePrecision() {
901 if (fUseScientific
) {
902 updatePrecisionForScientific();
904 updatePrecisionForFixed();
908 static void updatePrecisionForScientificMinMax(
909 const DigitInterval
&min
,
910 const DigitInterval
&max
,
911 DigitInterval
&resultMin
,
912 DigitInterval
&resultMax
,
913 SignificantDigitInterval
&resultSignificant
) {
914 resultMin
.setIntDigitCount(0);
915 resultMin
.setFracDigitCount(0);
916 resultSignificant
.clear();
919 int32_t maxIntDigitCount
= max
.getIntDigitCount();
920 int32_t minIntDigitCount
= min
.getIntDigitCount();
921 int32_t maxFracDigitCount
= max
.getFracDigitCount();
922 int32_t minFracDigitCount
= min
.getFracDigitCount();
925 // Not in spec: maxIntDigitCount > 8 assume
926 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
927 // no provision for unsetting maxIntDigitCount which would be useful for
928 // scientific notation. The best we can do is assume that if
929 // maxIntDigitCount is the default of 2000000000 or is "big enough" then
930 // user did not intend to explicitly set it. The 8 was derived emperically
931 // by extensive testing of legacy code.
932 if (maxIntDigitCount
> 8) {
933 maxIntDigitCount
= minIntDigitCount
;
936 // Per the spec, exponent grouping happens if maxIntDigitCount is more
937 // than 1 and more than minIntDigitCount.
938 UBool bExponentGrouping
= maxIntDigitCount
> 1 && minIntDigitCount
< maxIntDigitCount
;
939 if (bExponentGrouping
) {
940 resultMax
.setIntDigitCount(maxIntDigitCount
);
942 // For exponent grouping minIntDigits is always treated as 1 even
943 // if it wasn't set to 1!
944 resultMin
.setIntDigitCount(1);
946 // Fixed digit count left of decimal. minIntDigitCount doesn't have
947 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
948 // maxIntDigitCount == 1.
949 int32_t fixedIntDigitCount
= maxIntDigitCount
;
951 // If fixedIntDigitCount is 0 but
952 // min or max fraction count is 0 too then use 1. This way we can get
953 // unlimited precision for X.XXXEX
954 if (fixedIntDigitCount
== 0 && (minFracDigitCount
== 0 || maxFracDigitCount
== 0)) {
955 fixedIntDigitCount
= 1;
957 resultMax
.setIntDigitCount(fixedIntDigitCount
);
958 resultMin
.setIntDigitCount(fixedIntDigitCount
);
960 // Spec says this is how we compute significant digits. 0 means
961 // unlimited significant digits.
962 int32_t maxSigDigits
= minIntDigitCount
+ maxFracDigitCount
;
963 if (maxSigDigits
> 0) {
964 int32_t minSigDigits
= minIntDigitCount
+ minFracDigitCount
;
965 resultSignificant
.setMin(minSigDigits
);
966 resultSignificant
.setMax(maxSigDigits
);
971 DecimalFormatImpl::updatePrecisionForScientific() {
972 FixedPrecision
*result
= &fEffPrecision
.fMantissa
;
974 result
->fMax
.setFracDigitCount(-1);
975 result
->fMax
.setIntDigitCount(1);
976 result
->fMin
.setFracDigitCount(0);
977 result
->fMin
.setIntDigitCount(1);
978 result
->fSignificant
.clear();
979 extractSigDigits(result
->fSignificant
);
984 extractMinMaxDigits(min
, max
);
985 updatePrecisionForScientificMinMax(
987 result
->fMin
, result
->fMax
, result
->fSignificant
);
991 DecimalFormatImpl::updatePrecisionForFixed() {
992 FixedPrecision
*result
= &fEffPrecision
.fMantissa
;
993 if (!fUseSigDigits
) {
994 extractMinMaxDigits(result
->fMin
, result
->fMax
);
995 result
->fSignificant
.clear();
997 extractSigDigits(result
->fSignificant
);
998 result
->fMin
.setIntDigitCount(1);
999 result
->fMin
.setFracDigitCount(0);
1000 result
->fMax
.clear();
1005 DecimalFormatImpl::extractMinMaxDigits(
1006 DigitInterval
&min
, DigitInterval
&max
) const {
1007 min
.setIntDigitCount(fSuper
->getMinimumIntegerDigits());
1008 max
.setIntDigitCount(fSuper
->getMaximumIntegerDigits());
1009 min
.setFracDigitCount(fSuper
->getMinimumFractionDigits());
1010 max
.setFracDigitCount(fSuper
->getMaximumFractionDigits());
1014 DecimalFormatImpl::extractSigDigits(
1015 SignificantDigitInterval
&sig
) const {
1016 sig
.setMin(fMinSigDigits
< 0 ? 0 : fMinSigDigits
);
1017 sig
.setMax(fMaxSigDigits
< 0 ? 0 : fMaxSigDigits
);
1021 DecimalFormatImpl::updateGrouping() {
1022 if (fSuper
->isGroupingUsed()) {
1023 fEffGrouping
= fGrouping
;
1025 fEffGrouping
.clear();
1030 DecimalFormatImpl::updateCurrency(UErrorCode
&status
) {
1031 updateFormatting(kFormattingCurrency
, TRUE
, status
);
1035 DecimalFormatImpl::updateFormatting(
1036 int32_t changedFormattingFields
,
1037 UErrorCode
&status
) {
1038 updateFormatting(changedFormattingFields
, TRUE
, status
);
1042 DecimalFormatImpl::updateFormatting(
1043 int32_t changedFormattingFields
,
1044 UBool updatePrecisionBasedOnCurrency
,
1045 UErrorCode
&status
) {
1046 if (U_FAILURE(status
)) {
1049 // Each function updates one field. Order matters. For instance,
1050 // updatePluralRules comes before updateCurrencyAffixInfo because the
1051 // fRules field is needed to update the fCurrencyAffixInfo field.
1052 updateFormattingUsesCurrency(changedFormattingFields
);
1053 updateFormattingFixedPointFormatter(changedFormattingFields
);
1054 updateFormattingAffixParser(changedFormattingFields
);
1055 updateFormattingPluralRules(changedFormattingFields
, status
);
1056 updateFormattingCurrencyAffixInfo(
1057 changedFormattingFields
,
1058 updatePrecisionBasedOnCurrency
,
1060 updateFormattingLocalizedPositivePrefix(
1061 changedFormattingFields
, status
);
1062 updateFormattingLocalizedPositiveSuffix(
1063 changedFormattingFields
, status
);
1064 updateFormattingLocalizedNegativePrefix(
1065 changedFormattingFields
, status
);
1066 updateFormattingLocalizedNegativeSuffix(
1067 changedFormattingFields
, status
);
1071 DecimalFormatImpl::updateFormattingUsesCurrency(
1072 int32_t &changedFormattingFields
) {
1073 if ((changedFormattingFields
& kFormattingAffixes
) == 0) {
1074 // If no affixes changed, don't need to do any work
1077 UBool newUsesCurrency
=
1078 fPositivePrefixPattern
.usesCurrency() ||
1079 fPositiveSuffixPattern
.usesCurrency() ||
1080 fNegativePrefixPattern
.usesCurrency() ||
1081 fNegativeSuffixPattern
.usesCurrency();
1082 if (fMonetary
!= newUsesCurrency
) {
1083 fMonetary
= newUsesCurrency
;
1084 changedFormattingFields
|= kFormattingUsesCurrency
;
1089 DecimalFormatImpl::updateFormattingPluralRules(
1090 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1091 if ((changedFormattingFields
& (kFormattingSymbols
| kFormattingUsesCurrency
)) == 0) {
1092 // No work to do if both fSymbols and fMonetary
1093 // fields are unchanged
1096 if (U_FAILURE(status
)) {
1099 PluralRules
*newRules
= NULL
;
1101 newRules
= PluralRules::forLocale(fSymbols
->getLocale(), status
);
1102 if (U_FAILURE(status
)) {
1106 // Its ok to say a field has changed when it really hasn't but not
1107 // the other way around. Here we assume the field changed unless it
1108 // was NULL before and is still NULL now
1109 if (fRules
!= newRules
) {
1112 changedFormattingFields
|= kFormattingPluralRules
;
1117 DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
1118 int32_t &changedFormattingFields
,
1119 UBool updatePrecisionBasedOnCurrency
,
1120 UErrorCode
&status
) {
1121 if ((changedFormattingFields
& (
1122 kFormattingSymbols
| kFormattingCurrency
|
1123 kFormattingUsesCurrency
| kFormattingPluralRules
)) == 0) {
1124 // If all these fields are unchanged, no work to do.
1127 if (U_FAILURE(status
)) {
1131 if (fCurrencyAffixInfo
.isDefault()) {
1132 // In this case don't have to do any work
1135 fCurrencyAffixInfo
.set(NULL
, NULL
, NULL
, status
);
1136 if (U_FAILURE(status
)) {
1139 changedFormattingFields
|= kFormattingCurrencyAffixInfo
;
1141 const UChar
*currency
= fSuper
->getCurrency();
1142 UChar localeCurr
[4];
1143 if (currency
[0] == 0) {
1144 ucurr_forLocale(fSymbols
->getLocale().getName(), localeCurr
, UPRV_LENGTHOF(localeCurr
), &status
);
1145 if (U_SUCCESS(status
)) {
1146 currency
= localeCurr
;
1147 fSuper
->NumberFormat::setCurrency(currency
, status
);
1150 status
= U_ZERO_ERROR
;
1153 fCurrencyAffixInfo
.set(
1154 fSymbols
->getLocale().getName(), fRules
, currency
, status
);
1155 if (U_FAILURE(status
)) {
1158 UBool customCurrencySymbol
= FALSE
;
1159 // If DecimalFormatSymbols has custom currency symbol, prefer
1160 // that over what we just read from the resource bundles
1161 if (fSymbols
->isCustomCurrencySymbol()) {
1162 fCurrencyAffixInfo
.setSymbol(
1163 fSymbols
->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1164 customCurrencySymbol
= TRUE
;
1166 if (fSymbols
->isCustomIntlCurrencySymbol()) {
1167 fCurrencyAffixInfo
.setISO(
1168 fSymbols
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1169 customCurrencySymbol
= TRUE
;
1171 changedFormattingFields
|= kFormattingCurrencyAffixInfo
;
1172 if (currency
&& !customCurrencySymbol
&& updatePrecisionBasedOnCurrency
) {
1173 FixedPrecision precision
;
1174 CurrencyAffixInfo::adjustPrecision(
1175 currency
, fCurrencyUsage
, precision
, status
);
1176 if (U_FAILURE(status
)) {
1179 fSuper
->NumberFormat::setMinimumFractionDigits(
1180 precision
.fMin
.getFracDigitCount());
1181 fSuper
->NumberFormat::setMaximumFractionDigits(
1182 precision
.fMax
.getFracDigitCount());
1184 fEffPrecision
.fMantissa
.fRoundingIncrement
=
1185 precision
.fRoundingIncrement
;
1192 DecimalFormatImpl::updateFormattingFixedPointFormatter(
1193 int32_t &changedFormattingFields
) {
1194 if ((changedFormattingFields
& (kFormattingSymbols
| kFormattingUsesCurrency
)) == 0) {
1195 // No work to do if fSymbols is unchanged
1199 fFormatter
.setDecimalFormatSymbolsForMonetary(*fSymbols
);
1201 fFormatter
.setDecimalFormatSymbols(*fSymbols
);
1206 DecimalFormatImpl::updateFormattingAffixParser(
1207 int32_t &changedFormattingFields
) {
1208 if ((changedFormattingFields
& kFormattingSymbols
) == 0) {
1209 // No work to do if fSymbols is unchanged
1212 fAffixParser
.setDecimalFormatSymbols(*fSymbols
);
1213 changedFormattingFields
|= kFormattingAffixParser
;
1217 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
1218 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1219 if (U_FAILURE(status
)) {
1222 if ((changedFormattingFields
& (
1223 kFormattingPosPrefix
| kFormattingAffixParserWithCurrency
)) == 0) {
1227 fAffixes
.fPositivePrefix
.remove();
1229 fPositivePrefixPattern
,
1231 fAffixes
.fPositivePrefix
,
1236 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
1237 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1238 if (U_FAILURE(status
)) {
1241 if ((changedFormattingFields
& (
1242 kFormattingPosSuffix
| kFormattingAffixParserWithCurrency
)) == 0) {
1246 fAffixes
.fPositiveSuffix
.remove();
1248 fPositiveSuffixPattern
,
1250 fAffixes
.fPositiveSuffix
,
1255 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
1256 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1257 if (U_FAILURE(status
)) {
1260 if ((changedFormattingFields
& (
1261 kFormattingNegPrefix
| kFormattingAffixParserWithCurrency
)) == 0) {
1265 fAffixes
.fNegativePrefix
.remove();
1267 fNegativePrefixPattern
,
1269 fAffixes
.fNegativePrefix
,
1274 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
1275 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1276 if (U_FAILURE(status
)) {
1279 if ((changedFormattingFields
& (
1280 kFormattingNegSuffix
| kFormattingAffixParserWithCurrency
)) == 0) {
1284 fAffixes
.fNegativeSuffix
.remove();
1286 fNegativeSuffixPattern
,
1288 fAffixes
.fNegativeSuffix
,
1293 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1294 UErrorCode
&status
) {
1295 updateAll(kFormattingAll
& ~kFormattingSymbols
, TRUE
, status
);
1299 DecimalFormatImpl::updateForApplyPattern(UErrorCode
&status
) {
1300 updateAll(kFormattingAll
& ~kFormattingSymbols
, FALSE
, status
);
1304 DecimalFormatImpl::updateAll(UErrorCode
&status
) {
1305 updateAll(kFormattingAll
, TRUE
, status
);
1309 DecimalFormatImpl::updateAll(
1310 int32_t formattingFlags
,
1311 UBool updatePrecisionBasedOnCurrency
,
1312 UErrorCode
&status
) {
1313 if (U_FAILURE(status
)) {
1319 formattingFlags
, updatePrecisionBasedOnCurrency
, status
);
1320 setMultiplierScale(getPatternScale());
1321 fFormatFullPrecision
= FALSE
;
1326 getMinimumLengthToDescribeGrouping(const DigitGrouping
&grouping
) {
1327 if (grouping
.fGrouping
<= 0) {
1330 if (grouping
.fGrouping2
<= 0) {
1331 return grouping
.fGrouping
+ 1;
1333 return grouping
.fGrouping
+ grouping
.fGrouping2
+ 1;
1337 * Given a grouping policy, calculates how many digits are needed left of
1338 * the decimal point to achieve a desired length left of the
1340 * @param grouping the grouping policy
1341 * @param desiredLength number of characters needed left of decimal point
1342 * @param minLeftDigits at least this many digits is returned
1343 * @param leftDigits the number of digits needed stored here
1344 * which is >= minLeftDigits.
1345 * @return true if a perfect fit or false if having leftDigits would exceed
1349 getLeftDigitsForLeftLength(
1350 const DigitGrouping
&grouping
,
1351 int32_t desiredLength
,
1352 int32_t minLeftDigits
,
1353 int32_t &leftDigits
) {
1354 leftDigits
= minLeftDigits
;
1355 int32_t lengthSoFar
= leftDigits
+ grouping
.getSeparatorCount(leftDigits
);
1356 while (lengthSoFar
< desiredLength
) {
1357 lengthSoFar
+= grouping
.isSeparatorAt(leftDigits
+ 1, leftDigits
) ? 2 : 1;
1360 return (lengthSoFar
== desiredLength
);
1364 DecimalFormatImpl::computeExponentPatternLength() const {
1365 if (fUseScientific
) {
1366 return 1 + (fOptions
.fExponent
.fAlwaysShowSign
? 1 : 0) + fEffPrecision
.fMinExponentDigits
;
1372 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1373 int32_t fracDigitCount
) const {
1374 if (!fOptions
.fMantissa
.fAlwaysShowDecimal
&& fracDigitCount
== 0) {
1377 return fracDigitCount
+ 1;
1381 DecimalFormatImpl::toNumberPattern(
1382 UBool hasPadding
, int32_t minimumLength
, UnicodeString
& result
) const {
1383 // Get a grouping policy like the one in this object that does not
1384 // have minimum grouping since toPattern doesn't support it.
1385 DigitGrouping
grouping(fEffGrouping
);
1386 grouping
.fMinGrouping
= 0;
1388 // Only for fixed digits, these are the digits that get 0's.
1389 DigitInterval minInterval
;
1391 // Only for fixed digits, these are the digits that get #'s.
1392 DigitInterval maxInterval
;
1394 // Only for significant digits
1395 int32_t sigMin
= 0; /* initialize to avoid compiler warning */
1396 int32_t sigMax
= 0; /* initialize to avoid compiler warning */
1398 // These are all the digits to be displayed. For significant digits,
1399 // this interval always starts at the 1's place an extends left.
1400 DigitInterval fullInterval
;
1402 // Digit range of rounding increment. If rounding increment is .025.
1403 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
1404 int32_t roundingIncrementLowerExp
= 0;
1405 int32_t roundingIncrementUpperExp
= 0;
1407 if (fUseSigDigits
) {
1408 SignificantDigitInterval sigInterval
;
1409 extractSigDigits(sigInterval
);
1410 sigMax
= sigInterval
.getMax();
1411 sigMin
= sigInterval
.getMin();
1412 fullInterval
.setFracDigitCount(0);
1413 fullInterval
.setIntDigitCount(sigMax
);
1415 extractMinMaxDigits(minInterval
, maxInterval
);
1416 if (fUseScientific
) {
1417 if (maxInterval
.getIntDigitCount() > kMaxScientificIntegerDigits
) {
1418 maxInterval
.setIntDigitCount(1);
1419 minInterval
.shrinkToFitWithin(maxInterval
);
1421 } else if (hasPadding
) {
1422 // Make max int digits match min int digits for now, we
1423 // compute necessary padding later.
1424 maxInterval
.setIntDigitCount(minInterval
.getIntDigitCount());
1426 // For some reason toPattern adds at least one leading '#'
1427 maxInterval
.setIntDigitCount(minInterval
.getIntDigitCount() + 1);
1429 if (!fEffPrecision
.fMantissa
.fRoundingIncrement
.isZero()) {
1430 roundingIncrementLowerExp
=
1431 fEffPrecision
.fMantissa
.fRoundingIncrement
.getLowerExponent();
1432 roundingIncrementUpperExp
=
1433 fEffPrecision
.fMantissa
.fRoundingIncrement
.getUpperExponent();
1434 // We have to include the rounding increment in what we display
1435 maxInterval
.expandToContainDigit(roundingIncrementLowerExp
);
1436 maxInterval
.expandToContainDigit(roundingIncrementUpperExp
- 1);
1438 fullInterval
= maxInterval
;
1440 // We have to include enough digits to show grouping strategy
1441 int32_t minLengthToDescribeGrouping
=
1442 getMinimumLengthToDescribeGrouping(grouping
);
1443 if (minLengthToDescribeGrouping
> 0) {
1444 fullInterval
.expandToContainDigit(
1445 getMinimumLengthToDescribeGrouping(grouping
) - 1);
1448 // If we have a minimum length, we have to add digits to the left to
1451 // For non scientific notation,
1452 // minimumLengthForMantissa = minimumLength
1453 int32_t minimumLengthForMantissa
=
1454 minimumLength
- computeExponentPatternLength();
1455 int32_t mininumLengthForMantissaIntPart
=
1456 minimumLengthForMantissa
1457 - countFractionDigitAndDecimalPatternLength(
1458 fullInterval
.getFracDigitCount());
1459 // Because of grouping, we may need fewer than expected digits to
1460 // achieve the length we need.
1461 int32_t digitsNeeded
;
1462 if (getLeftDigitsForLeftLength(
1464 mininumLengthForMantissaIntPart
,
1465 fullInterval
.getIntDigitCount(),
1468 // In this case, we achieved the exact length that we want.
1469 fullInterval
.setIntDigitCount(digitsNeeded
);
1470 } else if (digitsNeeded
> fullInterval
.getIntDigitCount()) {
1472 // Having digitsNeeded digits goes over desired length which
1473 // means that to have desired length would mean starting on a
1474 // grouping sepearator e.g ,###,### so add a '#' and use one
1475 // less digit. This trick gives ####,### but that is the best
1477 result
.append(kPatternDigit
);
1478 fullInterval
.setIntDigitCount(digitsNeeded
- 1);
1481 int32_t maxDigitPos
= fullInterval
.getMostSignificantExclusive();
1482 int32_t minDigitPos
= fullInterval
.getLeastSignificantInclusive();
1483 for (int32_t i
= maxDigitPos
- 1; i
>= minDigitPos
; --i
) {
1484 if (!fOptions
.fMantissa
.fAlwaysShowDecimal
&& i
== -1) {
1485 result
.append(kPatternDecimalSeparator
);
1487 if (fUseSigDigits
) {
1489 if (i
>= sigMax
|| i
< sigMax
- sigMin
) {
1490 result
.append(kPatternDigit
);
1492 result
.append(kPatternSignificantDigit
);
1495 if (i
< roundingIncrementUpperExp
&& i
>= roundingIncrementLowerExp
) {
1496 result
.append((UChar
)(fEffPrecision
.fMantissa
.fRoundingIncrement
.getDigitByExponent(i
) + kPatternZeroDigit
));
1497 } else if (minInterval
.contains(i
)) {
1498 result
.append(kPatternZeroDigit
);
1500 result
.append(kPatternDigit
);
1503 if (grouping
.isSeparatorAt(i
+ 1, i
)) {
1504 result
.append(kPatternGroupingSeparator
);
1506 if (fOptions
.fMantissa
.fAlwaysShowDecimal
&& i
== 0) {
1507 result
.append(kPatternDecimalSeparator
);
1510 if (fUseScientific
) {
1511 result
.append(kPatternExponent
);
1512 if (fOptions
.fExponent
.fAlwaysShowSign
) {
1513 result
.append(kPatternPlus
);
1515 for (int32_t i
= 0; i
< 1 || i
< fEffPrecision
.fMinExponentDigits
; ++i
) {
1516 result
.append(kPatternZeroDigit
);
1523 DecimalFormatImpl::toPattern(UnicodeString
& result
) const {
1525 UnicodeString padSpec
;
1526 if (fAffixes
.fWidth
> 0) {
1527 padSpec
.append(kPatternPadEscape
);
1528 padSpec
.append(fAffixes
.fPadChar
);
1530 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforePrefix
) {
1531 result
.append(padSpec
);
1533 fPositivePrefixPattern
.toUserString(result
);
1534 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterPrefix
) {
1535 result
.append(padSpec
);
1538 fAffixes
.fWidth
> 0,
1539 fAffixes
.fWidth
- fPositivePrefixPattern
.countChar32() - fPositiveSuffixPattern
.countChar32(),
1541 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforeSuffix
) {
1542 result
.append(padSpec
);
1544 fPositiveSuffixPattern
.toUserString(result
);
1545 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterSuffix
) {
1546 result
.append(padSpec
);
1548 AffixPattern withNegative
;
1549 withNegative
.add(AffixPattern::kNegative
);
1550 withNegative
.append(fPositivePrefixPattern
);
1551 if (!fPositiveSuffixPattern
.equals(fNegativeSuffixPattern
) ||
1552 !withNegative
.equals(fNegativePrefixPattern
)) {
1553 result
.append(kPatternSeparator
);
1554 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforePrefix
) {
1555 result
.append(padSpec
);
1557 fNegativePrefixPattern
.toUserString(result
);
1558 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterPrefix
) {
1559 result
.append(padSpec
);
1562 fAffixes
.fWidth
> 0,
1563 fAffixes
.fWidth
- fNegativePrefixPattern
.countChar32() - fNegativeSuffixPattern
.countChar32(),
1565 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforeSuffix
) {
1566 result
.append(padSpec
);
1568 fNegativeSuffixPattern
.toUserString(result
);
1569 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterSuffix
) {
1570 result
.append(padSpec
);
1577 DecimalFormatImpl::getOldFormatWidth() const {
1578 if (fAffixes
.fWidth
== 0) {
1581 return fAffixes
.fWidth
- fPositiveSuffixPattern
.countChar32() - fPositivePrefixPattern
.countChar32();
1584 const UnicodeString
&
1585 DecimalFormatImpl::getConstSymbol(
1586 DecimalFormatSymbols::ENumberFormatSymbol symbol
) const {
1587 return fSymbols
->getConstSymbol(symbol
);
1591 DecimalFormatImpl::isParseFastpath() const {
1592 AffixPattern negative
;
1593 negative
.add(AffixPattern::kNegative
);
1595 return fAffixes
.fWidth
== 0 &&
1596 fPositivePrefixPattern
.countChar32() == 0 &&
1597 fNegativePrefixPattern
.equals(negative
) &&
1598 fPositiveSuffixPattern
.countChar32() == 0 &&
1599 fNegativeSuffixPattern
.countChar32() == 0;
1605 #endif /* #if !UCONFIG_NO_FORMATTING */