2 * Copyright (C) 2015, International Business Machines
3 * Corporation and others. All Rights Reserved.
5 * file name: decimfmtimpl.cpp
8 #include "unicode/utypes.h"
10 #if !UCONFIG_NO_FORMATTING
13 #include "unicode/numfmt.h"
14 #include "unicode/plurrule.h"
15 #include "unicode/ustring.h"
16 #include "decimalformatpattern.h"
17 #include "decimalformatpatternimpl.h"
18 #include "decimfmtimpl.h"
20 #include "plurrule_impl.h"
21 #include "valueformatter.h"
22 #include "visibledigits.h"
26 static const int32_t kMaxScientificIntegerDigits
= 8;
28 static const int32_t kFormattingPosPrefix
= (1 << 0);
29 static const int32_t kFormattingNegPrefix
= (1 << 1);
30 static const int32_t kFormattingPosSuffix
= (1 << 2);
31 static const int32_t kFormattingNegSuffix
= (1 << 3);
32 static const int32_t kFormattingSymbols
= (1 << 4);
33 static const int32_t kFormattingCurrency
= (1 << 5);
34 static const int32_t kFormattingUsesCurrency
= (1 << 6);
35 static const int32_t kFormattingPluralRules
= (1 << 7);
36 static const int32_t kFormattingAffixParser
= (1 << 8);
37 static const int32_t kFormattingCurrencyAffixInfo
= (1 << 9);
38 static const int32_t kFormattingAll
= (1 << 10) - 1;
39 static const int32_t kFormattingAffixes
=
40 kFormattingPosPrefix
| kFormattingPosSuffix
|
41 kFormattingNegPrefix
| kFormattingNegSuffix
;
42 static const int32_t kFormattingAffixParserWithCurrency
=
43 kFormattingAffixParser
| kFormattingCurrencyAffixInfo
;
45 DecimalFormatImpl::DecimalFormatImpl(
48 const UnicodeString
&pattern
,
52 fRoundingMode(DecimalFormat::kRoundHalfEven
),
54 fCurrencyUsage(UCURR_USAGE_STANDARD
),
57 if (U_FAILURE(status
)) {
60 fSymbols
= new DecimalFormatSymbols(
62 if (fSymbols
== NULL
) {
63 status
= U_MEMORY_ALLOCATION_ERROR
;
66 UParseError parseError
;
67 applyPattern(pattern
, FALSE
, parseError
, status
);
71 DecimalFormatImpl::DecimalFormatImpl(
73 const UnicodeString
&pattern
,
74 DecimalFormatSymbols
*symbolsToAdopt
,
75 UParseError
&parseError
,
79 fRoundingMode(DecimalFormat::kRoundHalfEven
),
80 fSymbols(symbolsToAdopt
),
81 fCurrencyUsage(UCURR_USAGE_STANDARD
),
84 applyPattern(pattern
, FALSE
, parseError
, status
);
88 DecimalFormatImpl::DecimalFormatImpl(
89 NumberFormat
*super
, const DecimalFormatImpl
&other
, UErrorCode
&status
) :
91 fMultiplier(other
.fMultiplier
),
93 fRoundingMode(other
.fRoundingMode
),
94 fMinSigDigits(other
.fMinSigDigits
),
95 fMaxSigDigits(other
.fMaxSigDigits
),
96 fUseScientific(other
.fUseScientific
),
97 fUseSigDigits(other
.fUseSigDigits
),
98 fGrouping(other
.fGrouping
),
99 fPositivePrefixPattern(other
.fPositivePrefixPattern
),
100 fNegativePrefixPattern(other
.fNegativePrefixPattern
),
101 fPositiveSuffixPattern(other
.fPositiveSuffixPattern
),
102 fNegativeSuffixPattern(other
.fNegativeSuffixPattern
),
103 fSymbols(other
.fSymbols
),
104 fCurrencyUsage(other
.fCurrencyUsage
),
106 fMonetary(other
.fMonetary
),
107 fAffixParser(other
.fAffixParser
),
108 fCurrencyAffixInfo(other
.fCurrencyAffixInfo
),
109 fEffPrecision(other
.fEffPrecision
),
110 fEffGrouping(other
.fEffGrouping
),
111 fOptions(other
.fOptions
),
112 fFormatter(other
.fFormatter
),
113 fAffixes(other
.fAffixes
) {
114 fSymbols
= new DecimalFormatSymbols(*fSymbols
);
115 if (fSymbols
== NULL
&& U_SUCCESS(status
)) {
116 status
= U_MEMORY_ALLOCATION_ERROR
;
118 if (other
.fRules
!= NULL
) {
119 fRules
= new PluralRules(*other
.fRules
);
120 if (fRules
== NULL
&& U_SUCCESS(status
)) {
121 status
= U_MEMORY_ALLOCATION_ERROR
;
128 DecimalFormatImpl::assign(const DecimalFormatImpl
&other
, UErrorCode
&status
) {
129 if (U_FAILURE(status
) || this == &other
) {
132 UObject::operator=(other
);
133 fMultiplier
= other
.fMultiplier
;
134 fScale
= other
.fScale
;
135 fRoundingMode
= other
.fRoundingMode
;
136 fMinSigDigits
= other
.fMinSigDigits
;
137 fMaxSigDigits
= other
.fMaxSigDigits
;
138 fUseScientific
= other
.fUseScientific
;
139 fUseSigDigits
= other
.fUseSigDigits
;
140 fGrouping
= other
.fGrouping
;
141 fPositivePrefixPattern
= other
.fPositivePrefixPattern
;
142 fNegativePrefixPattern
= other
.fNegativePrefixPattern
;
143 fPositiveSuffixPattern
= other
.fPositiveSuffixPattern
;
144 fNegativeSuffixPattern
= other
.fNegativeSuffixPattern
;
145 fCurrencyUsage
= other
.fCurrencyUsage
;
146 fMonetary
= other
.fMonetary
;
147 fAffixParser
= other
.fAffixParser
;
148 fCurrencyAffixInfo
= other
.fCurrencyAffixInfo
;
149 fEffPrecision
= other
.fEffPrecision
;
150 fEffGrouping
= other
.fEffGrouping
;
151 fOptions
= other
.fOptions
;
152 fFormatter
= other
.fFormatter
;
153 fAffixes
= other
.fAffixes
;
154 *fSymbols
= *other
.fSymbols
;
155 if (fRules
!= NULL
&& other
.fRules
!= NULL
) {
156 *fRules
= *other
.fRules
;
159 fRules
= other
.fRules
;
160 if (fRules
!= NULL
) {
161 fRules
= new PluralRules(*fRules
);
162 if (fRules
== NULL
) {
163 status
= U_MEMORY_ALLOCATION_ERROR
;
172 DecimalFormatImpl::operator==(const DecimalFormatImpl
&other
) const {
173 if (this == &other
) {
176 return (fMultiplier
== other
.fMultiplier
)
177 && (fScale
== other
.fScale
)
178 && (fRoundingMode
== other
.fRoundingMode
)
179 && (fMinSigDigits
== other
.fMinSigDigits
)
180 && (fMaxSigDigits
== other
.fMaxSigDigits
)
181 && (fUseScientific
== other
.fUseScientific
)
182 && (fUseSigDigits
== other
.fUseSigDigits
)
183 && fGrouping
.equals(other
.fGrouping
)
184 && fPositivePrefixPattern
.equals(other
.fPositivePrefixPattern
)
185 && fNegativePrefixPattern
.equals(other
.fNegativePrefixPattern
)
186 && fPositiveSuffixPattern
.equals(other
.fPositiveSuffixPattern
)
187 && fNegativeSuffixPattern
.equals(other
.fNegativeSuffixPattern
)
188 && fCurrencyUsage
== other
.fCurrencyUsage
189 && fAffixParser
.equals(other
.fAffixParser
)
190 && fCurrencyAffixInfo
.equals(other
.fCurrencyAffixInfo
)
191 && fEffPrecision
.equals(other
.fEffPrecision
)
192 && fEffGrouping
.equals(other
.fEffGrouping
)
193 && fOptions
.equals(other
.fOptions
)
194 && fFormatter
.equals(other
.fFormatter
)
195 && fAffixes
.equals(other
.fAffixes
)
196 && (*fSymbols
== *other
.fSymbols
)
197 && ((fRules
== other
.fRules
) || (
198 (fRules
!= NULL
) && (other
.fRules
!= NULL
)
199 && (*fRules
== *other
.fRules
)))
200 && (fMonetary
== other
.fMonetary
);
203 DecimalFormatImpl::~DecimalFormatImpl() {
209 DecimalFormatImpl::prepareValueFormatter(ValueFormatter
&vf
) const {
210 if (fUseScientific
) {
211 vf
.prepareScientificFormatting(
212 fFormatter
, fEffPrecision
, fOptions
);
215 vf
.prepareFixedDecimalFormatting(
216 fFormatter
, fEffGrouping
, fEffPrecision
.fMantissa
, fOptions
.fMantissa
);
221 DecimalFormatImpl::getPatternScale() const {
222 UBool usesPercent
= fPositivePrefixPattern
.usesPercent() ||
223 fPositiveSuffixPattern
.usesPercent() ||
224 fNegativePrefixPattern
.usesPercent() ||
225 fNegativeSuffixPattern
.usesPercent();
229 UBool usesPermill
= fPositivePrefixPattern
.usesPermill() ||
230 fPositiveSuffixPattern
.usesPermill() ||
231 fNegativePrefixPattern
.usesPermill() ||
232 fNegativeSuffixPattern
.usesPermill();
240 DecimalFormatImpl::setMultiplierScale(int32_t scale
) {
242 // Needed to preserve equality. fMultiplier == 0 means
247 fMultiplier
.shiftDecimalRight(scale
);
252 DecimalFormatImpl::format(
254 UnicodeString
&appendTo
,
256 UErrorCode
&status
) const {
257 FieldPositionOnlyHandler
handler(pos
);
258 return formatInt32(number
, appendTo
, handler
, status
);
262 DecimalFormatImpl::format(
264 UnicodeString
&appendTo
,
265 FieldPositionIterator
*posIter
,
266 UErrorCode
&status
) const {
267 FieldPositionIteratorHandler
handler(posIter
, status
);
268 return formatInt32(number
, appendTo
, handler
, status
);
272 UBool
DecimalFormatImpl::maybeFormatWithDigitList(
274 UnicodeString
&appendTo
,
275 FieldPositionHandler
&handler
,
276 UErrorCode
&status
) const {
277 if (!fMultiplier
.isZero()) {
280 digits
.mult(fMultiplier
, status
);
281 digits
.shiftDecimalRight(fScale
);
282 formatAdjustedDigitList(digits
, appendTo
, handler
, status
);
288 digits
.shiftDecimalRight(fScale
);
289 formatAdjustedDigitList(digits
, appendTo
, handler
, status
);
296 UBool
DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
298 VisibleDigitsWithExponent
&visibleDigits
,
299 UErrorCode
&status
) const {
300 if (!fMultiplier
.isZero()) {
303 digits
.mult(fMultiplier
, status
);
304 digits
.shiftDecimalRight(fScale
);
305 initVisibleDigitsFromAdjusted(digits
, visibleDigits
, status
);
311 digits
.shiftDecimalRight(fScale
);
312 initVisibleDigitsFromAdjusted(digits
, visibleDigits
, status
);
319 DecimalFormatImpl::formatInt32(
321 UnicodeString
&appendTo
,
322 FieldPositionHandler
&handler
,
323 UErrorCode
&status
) const {
324 if (maybeFormatWithDigitList(number
, appendTo
, handler
, status
)) {
328 return fAffixes
.formatInt32(
330 prepareValueFormatter(vf
),
338 DecimalFormatImpl::formatInt64(
340 UnicodeString
&appendTo
,
341 FieldPositionHandler
&handler
,
342 UErrorCode
&status
) const {
343 if (number
>= INT32_MIN
&& number
<= INT32_MAX
) {
344 return formatInt32((int32_t) number
, appendTo
, handler
, status
);
346 VisibleDigitsWithExponent digits
;
347 initVisibleDigitsWithExponent(number
, digits
, status
);
348 return formatVisibleDigitsWithExponent(
349 digits
, appendTo
, handler
, status
);
353 DecimalFormatImpl::formatDouble(
355 UnicodeString
&appendTo
,
356 FieldPositionHandler
&handler
,
357 UErrorCode
&status
) const {
358 VisibleDigitsWithExponent digits
;
359 initVisibleDigitsWithExponent(number
, digits
, status
);
360 return formatVisibleDigitsWithExponent(
361 digits
, appendTo
, handler
, status
);
365 DecimalFormatImpl::format(
367 UnicodeString
&appendTo
,
369 UErrorCode
&status
) const {
370 FieldPositionOnlyHandler
handler(pos
);
371 return formatDouble(number
, appendTo
, handler
, status
);
375 DecimalFormatImpl::format(
376 const DigitList
&number
,
377 UnicodeString
&appendTo
,
379 UErrorCode
&status
) const {
380 DigitList
dl(number
);
381 FieldPositionOnlyHandler
handler(pos
);
382 return formatDigitList(dl
, appendTo
, handler
, status
);
386 DecimalFormatImpl::format(
388 UnicodeString
&appendTo
,
390 UErrorCode
&status
) const {
391 FieldPositionOnlyHandler
handler(pos
);
392 return formatInt64(number
, appendTo
, handler
, status
);
396 DecimalFormatImpl::format(
398 UnicodeString
&appendTo
,
399 FieldPositionIterator
*posIter
,
400 UErrorCode
&status
) const {
401 FieldPositionIteratorHandler
handler(posIter
, status
);
402 return formatInt64(number
, appendTo
, handler
, status
);
406 DecimalFormatImpl::format(
408 UnicodeString
&appendTo
,
409 FieldPositionIterator
*posIter
,
410 UErrorCode
&status
) const {
411 FieldPositionIteratorHandler
handler(posIter
, status
);
412 return formatDouble(number
, appendTo
, handler
, status
);
416 DecimalFormatImpl::format(
417 const DigitList
&number
,
418 UnicodeString
&appendTo
,
419 FieldPositionIterator
*posIter
,
420 UErrorCode
&status
) const {
421 DigitList
dl(number
);
422 FieldPositionIteratorHandler
handler(posIter
, status
);
423 return formatDigitList(dl
, appendTo
, handler
, status
);
427 DecimalFormatImpl::format(
428 const StringPiece
&number
,
429 UnicodeString
&appendTo
,
430 FieldPositionIterator
*posIter
,
431 UErrorCode
&status
) const {
433 dl
.set(number
, status
);
434 FieldPositionIteratorHandler
handler(posIter
, status
);
435 return formatDigitList(dl
, appendTo
, handler
, status
);
439 DecimalFormatImpl::format(
440 const VisibleDigitsWithExponent
&digits
,
441 UnicodeString
&appendTo
,
443 UErrorCode
&status
) const {
444 FieldPositionOnlyHandler
handler(pos
);
445 return formatVisibleDigitsWithExponent(
446 digits
, appendTo
, handler
, status
);
450 DecimalFormatImpl::format(
451 const VisibleDigitsWithExponent
&digits
,
452 UnicodeString
&appendTo
,
453 FieldPositionIterator
*posIter
,
454 UErrorCode
&status
) const {
455 FieldPositionIteratorHandler
handler(posIter
, status
);
456 return formatVisibleDigitsWithExponent(
457 digits
, appendTo
, handler
, status
);
461 DecimalFormatImpl::adjustDigitList(
462 DigitList
&number
, UErrorCode
&status
) const {
463 number
.setRoundingMode(fRoundingMode
);
464 if (!fMultiplier
.isZero()) {
465 number
.mult(fMultiplier
, status
);
468 number
.shiftDecimalRight(fScale
);
475 DecimalFormatImpl::formatDigitList(
477 UnicodeString
&appendTo
,
478 FieldPositionHandler
&handler
,
479 UErrorCode
&status
) const {
480 VisibleDigitsWithExponent digits
;
481 initVisibleDigitsWithExponent(number
, digits
, status
);
482 return formatVisibleDigitsWithExponent(
483 digits
, appendTo
, handler
, status
);
487 DecimalFormatImpl::formatAdjustedDigitList(
489 UnicodeString
&appendTo
,
490 FieldPositionHandler
&handler
,
491 UErrorCode
&status
) const {
493 return fAffixes
.format(
495 prepareValueFormatter(vf
),
503 DecimalFormatImpl::formatVisibleDigitsWithExponent(
504 const VisibleDigitsWithExponent
&digits
,
505 UnicodeString
&appendTo
,
506 FieldPositionHandler
&handler
,
507 UErrorCode
&status
) const {
509 return fAffixes
.format(
511 prepareValueFormatter(vf
),
518 static FixedDecimal
&initFixedDecimal(
519 const VisibleDigits
&digits
, FixedDecimal
&result
) {
521 result
.isNegative
= digits
.isNegative();
522 result
.isNanOrInfinity
= digits
.isNaNOrInfinity();
523 digits
.getFixedDecimal(
524 result
.source
, result
.intValue
, result
.decimalDigits
,
525 result
.decimalDigitsWithoutTrailingZeros
,
526 result
.visibleDecimalDigitCount
, result
.hasIntegerValue
);
531 DecimalFormatImpl::getFixedDecimal(double number
, FixedDecimal
&result
, UErrorCode
&status
) const {
532 if (U_FAILURE(status
)) {
535 VisibleDigits digits
;
536 fEffPrecision
.fMantissa
.initVisibleDigits(number
, digits
, status
);
537 return initFixedDecimal(digits
, result
);
541 DecimalFormatImpl::getFixedDecimal(
542 DigitList
&number
, FixedDecimal
&result
, UErrorCode
&status
) const {
543 if (U_FAILURE(status
)) {
546 VisibleDigits digits
;
547 fEffPrecision
.fMantissa
.initVisibleDigits(number
, digits
, status
);
548 return initFixedDecimal(digits
, result
);
551 VisibleDigitsWithExponent
&
552 DecimalFormatImpl::initVisibleDigitsWithExponent(
554 VisibleDigitsWithExponent
&digits
,
555 UErrorCode
&status
) const {
556 if (maybeInitVisibleDigitsFromDigitList(
557 number
, digits
, status
)) {
560 if (fUseScientific
) {
561 fEffPrecision
.initVisibleDigitsWithExponent(
562 number
, digits
, status
);
564 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
565 number
, digits
, status
);
570 VisibleDigitsWithExponent
&
571 DecimalFormatImpl::initVisibleDigitsWithExponent(
573 VisibleDigitsWithExponent
&digits
,
574 UErrorCode
&status
) const {
575 if (maybeInitVisibleDigitsFromDigitList(
576 number
, digits
, status
)) {
579 if (fUseScientific
) {
580 fEffPrecision
.initVisibleDigitsWithExponent(
581 number
, digits
, status
);
583 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
584 number
, digits
, status
);
589 VisibleDigitsWithExponent
&
590 DecimalFormatImpl::initVisibleDigitsWithExponent(
592 VisibleDigitsWithExponent
&digits
,
593 UErrorCode
&status
) const {
594 adjustDigitList(number
, status
);
595 return initVisibleDigitsFromAdjusted(number
, digits
, status
);
598 VisibleDigitsWithExponent
&
599 DecimalFormatImpl::initVisibleDigitsFromAdjusted(
601 VisibleDigitsWithExponent
&digits
,
602 UErrorCode
&status
) const {
603 if (fUseScientific
) {
604 fEffPrecision
.initVisibleDigitsWithExponent(
605 number
, digits
, status
);
607 fEffPrecision
.fMantissa
.initVisibleDigitsWithExponent(
608 number
, digits
, status
);
614 DecimalFormatImpl::round(
615 DigitList
&number
, UErrorCode
&status
) const {
616 if (number
.isNaN() || number
.isInfinite()) {
619 adjustDigitList(number
, status
);
621 prepareValueFormatter(vf
);
622 return vf
.round(number
, status
);
626 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue
) {
627 fMinSigDigits
= newValue
;
628 fUseSigDigits
= TRUE
; // ticket 9936
633 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue
) {
634 fMaxSigDigits
= newValue
;
635 fUseSigDigits
= TRUE
; // ticket 9936
640 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min
, int32_t max
) {
643 fUseSigDigits
= TRUE
; // ticket 9936
648 DecimalFormatImpl::setScientificNotation(UBool newValue
) {
649 fUseScientific
= newValue
;
654 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue
) {
655 fUseSigDigits
= newValue
;
660 DecimalFormatImpl::setGroupingSize(int32_t newValue
) {
661 fGrouping
.fGrouping
= newValue
;
666 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue
) {
667 fGrouping
.fGrouping2
= newValue
;
672 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue
) {
673 fGrouping
.fMinGrouping
= newValue
;
678 DecimalFormatImpl::setCurrencyUsage(
679 UCurrencyUsage currencyUsage
, UErrorCode
&status
) {
680 fCurrencyUsage
= currencyUsage
;
681 updateFormatting(kFormattingCurrency
, status
);
685 DecimalFormatImpl::setRoundingIncrement(double d
) {
687 fEffPrecision
.fMantissa
.fRoundingIncrement
.set(d
);
689 fEffPrecision
.fMantissa
.fRoundingIncrement
.set(0.0);
694 DecimalFormatImpl::getRoundingIncrement() const {
695 return fEffPrecision
.fMantissa
.fRoundingIncrement
.getDouble();
699 DecimalFormatImpl::getMultiplier() const {
700 if (fMultiplier
.isZero()) {
703 return (int32_t) fMultiplier
.getDouble();
707 DecimalFormatImpl::setMultiplier(int32_t m
) {
708 if (m
== 0 || m
== 1) {
716 DecimalFormatImpl::setPositivePrefix(const UnicodeString
&str
) {
717 fPositivePrefixPattern
.remove();
718 fPositivePrefixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
719 UErrorCode status
= U_ZERO_ERROR
;
720 updateFormatting(kFormattingPosPrefix
, status
);
724 DecimalFormatImpl::setPositiveSuffix(const UnicodeString
&str
) {
725 fPositiveSuffixPattern
.remove();
726 fPositiveSuffixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
727 UErrorCode status
= U_ZERO_ERROR
;
728 updateFormatting(kFormattingPosSuffix
, status
);
732 DecimalFormatImpl::setNegativePrefix(const UnicodeString
&str
) {
733 fNegativePrefixPattern
.remove();
734 fNegativePrefixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
735 UErrorCode status
= U_ZERO_ERROR
;
736 updateFormatting(kFormattingNegPrefix
, status
);
740 DecimalFormatImpl::setNegativeSuffix(const UnicodeString
&str
) {
741 fNegativeSuffixPattern
.remove();
742 fNegativeSuffixPattern
.addLiteral(str
.getBuffer(), 0, str
.length());
743 UErrorCode status
= U_ZERO_ERROR
;
744 updateFormatting(kFormattingNegSuffix
, status
);
748 DecimalFormatImpl::getPositivePrefix(UnicodeString
&result
) const {
749 result
= fAffixes
.fPositivePrefix
.getOtherVariant().toString();
754 DecimalFormatImpl::getPositiveSuffix(UnicodeString
&result
) const {
755 result
= fAffixes
.fPositiveSuffix
.getOtherVariant().toString();
760 DecimalFormatImpl::getNegativePrefix(UnicodeString
&result
) const {
761 result
= fAffixes
.fNegativePrefix
.getOtherVariant().toString();
766 DecimalFormatImpl::getNegativeSuffix(UnicodeString
&result
) const {
767 result
= fAffixes
.fNegativeSuffix
.getOtherVariant().toString();
772 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols
*symbolsToAdopt
) {
773 if (symbolsToAdopt
== NULL
) {
777 fSymbols
= symbolsToAdopt
;
778 UErrorCode status
= U_ZERO_ERROR
;
779 updateFormatting(kFormattingSymbols
, status
);
783 DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
784 const UnicodeString
&pattern
, UErrorCode
&status
) {
786 applyPattern(pattern
, FALSE
, perror
, status
);
787 updateForApplyPatternFavorCurrencyPrecision(status
);
791 DecimalFormatImpl::applyPattern(
792 const UnicodeString
&pattern
, UErrorCode
&status
) {
794 applyPattern(pattern
, FALSE
, perror
, status
);
795 updateForApplyPattern(status
);
799 DecimalFormatImpl::applyPattern(
800 const UnicodeString
&pattern
,
801 UParseError
&perror
, UErrorCode
&status
) {
802 applyPattern(pattern
, FALSE
, perror
, status
);
803 updateForApplyPattern(status
);
807 DecimalFormatImpl::applyLocalizedPattern(
808 const UnicodeString
&pattern
, UErrorCode
&status
) {
810 applyPattern(pattern
, TRUE
, perror
, status
);
811 updateForApplyPattern(status
);
815 DecimalFormatImpl::applyLocalizedPattern(
816 const UnicodeString
&pattern
,
817 UParseError
&perror
, UErrorCode
&status
) {
818 applyPattern(pattern
, TRUE
, perror
, status
);
819 updateForApplyPattern(status
);
823 DecimalFormatImpl::applyPattern(
824 const UnicodeString
&pattern
,
825 UBool localized
, UParseError
&perror
, UErrorCode
&status
) {
826 if (U_FAILURE(status
)) {
829 DecimalFormatPatternParser patternParser
;
831 patternParser
.useSymbols(*fSymbols
);
833 DecimalFormatPattern out
;
834 patternParser
.applyPatternWithoutExpandAffix(
835 pattern
, out
, perror
, status
);
836 if (U_FAILURE(status
)) {
839 fUseScientific
= out
.fUseExponentialNotation
;
840 fUseSigDigits
= out
.fUseSignificantDigits
;
841 fSuper
->NumberFormat::setMinimumIntegerDigits(out
.fMinimumIntegerDigits
);
842 fSuper
->NumberFormat::setMaximumIntegerDigits(out
.fMaximumIntegerDigits
);
843 fSuper
->NumberFormat::setMinimumFractionDigits(out
.fMinimumFractionDigits
);
844 fSuper
->NumberFormat::setMaximumFractionDigits(out
.fMaximumFractionDigits
);
845 fMinSigDigits
= out
.fMinimumSignificantDigits
;
846 fMaxSigDigits
= out
.fMaximumSignificantDigits
;
847 fEffPrecision
.fMinExponentDigits
= out
.fMinExponentDigits
;
848 fOptions
.fExponent
.fAlwaysShowSign
= out
.fExponentSignAlwaysShown
;
849 fSuper
->NumberFormat::setGroupingUsed(out
.fGroupingUsed
);
850 fGrouping
.fGrouping
= out
.fGroupingSize
;
851 fGrouping
.fGrouping2
= out
.fGroupingSize2
;
852 fOptions
.fMantissa
.fAlwaysShowDecimal
= out
.fDecimalSeparatorAlwaysShown
;
853 if (out
.fRoundingIncrementUsed
) {
854 fEffPrecision
.fMantissa
.fRoundingIncrement
= out
.fRoundingIncrement
;
856 fEffPrecision
.fMantissa
.fRoundingIncrement
.clear();
858 fAffixes
.fPadChar
= out
.fPad
;
859 fNegativePrefixPattern
= out
.fNegPrefixAffix
;
860 fNegativeSuffixPattern
= out
.fNegSuffixAffix
;
861 fPositivePrefixPattern
= out
.fPosPrefixAffix
;
862 fPositiveSuffixPattern
= out
.fPosSuffixAffix
;
864 // Work around. Pattern parsing code and DecimalFormat code don't agree
865 // on the definition of field width, so we have to translate from
866 // pattern field width to decimal format field width here.
867 fAffixes
.fWidth
= out
.fFormatWidth
== 0 ? 0 :
868 out
.fFormatWidth
+ fPositivePrefixPattern
.countChar32()
869 + fPositiveSuffixPattern
.countChar32();
870 switch (out
.fPadPosition
) {
871 case DecimalFormatPattern::kPadBeforePrefix
:
872 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadBeforePrefix
;
874 case DecimalFormatPattern::kPadAfterPrefix
:
875 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadAfterPrefix
;
877 case DecimalFormatPattern::kPadBeforeSuffix
:
878 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadBeforeSuffix
;
880 case DecimalFormatPattern::kPadAfterSuffix
:
881 fAffixes
.fPadPosition
= DigitAffixesAndPadding::kPadAfterSuffix
;
889 DecimalFormatImpl::updatePrecision() {
890 if (fUseScientific
) {
891 updatePrecisionForScientific();
893 updatePrecisionForFixed();
897 static void updatePrecisionForScientificMinMax(
898 const DigitInterval
&min
,
899 const DigitInterval
&max
,
900 DigitInterval
&resultMin
,
901 DigitInterval
&resultMax
,
902 SignificantDigitInterval
&resultSignificant
) {
903 resultMin
.setIntDigitCount(0);
904 resultMin
.setFracDigitCount(0);
905 resultSignificant
.clear();
908 int32_t maxIntDigitCount
= max
.getIntDigitCount();
909 int32_t minIntDigitCount
= min
.getIntDigitCount();
910 int32_t maxFracDigitCount
= max
.getFracDigitCount();
911 int32_t minFracDigitCount
= min
.getFracDigitCount();
914 // Not in spec: maxIntDigitCount > 8 assume
915 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
916 // no provision for unsetting maxIntDigitCount which would be useful for
917 // scientific notation. The best we can do is assume that if
918 // maxIntDigitCount is the default of 2000000000 or is "big enough" then
919 // user did not intend to explicitly set it. The 8 was derived emperically
920 // by extensive testing of legacy code.
921 if (maxIntDigitCount
> 8) {
922 maxIntDigitCount
= minIntDigitCount
;
925 // Per the spec, exponent grouping happens if maxIntDigitCount is more
926 // than 1 and more than minIntDigitCount.
927 UBool bExponentGrouping
= maxIntDigitCount
> 1 && minIntDigitCount
< maxIntDigitCount
;
928 if (bExponentGrouping
) {
929 resultMax
.setIntDigitCount(maxIntDigitCount
);
931 // For exponent grouping minIntDigits is always treated as 1 even
932 // if it wasn't set to 1!
933 resultMin
.setIntDigitCount(1);
935 // Fixed digit count left of decimal. minIntDigitCount doesn't have
936 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
937 // maxIntDigitCount == 1.
938 int32_t fixedIntDigitCount
= maxIntDigitCount
;
940 // If fixedIntDigitCount is 0 but
941 // min or max fraction count is 0 too then use 1. This way we can get
942 // unlimited precision for X.XXXEX
943 if (fixedIntDigitCount
== 0 && (minFracDigitCount
== 0 || maxFracDigitCount
== 0)) {
944 fixedIntDigitCount
= 1;
946 resultMax
.setIntDigitCount(fixedIntDigitCount
);
947 resultMin
.setIntDigitCount(fixedIntDigitCount
);
949 // Spec says this is how we compute significant digits. 0 means
950 // unlimited significant digits.
951 int32_t maxSigDigits
= minIntDigitCount
+ maxFracDigitCount
;
952 if (maxSigDigits
> 0) {
953 int32_t minSigDigits
= minIntDigitCount
+ minFracDigitCount
;
954 resultSignificant
.setMin(minSigDigits
);
955 resultSignificant
.setMax(maxSigDigits
);
960 DecimalFormatImpl::updatePrecisionForScientific() {
961 FixedPrecision
*result
= &fEffPrecision
.fMantissa
;
963 result
->fMax
.setFracDigitCount(-1);
964 result
->fMax
.setIntDigitCount(1);
965 result
->fMin
.setFracDigitCount(0);
966 result
->fMin
.setIntDigitCount(1);
967 result
->fSignificant
.clear();
968 extractSigDigits(result
->fSignificant
);
973 extractMinMaxDigits(min
, max
);
974 updatePrecisionForScientificMinMax(
976 result
->fMin
, result
->fMax
, result
->fSignificant
);
980 DecimalFormatImpl::updatePrecisionForFixed() {
981 FixedPrecision
*result
= &fEffPrecision
.fMantissa
;
982 if (!fUseSigDigits
) {
983 extractMinMaxDigits(result
->fMin
, result
->fMax
);
984 result
->fSignificant
.clear();
986 extractSigDigits(result
->fSignificant
);
987 result
->fMin
.setIntDigitCount(1);
988 result
->fMin
.setFracDigitCount(0);
989 result
->fMax
.clear();
994 DecimalFormatImpl::extractMinMaxDigits(
995 DigitInterval
&min
, DigitInterval
&max
) const {
996 min
.setIntDigitCount(fSuper
->getMinimumIntegerDigits());
997 max
.setIntDigitCount(fSuper
->getMaximumIntegerDigits());
998 min
.setFracDigitCount(fSuper
->getMinimumFractionDigits());
999 max
.setFracDigitCount(fSuper
->getMaximumFractionDigits());
1003 DecimalFormatImpl::extractSigDigits(
1004 SignificantDigitInterval
&sig
) const {
1005 sig
.setMin(fMinSigDigits
< 0 ? 0 : fMinSigDigits
);
1006 sig
.setMax(fMaxSigDigits
< 0 ? 0 : fMaxSigDigits
);
1010 DecimalFormatImpl::updateGrouping() {
1011 if (fSuper
->isGroupingUsed()) {
1012 fEffGrouping
= fGrouping
;
1014 fEffGrouping
.clear();
1019 DecimalFormatImpl::updateCurrency(UErrorCode
&status
) {
1020 updateFormatting(kFormattingCurrency
, TRUE
, status
);
1024 DecimalFormatImpl::updateFormatting(
1025 int32_t changedFormattingFields
,
1026 UErrorCode
&status
) {
1027 updateFormatting(changedFormattingFields
, TRUE
, status
);
1031 DecimalFormatImpl::updateFormatting(
1032 int32_t changedFormattingFields
,
1033 UBool updatePrecisionBasedOnCurrency
,
1034 UErrorCode
&status
) {
1035 if (U_FAILURE(status
)) {
1038 // Each function updates one field. Order matters. For instance,
1039 // updatePluralRules comes before updateCurrencyAffixInfo because the
1040 // fRules field is needed to update the fCurrencyAffixInfo field.
1041 updateFormattingUsesCurrency(changedFormattingFields
);
1042 updateFormattingFixedPointFormatter(changedFormattingFields
);
1043 updateFormattingAffixParser(changedFormattingFields
);
1044 updateFormattingPluralRules(changedFormattingFields
, status
);
1045 updateFormattingCurrencyAffixInfo(
1046 changedFormattingFields
,
1047 updatePrecisionBasedOnCurrency
,
1049 updateFormattingLocalizedPositivePrefix(
1050 changedFormattingFields
, status
);
1051 updateFormattingLocalizedPositiveSuffix(
1052 changedFormattingFields
, status
);
1053 updateFormattingLocalizedNegativePrefix(
1054 changedFormattingFields
, status
);
1055 updateFormattingLocalizedNegativeSuffix(
1056 changedFormattingFields
, status
);
1060 DecimalFormatImpl::updateFormattingUsesCurrency(
1061 int32_t &changedFormattingFields
) {
1062 if ((changedFormattingFields
& kFormattingAffixes
) == 0) {
1063 // If no affixes changed, don't need to do any work
1066 UBool newUsesCurrency
=
1067 fPositivePrefixPattern
.usesCurrency() ||
1068 fPositiveSuffixPattern
.usesCurrency() ||
1069 fNegativePrefixPattern
.usesCurrency() ||
1070 fNegativeSuffixPattern
.usesCurrency();
1071 if (fMonetary
!= newUsesCurrency
) {
1072 fMonetary
= newUsesCurrency
;
1073 changedFormattingFields
|= kFormattingUsesCurrency
;
1078 DecimalFormatImpl::updateFormattingPluralRules(
1079 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1080 if ((changedFormattingFields
& (kFormattingSymbols
| kFormattingUsesCurrency
)) == 0) {
1081 // No work to do if both fSymbols and fMonetary
1082 // fields are unchanged
1085 if (U_FAILURE(status
)) {
1088 PluralRules
*newRules
= NULL
;
1090 newRules
= PluralRules::forLocale(fSymbols
->getLocale(), status
);
1091 if (U_FAILURE(status
)) {
1095 // Its ok to say a field has changed when it really hasn't but not
1096 // the other way around. Here we assume the field changed unless it
1097 // was NULL before and is still NULL now
1098 if (fRules
!= newRules
) {
1101 changedFormattingFields
|= kFormattingPluralRules
;
1106 DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
1107 int32_t &changedFormattingFields
,
1108 UBool updatePrecisionBasedOnCurrency
,
1109 UErrorCode
&status
) {
1110 if ((changedFormattingFields
& (
1111 kFormattingSymbols
| kFormattingCurrency
|
1112 kFormattingUsesCurrency
| kFormattingPluralRules
)) == 0) {
1113 // If all these fields are unchanged, no work to do.
1116 if (U_FAILURE(status
)) {
1120 if (fCurrencyAffixInfo
.isDefault()) {
1121 // In this case don't have to do any work
1124 fCurrencyAffixInfo
.set(NULL
, NULL
, NULL
, status
);
1125 if (U_FAILURE(status
)) {
1128 changedFormattingFields
|= kFormattingCurrencyAffixInfo
;
1130 const UChar
*currency
= fSuper
->getCurrency();
1131 UChar localeCurr
[4];
1132 if (currency
[0] == 0) {
1133 ucurr_forLocale(fSymbols
->getLocale().getName(), localeCurr
, UPRV_LENGTHOF(localeCurr
), &status
);
1134 if (U_SUCCESS(status
)) {
1135 currency
= localeCurr
;
1136 fSuper
->NumberFormat::setCurrency(currency
, status
);
1139 status
= U_ZERO_ERROR
;
1142 fCurrencyAffixInfo
.set(
1143 fSymbols
->getLocale().getName(), fRules
, currency
, status
);
1144 if (U_FAILURE(status
)) {
1147 UBool customCurrencySymbol
= FALSE
;
1148 // If DecimalFormatSymbols has custom currency symbol, prefer
1149 // that over what we just read from the resource bundles
1150 if (fSymbols
->isCustomCurrencySymbol()) {
1151 fCurrencyAffixInfo
.setSymbol(
1152 fSymbols
->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1153 customCurrencySymbol
= TRUE
;
1155 if (fSymbols
->isCustomIntlCurrencySymbol()) {
1156 fCurrencyAffixInfo
.setISO(
1157 fSymbols
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1158 customCurrencySymbol
= TRUE
;
1160 changedFormattingFields
|= kFormattingCurrencyAffixInfo
;
1161 if (currency
&& !customCurrencySymbol
&& updatePrecisionBasedOnCurrency
) {
1162 FixedPrecision precision
;
1163 CurrencyAffixInfo::adjustPrecision(
1164 currency
, fCurrencyUsage
, precision
, status
);
1165 if (U_FAILURE(status
)) {
1168 fSuper
->NumberFormat::setMinimumFractionDigits(
1169 precision
.fMin
.getFracDigitCount());
1170 fSuper
->NumberFormat::setMaximumFractionDigits(
1171 precision
.fMax
.getFracDigitCount());
1173 fEffPrecision
.fMantissa
.fRoundingIncrement
=
1174 precision
.fRoundingIncrement
;
1181 DecimalFormatImpl::updateFormattingFixedPointFormatter(
1182 int32_t &changedFormattingFields
) {
1183 if ((changedFormattingFields
& (kFormattingSymbols
| kFormattingUsesCurrency
)) == 0) {
1184 // No work to do if fSymbols is unchanged
1188 fFormatter
.setDecimalFormatSymbolsForMonetary(*fSymbols
);
1190 fFormatter
.setDecimalFormatSymbols(*fSymbols
);
1195 DecimalFormatImpl::updateFormattingAffixParser(
1196 int32_t &changedFormattingFields
) {
1197 if ((changedFormattingFields
& kFormattingSymbols
) == 0) {
1198 // No work to do if fSymbols is unchanged
1201 fAffixParser
.setDecimalFormatSymbols(*fSymbols
);
1202 changedFormattingFields
|= kFormattingAffixParser
;
1206 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
1207 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1208 if (U_FAILURE(status
)) {
1211 if ((changedFormattingFields
& (
1212 kFormattingPosPrefix
| kFormattingAffixParserWithCurrency
)) == 0) {
1216 fAffixes
.fPositivePrefix
.remove();
1218 fPositivePrefixPattern
,
1220 fAffixes
.fPositivePrefix
,
1225 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
1226 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1227 if (U_FAILURE(status
)) {
1230 if ((changedFormattingFields
& (
1231 kFormattingPosSuffix
| kFormattingAffixParserWithCurrency
)) == 0) {
1235 fAffixes
.fPositiveSuffix
.remove();
1237 fPositiveSuffixPattern
,
1239 fAffixes
.fPositiveSuffix
,
1244 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
1245 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1246 if (U_FAILURE(status
)) {
1249 if ((changedFormattingFields
& (
1250 kFormattingNegPrefix
| kFormattingAffixParserWithCurrency
)) == 0) {
1254 fAffixes
.fNegativePrefix
.remove();
1256 fNegativePrefixPattern
,
1258 fAffixes
.fNegativePrefix
,
1263 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
1264 int32_t &changedFormattingFields
, UErrorCode
&status
) {
1265 if (U_FAILURE(status
)) {
1268 if ((changedFormattingFields
& (
1269 kFormattingNegSuffix
| kFormattingAffixParserWithCurrency
)) == 0) {
1273 fAffixes
.fNegativeSuffix
.remove();
1275 fNegativeSuffixPattern
,
1277 fAffixes
.fNegativeSuffix
,
1282 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1283 UErrorCode
&status
) {
1284 updateAll(kFormattingAll
& ~kFormattingSymbols
, TRUE
, status
);
1288 DecimalFormatImpl::updateForApplyPattern(UErrorCode
&status
) {
1289 updateAll(kFormattingAll
& ~kFormattingSymbols
, FALSE
, status
);
1293 DecimalFormatImpl::updateAll(UErrorCode
&status
) {
1294 updateAll(kFormattingAll
, TRUE
, status
);
1298 DecimalFormatImpl::updateAll(
1299 int32_t formattingFlags
,
1300 UBool updatePrecisionBasedOnCurrency
,
1301 UErrorCode
&status
) {
1302 if (U_FAILURE(status
)) {
1308 formattingFlags
, updatePrecisionBasedOnCurrency
, status
);
1309 setMultiplierScale(getPatternScale());
1314 getMinimumLengthToDescribeGrouping(const DigitGrouping
&grouping
) {
1315 if (grouping
.fGrouping
<= 0) {
1318 if (grouping
.fGrouping2
<= 0) {
1319 return grouping
.fGrouping
+ 1;
1321 return grouping
.fGrouping
+ grouping
.fGrouping2
+ 1;
1325 * Given a grouping policy, calculates how many digits are needed left of
1326 * the decimal point to achieve a desired length left of the
1328 * @param grouping the grouping policy
1329 * @param desiredLength number of characters needed left of decimal point
1330 * @param minLeftDigits at least this many digits is returned
1331 * @param leftDigits the number of digits needed stored here
1332 * which is >= minLeftDigits.
1333 * @return true if a perfect fit or false if having leftDigits would exceed
1337 getLeftDigitsForLeftLength(
1338 const DigitGrouping
&grouping
,
1339 int32_t desiredLength
,
1340 int32_t minLeftDigits
,
1341 int32_t &leftDigits
) {
1342 leftDigits
= minLeftDigits
;
1343 int32_t lengthSoFar
= leftDigits
+ grouping
.getSeparatorCount(leftDigits
);
1344 while (lengthSoFar
< desiredLength
) {
1345 lengthSoFar
+= grouping
.isSeparatorAt(leftDigits
+ 1, leftDigits
) ? 2 : 1;
1348 return (lengthSoFar
== desiredLength
);
1352 DecimalFormatImpl::computeExponentPatternLength() const {
1353 if (fUseScientific
) {
1354 return 1 + (fOptions
.fExponent
.fAlwaysShowSign
? 1 : 0) + fEffPrecision
.fMinExponentDigits
;
1360 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1361 int32_t fracDigitCount
) const {
1362 if (!fOptions
.fMantissa
.fAlwaysShowDecimal
&& fracDigitCount
== 0) {
1365 return fracDigitCount
+ 1;
1369 DecimalFormatImpl::toNumberPattern(
1370 UBool hasPadding
, int32_t minimumLength
, UnicodeString
& result
) const {
1371 // Get a grouping policy like the one in this object that does not
1372 // have minimum grouping since toPattern doesn't support it.
1373 DigitGrouping
grouping(fEffGrouping
);
1374 grouping
.fMinGrouping
= 0;
1376 // Only for fixed digits, these are the digits that get 0's.
1377 DigitInterval minInterval
;
1379 // Only for fixed digits, these are the digits that get #'s.
1380 DigitInterval maxInterval
;
1382 // Only for significant digits
1386 // These are all the digits to be displayed. For significant digits,
1387 // this interval always starts at the 1's place an extends left.
1388 DigitInterval fullInterval
;
1390 // Digit range of rounding increment. If rounding increment is .025.
1391 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
1392 int32_t roundingIncrementLowerExp
= 0;
1393 int32_t roundingIncrementUpperExp
= 0;
1395 if (fUseSigDigits
) {
1396 SignificantDigitInterval sigInterval
;
1397 extractSigDigits(sigInterval
);
1398 sigMax
= sigInterval
.getMax();
1399 sigMin
= sigInterval
.getMin();
1400 fullInterval
.setFracDigitCount(0);
1401 fullInterval
.setIntDigitCount(sigMax
);
1403 extractMinMaxDigits(minInterval
, maxInterval
);
1404 if (fUseScientific
) {
1405 if (maxInterval
.getIntDigitCount() > kMaxScientificIntegerDigits
) {
1406 maxInterval
.setIntDigitCount(1);
1407 minInterval
.shrinkToFitWithin(maxInterval
);
1409 } else if (hasPadding
) {
1410 // Make max int digits match min int digits for now, we
1411 // compute necessary padding later.
1412 maxInterval
.setIntDigitCount(minInterval
.getIntDigitCount());
1414 // For some reason toPattern adds at least one leading '#'
1415 maxInterval
.setIntDigitCount(minInterval
.getIntDigitCount() + 1);
1417 if (!fEffPrecision
.fMantissa
.fRoundingIncrement
.isZero()) {
1418 roundingIncrementLowerExp
=
1419 fEffPrecision
.fMantissa
.fRoundingIncrement
.getLowerExponent();
1420 roundingIncrementUpperExp
=
1421 fEffPrecision
.fMantissa
.fRoundingIncrement
.getUpperExponent();
1422 // We have to include the rounding increment in what we display
1423 maxInterval
.expandToContainDigit(roundingIncrementLowerExp
);
1424 maxInterval
.expandToContainDigit(roundingIncrementUpperExp
- 1);
1426 fullInterval
= maxInterval
;
1428 // We have to include enough digits to show grouping strategy
1429 int32_t minLengthToDescribeGrouping
=
1430 getMinimumLengthToDescribeGrouping(grouping
);
1431 if (minLengthToDescribeGrouping
> 0) {
1432 fullInterval
.expandToContainDigit(
1433 getMinimumLengthToDescribeGrouping(grouping
) - 1);
1436 // If we have a minimum length, we have to add digits to the left to
1439 // For non scientific notation,
1440 // minimumLengthForMantissa = minimumLength
1441 int32_t minimumLengthForMantissa
=
1442 minimumLength
- computeExponentPatternLength();
1443 int32_t mininumLengthForMantissaIntPart
=
1444 minimumLengthForMantissa
1445 - countFractionDigitAndDecimalPatternLength(
1446 fullInterval
.getFracDigitCount());
1447 // Because of grouping, we may need fewer than expected digits to
1448 // achieve the length we need.
1449 int32_t digitsNeeded
;
1450 if (getLeftDigitsForLeftLength(
1452 mininumLengthForMantissaIntPart
,
1453 fullInterval
.getIntDigitCount(),
1456 // In this case, we achieved the exact length that we want.
1457 fullInterval
.setIntDigitCount(digitsNeeded
);
1458 } else if (digitsNeeded
> fullInterval
.getIntDigitCount()) {
1460 // Having digitsNeeded digits goes over desired length which
1461 // means that to have desired length would mean starting on a
1462 // grouping sepearator e.g ,###,### so add a '#' and use one
1463 // less digit. This trick gives ####,### but that is the best
1465 result
.append(kPatternDigit
);
1466 fullInterval
.setIntDigitCount(digitsNeeded
- 1);
1469 int32_t maxDigitPos
= fullInterval
.getMostSignificantExclusive();
1470 int32_t minDigitPos
= fullInterval
.getLeastSignificantInclusive();
1471 for (int32_t i
= maxDigitPos
- 1; i
>= minDigitPos
; --i
) {
1472 if (!fOptions
.fMantissa
.fAlwaysShowDecimal
&& i
== -1) {
1473 result
.append(kPatternDecimalSeparator
);
1475 if (fUseSigDigits
) {
1477 if (i
>= sigMax
|| i
< sigMax
- sigMin
) {
1478 result
.append(kPatternDigit
);
1480 result
.append(kPatternSignificantDigit
);
1483 if (i
< roundingIncrementUpperExp
&& i
>= roundingIncrementLowerExp
) {
1484 result
.append(fEffPrecision
.fMantissa
.fRoundingIncrement
.getDigitByExponent(i
) + kPatternZeroDigit
);
1485 } else if (minInterval
.contains(i
)) {
1486 result
.append(kPatternZeroDigit
);
1488 result
.append(kPatternDigit
);
1491 if (grouping
.isSeparatorAt(i
+ 1, i
)) {
1492 result
.append(kPatternGroupingSeparator
);
1494 if (fOptions
.fMantissa
.fAlwaysShowDecimal
&& i
== 0) {
1495 result
.append(kPatternDecimalSeparator
);
1498 if (fUseScientific
) {
1499 result
.append(kPatternExponent
);
1500 if (fOptions
.fExponent
.fAlwaysShowSign
) {
1501 result
.append(kPatternPlus
);
1503 for (int32_t i
= 0; i
< 1 || i
< fEffPrecision
.fMinExponentDigits
; ++i
) {
1504 result
.append(kPatternZeroDigit
);
1511 DecimalFormatImpl::toPattern(UnicodeString
& result
) const {
1513 UnicodeString padSpec
;
1514 if (fAffixes
.fWidth
> 0) {
1515 padSpec
.append(kPatternPadEscape
);
1516 padSpec
.append(fAffixes
.fPadChar
);
1518 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforePrefix
) {
1519 result
.append(padSpec
);
1521 fPositivePrefixPattern
.toUserString(result
);
1522 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterPrefix
) {
1523 result
.append(padSpec
);
1526 fAffixes
.fWidth
> 0,
1527 fAffixes
.fWidth
- fPositivePrefixPattern
.countChar32() - fPositiveSuffixPattern
.countChar32(),
1529 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforeSuffix
) {
1530 result
.append(padSpec
);
1532 fPositiveSuffixPattern
.toUserString(result
);
1533 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterSuffix
) {
1534 result
.append(padSpec
);
1536 AffixPattern withNegative
;
1537 withNegative
.add(AffixPattern::kNegative
);
1538 withNegative
.append(fPositivePrefixPattern
);
1539 if (!fPositiveSuffixPattern
.equals(fNegativeSuffixPattern
) ||
1540 !withNegative
.equals(fNegativePrefixPattern
)) {
1541 result
.append(kPatternSeparator
);
1542 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforePrefix
) {
1543 result
.append(padSpec
);
1545 fNegativePrefixPattern
.toUserString(result
);
1546 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterPrefix
) {
1547 result
.append(padSpec
);
1550 fAffixes
.fWidth
> 0,
1551 fAffixes
.fWidth
- fNegativePrefixPattern
.countChar32() - fNegativeSuffixPattern
.countChar32(),
1553 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadBeforeSuffix
) {
1554 result
.append(padSpec
);
1556 fNegativeSuffixPattern
.toUserString(result
);
1557 if (fAffixes
.fPadPosition
== DigitAffixesAndPadding::kPadAfterSuffix
) {
1558 result
.append(padSpec
);
1565 DecimalFormatImpl::getOldFormatWidth() const {
1566 if (fAffixes
.fWidth
== 0) {
1569 return fAffixes
.fWidth
- fPositiveSuffixPattern
.countChar32() - fPositivePrefixPattern
.countChar32();
1572 const UnicodeString
&
1573 DecimalFormatImpl::getConstSymbol(
1574 DecimalFormatSymbols::ENumberFormatSymbol symbol
) const {
1575 return fSymbols
->getConstSymbol(symbol
);
1579 DecimalFormatImpl::isParseFastpath() const {
1580 AffixPattern negative
;
1581 negative
.add(AffixPattern::kNegative
);
1583 return fAffixes
.fWidth
== 0 &&
1584 fPositivePrefixPattern
.countChar32() == 0 &&
1585 fNegativePrefixPattern
.equals(negative
) &&
1586 fPositiveSuffixPattern
.countChar32() == 0 &&
1587 fNegativeSuffixPattern
.countChar32() == 0;
1593 #endif /* #if !UCONFIG_NO_FORMATTING */