2 *******************************************************************************
3 * Copyright (C) 1997-2004, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
9 * Modification History:
11 * Date Name Description
12 * 02/19/97 aliu Converted from java.
13 * 03/20/97 clhuang Implemented with new APIs.
14 * 03/31/97 aliu Moved isLONG_MIN to DigitList, and fixed it.
15 * 04/3/97 aliu Rewrote parsing and formatting completely, and
16 * cleaned up and debugged. Actually works now.
17 * Implemented NAN and INF handling, for both parsing
18 * and formatting. Extensive testing & debugging.
19 * 04/10/97 aliu Modified to compile on AIX.
20 * 04/16/97 aliu Rewrote to use DigitList, which has been resurrected.
21 * Changed DigitCount to int per code review.
22 * 07/09/97 helena Made ParsePosition into a class.
23 * 08/26/97 aliu Extensive changes to applyPattern; completely
24 * rewritten from the Java.
25 * 09/09/97 aliu Ported over support for exponential formats.
26 * 07/20/98 stephen JDK 1.2 sync up.
27 * Various instances of '0' replaced with 'NULL'
28 * Check for grouping size in subFormat()
29 * Brought subParse() in line with Java 1.2
30 * Added method appendAffix()
31 * 08/24/1998 srl Removed Mutex calls. This is not a thread safe class!
32 * 02/22/99 stephen Removed character literals for EBCDIC safety
33 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
34 * 06/28/99 stephen Fixed bugs in toPattern().
35 * 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad,
37 ********************************************************************************
40 #include "unicode/utypes.h"
42 #if !UCONFIG_NO_FORMATTING
44 #include "unicode/decimfmt.h"
45 #include "unicode/choicfmt.h"
46 #include "unicode/ucurr.h"
47 #include "unicode/ustring.h"
48 #include "unicode/dcfmtsym.h"
49 #include "unicode/ures.h"
50 #include "unicode/uchar.h"
51 #include "unicode/curramt.h"
67 static void debugout(UnicodeString s
) {
69 s
.extract((int32_t) 0, s
.length(), buf
);
72 #define debug(x) printf("%s", x);
78 // *****************************************************************************
79 // class DecimalFormat
80 // *****************************************************************************
82 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat
)
84 // Constants for characters used in programmatic (unlocalized) patterns.
85 #define kPatternZeroDigit ((UChar)0x0030) /*'0'*/
86 #define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/
87 #define kPatternGroupingSeparator ((UChar)0x002C) /*','*/
88 #define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/
89 #define kPatternPerMill ((UChar)0x2030)
90 #define kPatternPercent ((UChar)0x0025) /*'%'*/
91 #define kPatternDigit ((UChar)0x0023) /*'#'*/
92 #define kPatternSeparator ((UChar)0x003B) /*';'*/
93 #define kPatternExponent ((UChar)0x0045) /*'E'*/
94 #define kPatternPlus ((UChar)0x002B) /*'+'*/
95 #define kPatternMinus ((UChar)0x002D) /*'-'*/
96 #define kPatternPadEscape ((UChar)0x002A) /*'*'*/
97 #define kQuote ((UChar)0x0027) /*'\''*/
99 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
100 * is used in patterns and substitued with either the currency symbol,
101 * or if it is doubled, with the international currency symbol. If the
102 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
103 * replaced with the monetary decimal separator.
105 #define kCurrencySign ((UChar)0x00A4)
106 #define kDefaultPad ((UChar)0x0020) /* */
108 const int32_t DecimalFormat::kDoubleIntegerDigits
= 309;
109 const int32_t DecimalFormat::kDoubleFractionDigits
= 340;
111 const int32_t DecimalFormat::kMaxScientificIntegerDigits
= 8;
114 * These are the tags we expect to see in normal resource bundle files associated
117 const char DecimalFormat::fgNumberPatterns
[]="NumberPatterns";
119 inline int32_t _min(int32_t a
, int32_t b
) { return (a
<b
) ? a
: b
; }
120 inline int32_t _max(int32_t a
, int32_t b
) { return (a
<b
) ? b
: a
; }
122 //------------------------------------------------------------------------------
123 // Constructs a DecimalFormat instance in the default locale.
125 DecimalFormat::DecimalFormat(UErrorCode
& status
)
127 fPosPrefixPattern(0),
128 fPosSuffixPattern(0),
129 fNegPrefixPattern(0),
130 fNegSuffixPattern(0),
136 fUseSignificantDigits(FALSE
),
137 fMinSignificantDigits(1),
138 fMaxSignificantDigits(6),
139 fMinExponentDigits(0),
140 fRoundingIncrement(0),
144 UParseError parseError
;
145 construct(status
, parseError
);
148 //------------------------------------------------------------------------------
149 // Constructs a DecimalFormat instance with the specified number format
150 // pattern in the default locale.
152 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
155 fPosPrefixPattern(0),
156 fPosSuffixPattern(0),
157 fNegPrefixPattern(0),
158 fNegSuffixPattern(0),
164 fUseSignificantDigits(FALSE
),
165 fMinSignificantDigits(1),
166 fMaxSignificantDigits(6),
167 fMinExponentDigits(0),
168 fRoundingIncrement(0),
172 UParseError parseError
;
173 construct(status
, parseError
, &pattern
);
176 //------------------------------------------------------------------------------
177 // Constructs a DecimalFormat instance with the specified number format
178 // pattern and the number format symbols in the default locale. The
179 // created instance owns the symbols.
181 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
182 DecimalFormatSymbols
* symbolsToAdopt
,
185 fPosPrefixPattern(0),
186 fPosSuffixPattern(0),
187 fNegPrefixPattern(0),
188 fNegSuffixPattern(0),
194 fUseSignificantDigits(FALSE
),
195 fMinSignificantDigits(1),
196 fMaxSignificantDigits(6),
197 fMinExponentDigits(0),
198 fRoundingIncrement(0),
202 UParseError parseError
;
203 if (symbolsToAdopt
== NULL
)
204 status
= U_ILLEGAL_ARGUMENT_ERROR
;
205 construct(status
, parseError
, &pattern
, symbolsToAdopt
);
208 DecimalFormat::DecimalFormat( const UnicodeString
& pattern
,
209 DecimalFormatSymbols
* symbolsToAdopt
,
210 UParseError
& parseErr
,
213 fPosPrefixPattern(0),
214 fPosSuffixPattern(0),
215 fNegPrefixPattern(0),
216 fNegSuffixPattern(0),
222 fUseSignificantDigits(FALSE
),
223 fMinSignificantDigits(1),
224 fMaxSignificantDigits(6),
225 fMinExponentDigits(0),
226 fRoundingIncrement(0),
230 if (symbolsToAdopt
== NULL
)
231 status
= U_ILLEGAL_ARGUMENT_ERROR
;
232 construct(status
,parseErr
, &pattern
, symbolsToAdopt
);
234 //------------------------------------------------------------------------------
235 // Constructs a DecimalFormat instance with the specified number format
236 // pattern and the number format symbols in the default locale. The
237 // created instance owns the clone of the symbols.
239 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
240 const DecimalFormatSymbols
& symbols
,
243 fPosPrefixPattern(0),
244 fPosSuffixPattern(0),
245 fNegPrefixPattern(0),
246 fNegSuffixPattern(0),
252 fUseSignificantDigits(FALSE
),
253 fMinSignificantDigits(1),
254 fMaxSignificantDigits(6),
255 fMinExponentDigits(0),
256 fRoundingIncrement(0),
260 UParseError parseError
;
261 construct(status
, parseError
, &pattern
, new DecimalFormatSymbols(symbols
));
264 //------------------------------------------------------------------------------
265 // Constructs a DecimalFormat instance with the specified number format
266 // pattern and the number format symbols in the desired locale. The
267 // created instance owns the symbols.
270 DecimalFormat::construct(UErrorCode
& status
,
271 UParseError
& parseErr
,
272 const UnicodeString
* pattern
,
273 DecimalFormatSymbols
* symbolsToAdopt
)
275 fSymbols
= symbolsToAdopt
; // Do this BEFORE aborting on status failure!!!
276 // fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!!
277 fRoundingIncrement
= NULL
;
278 fRoundingDouble
= 0.0;
279 fRoundingMode
= kRoundHalfEven
;
280 fPad
= kPatternPadEscape
;
281 fPadPosition
= kPadBeforePrefix
;
282 if (U_FAILURE(status
))
285 fPosPrefixPattern
= fPosSuffixPattern
= NULL
;
286 fNegPrefixPattern
= fNegSuffixPattern
= NULL
;
290 fDecimalSeparatorAlwaysShown
= FALSE
;
291 fIsCurrencyFormat
= FALSE
;
292 fUseExponentialNotation
= FALSE
;
293 fMinExponentDigits
= 0;
295 if (fSymbols
== NULL
)
297 fSymbols
= new DecimalFormatSymbols(Locale::getDefault(), status
);
300 status
= U_MEMORY_ALLOCATION_ERROR
;
306 // Uses the default locale's number format pattern if there isn't
311 UResourceBundle
*resource
= ures_open(NULL
, Locale::getDefault().getName(), &status
);
313 resource
= ures_getByKey(resource
, fgNumberPatterns
, resource
, &status
);
314 const UChar
*resStr
= ures_getStringByIndex(resource
, (int32_t)0, &len
, &status
);
315 str
.setTo(TRUE
, resStr
, len
);
317 ures_close(resource
);
320 if (U_FAILURE(status
))
325 if (pattern
->indexOf((UChar
)kCurrencySign
) >= 0) {
326 // If it looks like we are going to use a currency pattern
327 // then do the time consuming lookup.
328 if (symbolsToAdopt
== NULL
) {
329 setCurrencyForLocale(uloc_getDefault(), status
);
331 setCurrencyForSymbols();
334 setCurrency(NULL
, status
);
337 applyPattern(*pattern
, FALSE
/*not localized*/,parseErr
, status
);
341 * Sets our currency to be the default currency for the given locale.
343 void DecimalFormat::setCurrencyForLocale(const char* locale
, UErrorCode
& ec
) {
344 const UChar
* c
= NULL
;
346 // Trap an error in mapping locale to currency. If we can't
347 // map, then don't fail and set the currency to "".
348 UErrorCode ec2
= U_ZERO_ERROR
;
350 ucurr_forLocale(locale
, c
, 4, &ec2
);
355 //------------------------------------------------------------------------------
357 DecimalFormat::~DecimalFormat()
359 // delete fDigitList;
360 delete fPosPrefixPattern
;
361 delete fPosSuffixPattern
;
362 delete fNegPrefixPattern
;
363 delete fNegSuffixPattern
;
364 delete fCurrencyChoice
;
366 delete fRoundingIncrement
;
369 //------------------------------------------------------------------------------
372 DecimalFormat::DecimalFormat(const DecimalFormat
&source
)
373 : NumberFormat(source
),
375 fPosPrefixPattern(NULL
),
376 fPosSuffixPattern(NULL
),
377 fNegPrefixPattern(NULL
),
378 fNegSuffixPattern(NULL
),
379 fCurrencyChoice(NULL
),
381 fRoundingIncrement(NULL
)
386 //------------------------------------------------------------------------------
387 // assignment operator
388 // Note that fDigitList is not considered a significant part of the
389 // DecimalFormat because it's used as a buffer to process the numbers.
391 static void _copy_us_ptr(UnicodeString
** pdest
, const UnicodeString
* source
) {
392 if (source
== NULL
) {
395 } else if (*pdest
== NULL
) {
396 *pdest
= new UnicodeString(*source
);
403 DecimalFormat::operator=(const DecimalFormat
& rhs
)
406 NumberFormat::operator=(rhs
);
407 fPositivePrefix
= rhs
.fPositivePrefix
;
408 fPositiveSuffix
= rhs
.fPositiveSuffix
;
409 fNegativePrefix
= rhs
.fNegativePrefix
;
410 fNegativeSuffix
= rhs
.fNegativeSuffix
;
411 _copy_us_ptr(&fPosPrefixPattern
, rhs
.fPosPrefixPattern
);
412 _copy_us_ptr(&fPosSuffixPattern
, rhs
.fPosSuffixPattern
);
413 _copy_us_ptr(&fNegPrefixPattern
, rhs
.fNegPrefixPattern
);
414 _copy_us_ptr(&fNegSuffixPattern
, rhs
.fNegSuffixPattern
);
415 if (rhs
.fCurrencyChoice
== 0) {
416 delete fCurrencyChoice
;
419 fCurrencyChoice
= (ChoiceFormat
*) rhs
.fCurrencyChoice
->clone();
421 if(rhs
.fRoundingIncrement
== NULL
) {
422 delete fRoundingIncrement
;
423 fRoundingIncrement
= NULL
;
425 else if(fRoundingIncrement
== NULL
) {
426 fRoundingIncrement
= new DigitList(*rhs
.fRoundingIncrement
);
429 *fRoundingIncrement
= *rhs
.fRoundingIncrement
;
431 fRoundingDouble
= rhs
.fRoundingDouble
;
432 fMultiplier
= rhs
.fMultiplier
;
433 fGroupingSize
= rhs
.fGroupingSize
;
434 fGroupingSize2
= rhs
.fGroupingSize2
;
435 fDecimalSeparatorAlwaysShown
= rhs
.fDecimalSeparatorAlwaysShown
;
436 if(fSymbols
== NULL
) {
437 fSymbols
= new DecimalFormatSymbols(*rhs
.fSymbols
);
439 *fSymbols
= *rhs
.fSymbols
;
441 fUseExponentialNotation
= rhs
.fUseExponentialNotation
;
442 fExponentSignAlwaysShown
= rhs
.fExponentSignAlwaysShown
;
443 /*Bertrand A. D. Update 98.03.17*/
444 fIsCurrencyFormat
= rhs
.fIsCurrencyFormat
;
446 fMinExponentDigits
= rhs
.fMinExponentDigits
;
447 // if (fDigitList == NULL)
448 // fDigitList = new DigitList();
451 fFormatWidth
= rhs
.fFormatWidth
;
453 fPadPosition
= rhs
.fPadPosition
;
455 fMinSignificantDigits
= rhs
.fMinSignificantDigits
;
456 fMaxSignificantDigits
= rhs
.fMaxSignificantDigits
;
457 fUseSignificantDigits
= rhs
.fUseSignificantDigits
;
462 //------------------------------------------------------------------------------
465 DecimalFormat::operator==(const Format
& that
) const
470 // NumberFormat::operator== guarantees this cast is safe
471 const DecimalFormat
* other
= (DecimalFormat
*)&that
;
474 // This code makes it easy to determine why two format objects that should
477 if (!NumberFormat::operator==(that
)) {
478 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
479 debug("NumberFormat::!=");
481 if (!((fPosPrefixPattern
== other
->fPosPrefixPattern
&& // both null
482 fPositivePrefix
== other
->fPositivePrefix
)
483 || (fPosPrefixPattern
!= 0 && other
->fPosPrefixPattern
!= 0 &&
484 *fPosPrefixPattern
== *other
->fPosPrefixPattern
))) {
485 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
486 debug("Pos Prefix !=");
488 if (!((fPosSuffixPattern
== other
->fPosSuffixPattern
&& // both null
489 fPositiveSuffix
== other
->fPositiveSuffix
)
490 || (fPosSuffixPattern
!= 0 && other
->fPosSuffixPattern
!= 0 &&
491 *fPosSuffixPattern
== *other
->fPosSuffixPattern
))) {
492 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
493 debug("Pos Suffix !=");
495 if (!((fNegPrefixPattern
== other
->fNegPrefixPattern
&& // both null
496 fNegativePrefix
== other
->fNegativePrefix
)
497 || (fNegPrefixPattern
!= 0 && other
->fNegPrefixPattern
!= 0 &&
498 *fNegPrefixPattern
== *other
->fNegPrefixPattern
))) {
499 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
500 debug("Neg Prefix ");
501 if (fNegPrefixPattern
== NULL
) {
503 debugout(fNegativePrefix
);
506 debugout(*fNegPrefixPattern
);
509 if (other
->fNegPrefixPattern
== NULL
) {
511 debugout(other
->fNegativePrefix
);
514 debugout(*other
->fNegPrefixPattern
);
517 if (!((fNegSuffixPattern
== other
->fNegSuffixPattern
&& // both null
518 fNegativeSuffix
== other
->fNegativeSuffix
)
519 || (fNegSuffixPattern
!= 0 && other
->fNegSuffixPattern
!= 0 &&
520 *fNegSuffixPattern
== *other
->fNegSuffixPattern
))) {
521 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
522 debug("Neg Suffix ");
523 if (fNegSuffixPattern
== NULL
) {
525 debugout(fNegativeSuffix
);
528 debugout(*fNegSuffixPattern
);
531 if (other
->fNegSuffixPattern
== NULL
) {
533 debugout(other
->fNegativeSuffix
);
536 debugout(*other
->fNegSuffixPattern
);
539 if (!((fRoundingIncrement
== other
->fRoundingIncrement
) // both null
540 || (fRoundingIncrement
!= NULL
&&
541 other
->fRoundingIncrement
!= NULL
&&
542 *fRoundingIncrement
== *other
->fRoundingIncrement
))) {
543 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
544 debug("Rounding Increment !=");
546 if (fMultiplier
!= other
->fMultiplier
) {
547 if (first
) { printf("[ "); first
= FALSE
; }
548 printf("Multiplier %ld != %ld", fMultiplier
, other
->fMultiplier
);
550 if (fGroupingSize
!= other
->fGroupingSize
) {
551 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
552 printf("Grouping Size %ld != %ld", fGroupingSize
, other
->fGroupingSize
);
554 if (fGroupingSize2
!= other
->fGroupingSize2
) {
555 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
556 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2
, other
->fGroupingSize2
);
558 if (fDecimalSeparatorAlwaysShown
!= other
->fDecimalSeparatorAlwaysShown
) {
559 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
560 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown
, other
->fDecimalSeparatorAlwaysShown
);
562 if (fUseExponentialNotation
!= other
->fUseExponentialNotation
) {
563 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
566 if (!(!fUseExponentialNotation
||
567 fMinExponentDigits
!= other
->fMinExponentDigits
)) {
568 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
569 debug("Exp Digits !=");
571 if (*fSymbols
!= *(other
->fSymbols
)) {
572 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
575 // TODO Add debug stuff for significant digits here
576 if (!first
) { printf(" ]"); }
579 return (NumberFormat::operator==(that
) &&
580 ((fPosPrefixPattern
== other
->fPosPrefixPattern
&& // both null
581 fPositivePrefix
== other
->fPositivePrefix
)
582 || (fPosPrefixPattern
!= 0 && other
->fPosPrefixPattern
!= 0 &&
583 *fPosPrefixPattern
== *other
->fPosPrefixPattern
)) &&
584 ((fPosSuffixPattern
== other
->fPosSuffixPattern
&& // both null
585 fPositiveSuffix
== other
->fPositiveSuffix
)
586 || (fPosSuffixPattern
!= 0 && other
->fPosSuffixPattern
!= 0 &&
587 *fPosSuffixPattern
== *other
->fPosSuffixPattern
)) &&
588 ((fNegPrefixPattern
== other
->fNegPrefixPattern
&& // both null
589 fNegativePrefix
== other
->fNegativePrefix
)
590 || (fNegPrefixPattern
!= 0 && other
->fNegPrefixPattern
!= 0 &&
591 *fNegPrefixPattern
== *other
->fNegPrefixPattern
)) &&
592 ((fNegSuffixPattern
== other
->fNegSuffixPattern
&& // both null
593 fNegativeSuffix
== other
->fNegativeSuffix
)
594 || (fNegSuffixPattern
!= 0 && other
->fNegSuffixPattern
!= 0 &&
595 *fNegSuffixPattern
== *other
->fNegSuffixPattern
)) &&
596 ((fRoundingIncrement
== other
->fRoundingIncrement
) // both null
597 || (fRoundingIncrement
!= NULL
&&
598 other
->fRoundingIncrement
!= NULL
&&
599 *fRoundingIncrement
== *other
->fRoundingIncrement
)) &&
600 fMultiplier
== other
->fMultiplier
&&
601 fGroupingSize
== other
->fGroupingSize
&&
602 fGroupingSize2
== other
->fGroupingSize2
&&
603 fDecimalSeparatorAlwaysShown
== other
->fDecimalSeparatorAlwaysShown
&&
604 fUseExponentialNotation
== other
->fUseExponentialNotation
&&
605 (!fUseExponentialNotation
||
606 fMinExponentDigits
== other
->fMinExponentDigits
) &&
607 *fSymbols
== *(other
->fSymbols
) &&
608 fUseSignificantDigits
== other
->fUseSignificantDigits
&&
609 (!fUseSignificantDigits
||
610 (fMinSignificantDigits
== other
->fMinSignificantDigits
&&
611 fMaxSignificantDigits
== other
->fMaxSignificantDigits
)));
614 //------------------------------------------------------------------------------
617 DecimalFormat::clone() const
619 return new DecimalFormat(*this);
622 //------------------------------------------------------------------------------
625 DecimalFormat::format(int32_t number
,
626 UnicodeString
& appendTo
,
627 FieldPosition
& fieldPosition
) const
629 return format((int64_t)number
, appendTo
, fieldPosition
);
632 //------------------------------------------------------------------------------
635 DecimalFormat::format(int64_t number
,
636 UnicodeString
& appendTo
,
637 FieldPosition
& fieldPosition
) const
641 // Clears field positions.
642 fieldPosition
.setBeginIndex(0);
643 fieldPosition
.setEndIndex(0);
645 // If we are to do rounding, we need to move into the BigDecimal
646 // domain in order to do divide/multiply correctly.
648 // In general, long values always represent real finite numbers, so
649 // we don't have to check for +/- Infinity or NaN. However, there
650 // is one case we have to be careful of: The multiplier can push
651 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
652 // check for this before multiplying, and if it happens we use doubles
653 // instead, trading off accuracy for range.
654 if (fRoundingIncrement
!= NULL
655 || (fMultiplier
!= 0 && (number
> (U_INT64_MAX
/ fMultiplier
)
656 || number
< (U_INT64_MIN
/ fMultiplier
))))
658 digits
.set(((double)number
) * fMultiplier
,
660 !fUseExponentialNotation
&& !areSignificantDigitsUsed());
664 digits
.set(number
* fMultiplier
, precision(TRUE
));
667 return subformat(appendTo
, fieldPosition
, digits
, TRUE
);
670 //------------------------------------------------------------------------------
673 DecimalFormat::format( double number
,
674 UnicodeString
& appendTo
,
675 FieldPosition
& fieldPosition
) const
677 // Clears field positions.
678 fieldPosition
.setBeginIndex(0);
679 fieldPosition
.setEndIndex(0);
681 // Special case for NaN, sets the begin and end index to be the
682 // the string length of localized name of NaN.
683 if (uprv_isNaN(number
))
685 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
686 fieldPosition
.setBeginIndex(appendTo
.length());
688 appendTo
+= getConstSymbol(DecimalFormatSymbols::kNaNSymbol
);
690 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
691 fieldPosition
.setEndIndex(appendTo
.length());
693 addPadding(appendTo
, fieldPosition
, 0, 0);
697 /* Detecting whether a double is negative is easy with the exception of
698 * the value -0.0. This is a double which has a zero mantissa (and
699 * exponent), but a negative sign bit. It is semantically distinct from
700 * a zero with a positive sign bit, and this distinction is important
701 * to certain kinds of computations. However, it's a little tricky to
702 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
703 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
704 * -Infinity. Proper detection of -0.0 is needed to deal with the
705 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
707 UBool isNegative
= uprv_isNegative(number
);
709 // Do this BEFORE checking to see if value is infinite! Sets the
710 // begin and end index to be length of the string composed of
711 // localized name of Infinite and the positive/negative localized
714 number
*= fMultiplier
;
716 // Apply rounding after multiplier
717 if (fRoundingIncrement
!= NULL
) {
718 if (isNegative
) // For rounding in the correct direction
720 number
= fRoundingDouble
721 * round(number
/ fRoundingDouble
, fRoundingMode
, isNegative
);
726 // Special case for INFINITE,
727 if (uprv_isInfinite(number
))
729 int32_t prefixLen
= appendAffix(appendTo
, number
, isNegative
, TRUE
);
731 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
732 fieldPosition
.setBeginIndex(appendTo
.length());
734 appendTo
+= getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
);
736 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
737 fieldPosition
.setEndIndex(appendTo
.length());
739 int32_t suffixLen
= appendAffix(appendTo
, number
, isNegative
, FALSE
);
741 addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
);
747 // This detects negativity too.
748 digits
.set(number
, precision(FALSE
),
749 !fUseExponentialNotation
&& !areSignificantDigitsUsed());
751 return subformat(appendTo
, fieldPosition
, digits
, FALSE
);
755 * Round a double value to the nearest integer according to the
757 * @param a the absolute value of the number to be rounded
758 * @param mode a BigDecimal rounding mode
759 * @param isNegative true if the number to be rounded is negative
760 * @return the absolute value of the rounded result
762 double DecimalFormat::round(double a
, ERoundingMode mode
, UBool isNegative
) {
765 return isNegative
? uprv_floor(a
) : uprv_ceil(a
);
767 return isNegative
? uprv_ceil(a
) : uprv_floor(a
);
769 return uprv_floor(a
);
774 double f
= uprv_floor(a
);
775 if ((a
- f
) != 0.5) {
776 return uprv_floor(a
+ 0.5);
779 return (g
== uprv_floor(g
)) ? f
: (f
+ 1.0);
782 return ((a
- uprv_floor(a
)) <= 0.5) ? uprv_floor(a
) : uprv_ceil(a
);
784 return ((a
- uprv_floor(a
)) < 0.5) ? uprv_floor(a
) : uprv_ceil(a
);
790 DecimalFormat::format( const Formattable
& obj
,
791 UnicodeString
& appendTo
,
792 FieldPosition
& fieldPosition
,
793 UErrorCode
& status
) const
795 return NumberFormat::format(obj
, appendTo
, fieldPosition
, status
);
799 * Return true if a grouping separator belongs at the given
800 * position, based on whether grouping is in use and the values of
801 * the primary and secondary grouping interval.
802 * @param pos the number of integer digits to the right of
803 * the current position. Zero indicates the position after the
804 * rightmost integer digit.
805 * @return true if a grouping character belongs at the current
808 UBool
DecimalFormat::isGroupingPosition(int32_t pos
) const {
809 UBool result
= FALSE
;
810 if (isGroupingUsed() && (pos
> 0) && (fGroupingSize
> 0)) {
811 if ((fGroupingSize2
> 0) && (pos
> fGroupingSize
)) {
812 result
= ((pos
- fGroupingSize
) % fGroupingSize2
) == 0;
814 result
= pos
% fGroupingSize
== 0;
820 //------------------------------------------------------------------------------
823 * Complete the formatting of a finite number. On entry, the fDigitList must
824 * be filled in with the correct digits.
827 DecimalFormat::subformat(UnicodeString
& appendTo
,
828 FieldPosition
& fieldPosition
,
830 UBool isInteger
) const
832 // Gets the localized zero Unicode character.
833 UChar32 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
834 int32_t zeroDelta
= zero
- '0'; // '0' is the DigitList representation of zero
835 const UnicodeString
*grouping
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
);
836 const UnicodeString
*decimal
;
837 if(fIsCurrencyFormat
) {
838 decimal
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
840 decimal
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
842 UBool useSigDig
= areSignificantDigitsUsed();
843 int32_t maxIntDig
= getMaximumIntegerDigits();
844 int32_t minIntDig
= getMinimumIntegerDigits();
846 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
847 * format as zero. This allows sensible computations and preserves
848 * relations such as signum(1/x) = signum(x), where x is +Infinity or
849 * -Infinity. Prior to this fix, we always formatted zero values as if
850 * they were positive. Liu 7/6/98.
854 digits
.fDecimalAt
= digits
.fCount
= 0; // Normalize
857 // Appends the prefix.
858 double doubleValue
= digits
.getDouble();
859 int32_t prefixLen
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, TRUE
);
861 if (fUseExponentialNotation
)
863 // Record field information for caller.
864 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
866 fieldPosition
.setBeginIndex(appendTo
.length());
867 fieldPosition
.setEndIndex(-1);
869 else if (fieldPosition
.getField() == NumberFormat::kFractionField
)
871 fieldPosition
.setBeginIndex(-1);
874 int32_t minFracDig
= 0;
876 maxIntDig
= minIntDig
= 1;
877 minFracDig
= getMinimumSignificantDigits() - 1;
879 minFracDig
= getMinimumFractionDigits();
880 if (maxIntDig
> kMaxScientificIntegerDigits
) {
882 if (maxIntDig
< minIntDig
) {
883 maxIntDig
= minIntDig
;
886 if (maxIntDig
> minIntDig
) {
891 // Minimum integer digits are handled in exponential format by
892 // adjusting the exponent. For example, 0.01234 with 3 minimum
893 // integer digits is "123.4E-4".
895 // Maximum integer digits are interpreted as indicating the
896 // repeating range. This is useful for engineering notation, in
897 // which the exponent is restricted to a multiple of 3. For
898 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
899 // If maximum integer digits are defined and are larger than
900 // minimum integer digits, then minimum integer digits are
902 int32_t exponent
= digits
.fDecimalAt
;
903 if (maxIntDig
> 1 && maxIntDig
!= minIntDig
) {
904 // A exponent increment is defined; adjust to it.
905 exponent
= (exponent
> 0) ? (exponent
- 1) / maxIntDig
906 : (exponent
/ maxIntDig
) - 1;
907 exponent
*= maxIntDig
;
909 // No exponent increment is defined; use minimum integer digits.
910 // If none is specified, as in "#E0", generate 1 integer digit.
911 exponent
-= (minIntDig
> 0 || minFracDig
> 0)
915 // We now output a minimum number of digits, and more if there
916 // are more digits, up to the maximum number of digits. We
917 // place the decimal point after the "integer" digits, which
918 // are the first (decimalAt - exponent) digits.
919 int32_t minimumDigits
= minIntDig
+ minFracDig
;
920 // The number of integer digits is handled specially if the number
921 // is zero, since then there may be no digits.
922 int32_t integerDigits
= digits
.isZero() ? minIntDig
:
923 digits
.fDecimalAt
- exponent
;
924 int32_t totalDigits
= digits
.fCount
;
925 if (minimumDigits
> totalDigits
)
926 totalDigits
= minimumDigits
;
927 if (integerDigits
> totalDigits
)
928 totalDigits
= integerDigits
;
930 // totalDigits records total number of digits needs to be processed
932 for (i
=0; i
<totalDigits
; ++i
)
934 if (i
== integerDigits
)
936 // Record field information for caller.
937 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
938 fieldPosition
.setEndIndex(appendTo
.length());
940 appendTo
+= *decimal
;
942 // Record field information for caller.
943 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
944 fieldPosition
.setBeginIndex(appendTo
.length());
946 // Restores the digit character or pads the buffer with zeros.
947 UChar32 c
= (UChar32
)((i
< digits
.fCount
) ?
948 (digits
.fDigits
[i
] + zeroDelta
) :
953 // Record field information
954 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
956 if (fieldPosition
.getEndIndex() < 0)
957 fieldPosition
.setEndIndex(appendTo
.length());
959 else if (fieldPosition
.getField() == NumberFormat::kFractionField
)
961 if (fieldPosition
.getBeginIndex() < 0)
962 fieldPosition
.setBeginIndex(appendTo
.length());
963 fieldPosition
.setEndIndex(appendTo
.length());
966 // The exponent is output using the pattern-specified minimum
967 // exponent digits. There is no maximum limit to the exponent
968 // digits, since truncating the exponent would appendTo in an
969 // unacceptable inaccuracy.
970 appendTo
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
972 // For zero values, we force the exponent to zero. We
973 // must do this here, and not earlier, because the value
974 // is used to determine integer digit count above.
979 appendTo
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
980 } else if (fExponentSignAlwaysShown
) {
981 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
985 expDigits
.set(exponent
);
987 int expDig
= fMinExponentDigits
;
988 if (fUseExponentialNotation
&& expDig
< 1) {
991 for (i
=expDigits
.fDecimalAt
; i
<expDig
; ++i
)
994 for (i
=0; i
<expDigits
.fDecimalAt
; ++i
)
996 UChar32 c
= (UChar32
)((i
< expDigits
.fCount
) ?
997 (expDigits
.fDigits
[i
] + zeroDelta
) : zero
);
1001 else // Not using exponential notation
1003 // Record field information for caller.
1004 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
1005 fieldPosition
.setBeginIndex(appendTo
.length());
1007 int32_t sigCount
= 0;
1008 int32_t minSigDig
= getMinimumSignificantDigits();
1009 int32_t maxSigDig
= getMaximumSignificantDigits();
1012 maxSigDig
= INT32_MAX
;
1015 // Output the integer portion. Here 'count' is the total
1016 // number of integer digits we will display, including both
1017 // leading zeros required to satisfy getMinimumIntegerDigits,
1018 // and actual digits present in the number.
1019 int32_t count
= useSigDig
?
1020 _max(1, digits
.fDecimalAt
) : minIntDig
;
1021 if (digits
.fDecimalAt
> 0 && count
< digits
.fDecimalAt
) {
1022 count
= digits
.fDecimalAt
;
1025 // Handle the case where getMaximumIntegerDigits() is smaller
1026 // than the real number of integer digits. If this is so, we
1027 // output the least significant max integer digits. For example,
1028 // the value 1997 printed with 2 max integer digits is just "97".
1030 int32_t digitIndex
= 0; // Index into digitList.fDigits[]
1031 if (count
> maxIntDig
&& maxIntDig
>= 0) {
1033 digitIndex
= digits
.fDecimalAt
- count
;
1036 int32_t sizeBeforeIntegerPart
= appendTo
.length();
1039 for (i
=count
-1; i
>=0; --i
)
1041 if (i
< digits
.fDecimalAt
&& digitIndex
< digits
.fCount
&&
1042 sigCount
< maxSigDig
) {
1043 // Output a real digit
1044 appendTo
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
));
1049 // Output a zero (leading or trailing)
1056 // Output grouping separator if necessary.
1057 if (isGroupingPosition(i
)) {
1058 appendTo
.append(*grouping
);
1062 // Record field information for caller.
1063 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
1064 fieldPosition
.setEndIndex(appendTo
.length());
1066 // Determine whether or not there are any printable fractional
1067 // digits. If we've used up the digits we know there aren't.
1068 UBool fractionPresent
= (!isInteger
&& digitIndex
< digits
.fCount
) ||
1069 (useSigDig
? (sigCount
< minSigDig
) : (getMinimumFractionDigits() > 0));
1071 // If there is no fraction present, and we haven't printed any
1072 // integer digits, then print a zero. Otherwise we won't print
1073 // _any_ digits, and we won't be able to parse this string.
1074 if (!fractionPresent
&& appendTo
.length() == sizeBeforeIntegerPart
)
1077 // Output the decimal separator if we always do so.
1078 if (fDecimalSeparatorAlwaysShown
|| fractionPresent
)
1079 appendTo
+= *decimal
;
1081 // Record field information for caller.
1082 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
1083 fieldPosition
.setBeginIndex(appendTo
.length());
1085 count
= useSigDig
? INT32_MAX
: getMaximumFractionDigits();
1086 if (useSigDig
&& (sigCount
== maxSigDig
||
1087 (sigCount
>= minSigDig
&& digitIndex
== digits
.fCount
))) {
1091 for (i
=0; i
< count
; ++i
) {
1092 // Here is where we escape from the loop. We escape
1093 // if we've output the maximum fraction digits
1094 // (specified in the for expression above). We also
1095 // stop when we've output the minimum digits and
1096 // either: we have an integer, so there is no
1097 // fractional stuff to display, or we're out of
1098 // significant digits.
1099 if (!useSigDig
&& i
>= getMinimumFractionDigits() &&
1100 (isInteger
|| digitIndex
>= digits
.fCount
)) {
1104 // Output leading fractional zeros. These are zeros
1105 // that come after the decimal but before any
1106 // significant digits. These are only output if
1107 // abs(number being formatted) < 1.0.
1108 if (-1-i
> (digits
.fDecimalAt
-1)) {
1113 // Output a digit, if we have any precision left, or a
1114 // zero if we don't. We don't want to output noise digits.
1115 if (!isInteger
&& digitIndex
< digits
.fCount
) {
1116 appendTo
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
));
1121 // If we reach the maximum number of significant
1122 // digits, or if we output all the real digits and
1123 // reach the minimum, then we are done.
1126 (sigCount
== maxSigDig
||
1127 (digitIndex
== digits
.fCount
&& sigCount
>= minSigDig
))) {
1132 // Record field information for caller.
1133 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
1134 fieldPosition
.setEndIndex(appendTo
.length());
1137 int32_t suffixLen
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, FALSE
);
1139 addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
);
1144 * Inserts the character fPad as needed to expand result to fFormatWidth.
1145 * @param result the string to be padded
1147 void DecimalFormat::addPadding(UnicodeString
& appendTo
,
1148 FieldPosition
& fieldPosition
,
1150 int32_t suffixLen
) const
1152 if (fFormatWidth
> 0) {
1153 int32_t len
= fFormatWidth
- appendTo
.length();
1155 UnicodeString padding
;
1156 for (int32_t i
=0; i
<len
; ++i
) {
1159 switch (fPadPosition
) {
1160 case kPadAfterPrefix
:
1161 appendTo
.insert(prefixLen
, padding
);
1163 case kPadBeforePrefix
:
1164 appendTo
.insert(0, padding
);
1166 case kPadBeforeSuffix
:
1167 appendTo
.insert(appendTo
.length() - suffixLen
, padding
);
1169 case kPadAfterSuffix
:
1170 appendTo
+= padding
;
1173 if (fPadPosition
== kPadBeforePrefix
||
1174 fPadPosition
== kPadAfterPrefix
) {
1175 fieldPosition
.setBeginIndex(len
+ fieldPosition
.getBeginIndex());
1176 fieldPosition
.setEndIndex(len
+ fieldPosition
.getEndIndex());
1182 //------------------------------------------------------------------------------
1185 DecimalFormat::parse(const UnicodeString
& text
,
1186 Formattable
& result
,
1187 UErrorCode
& status
) const
1189 NumberFormat::parse(text
, result
, status
);
1193 DecimalFormat::parse(const UnicodeString
& text
,
1194 Formattable
& result
,
1195 ParsePosition
& parsePosition
) const {
1196 parse(text
, result
, parsePosition
, FALSE
);
1199 Formattable
& DecimalFormat::parseCurrency(const UnicodeString
& text
,
1200 Formattable
& result
,
1201 ParsePosition
& pos
) const {
1202 parse(text
, result
, pos
, TRUE
);
1207 * Parses the given text as either a number or a currency amount.
1208 * @param text the string to parse
1209 * @param result output parameter for the result
1210 * @param parsePosition input-output position; on input, the
1211 * position within text to match; must have 0 <= pos.getIndex() <
1212 * text.length(); on output, the position after the last matched
1213 * character. If the parse fails, the position in unchanged upon
1215 * @param parseCurrency if true, a currency amount is parsed;
1216 * otherwise a Number is parsed
1218 void DecimalFormat::parse(const UnicodeString
& text
,
1219 Formattable
& result
,
1220 ParsePosition
& parsePosition
,
1221 UBool parseCurrency
) const {
1223 int32_t i
= backup
= parsePosition
.getIndex();
1225 // Handle NaN as a special case:
1227 // Skip padding characters, if around prefix
1228 if (fFormatWidth
> 0 && (fPadPosition
== kPadBeforePrefix
||
1229 fPadPosition
== kPadAfterPrefix
)) {
1230 i
= skipPadding(text
, i
);
1232 // If the text is composed of the representation of NaN, returns NaN.length
1233 const UnicodeString
*nan
= &getConstSymbol(DecimalFormatSymbols::kNaNSymbol
);
1234 int32_t nanLen
= (text
.compare(i
, nan
->length(), *nan
)
1235 ? 0 : nan
->length());
1238 if (fFormatWidth
> 0 && (fPadPosition
== kPadBeforeSuffix
||
1239 fPadPosition
== kPadAfterSuffix
)) {
1240 i
= skipPadding(text
, i
);
1242 parsePosition
.setIndex(i
);
1243 result
.setDouble(uprv_getNaN());
1247 // NaN parse failed; start over
1250 // status is used to record whether a number is infinite.
1251 UBool status
[fgStatusLength
];
1253 UChar
* currency
= parseCurrency
? curbuf
: NULL
;
1256 if (!subparse(text
, parsePosition
, digits
, status
, currency
)) {
1257 parsePosition
.setIndex(backup
);
1262 if (status
[fgStatusInfinite
]) {
1263 double inf
= uprv_getInfinity();
1264 result
.setDouble(digits
.fIsPositive
? inf
: -inf
);
1268 // Do as much of the multiplier conversion as possible without
1270 int32_t mult
= fMultiplier
; // Don't modify this.multiplier
1271 while (mult
% 10 == 0) {
1273 --digits
.fDecimalAt
;
1276 // Handle integral values. We want to return the most
1277 // parsimonious type that will accommodate all of the result's
1278 // precision. We therefore only return a long if the result fits
1279 // entirely within a long (taking into account the multiplier) --
1280 // otherwise we fall through and return a double. When more
1281 // numeric types are supported by Formattable (e.g., 64-bit
1282 // integers, bignums) we will extend this logic to include them.
1283 if (digits
.fitsIntoLong(isParseIntegerOnly())) {
1284 int32_t n
= digits
.getLong();
1285 if (n
% mult
== 0) {
1286 result
.setLong(n
/ mult
);
1288 else { // else handle the remainder
1289 result
.setDouble(((double)n
) / mult
);
1292 else if (digits
.fitsIntoInt64(isParseIntegerOnly())) {
1293 int64_t n
= digits
.getInt64();
1294 if (n
% mult
== 0) {
1295 result
.setInt64(n
/ mult
);
1297 else { // else handle the remainder
1298 result
.setDouble(((double)n
) / mult
);
1302 // Handle non-integral or very large values
1303 // Dividing by one is okay and not that costly.
1304 result
.setDouble(digits
.getDouble() / mult
);
1308 if (parseCurrency
) {
1309 UErrorCode ec
= U_ZERO_ERROR
;
1310 Formattable
n(result
);
1311 result
.adoptObject(new CurrencyAmount(n
, curbuf
, ec
));
1312 U_ASSERT(U_SUCCESS(ec
)); // should always succeed
1318 This is an old implimentation that was preparing for 64-bit numbers in ICU.
1319 It is very slow, and 64-bit numbers are not ANSI-C compatible. This code
1320 is here if we change our minds.
1322 ^^^ what is this referring to? remove? ^^^ [alan]
1326 * Parse the given text into a number. The text is parsed beginning at
1327 * parsePosition, until an unparseable character is seen.
1328 * @param text the string to parse.
1329 * @param parsePosition The position at which to being parsing. Upon
1330 * return, the first unparsed character.
1331 * @param digits the DigitList to set to the parsed value.
1332 * @param status output param containing boolean status flags indicating
1333 * whether the value was infinite and whether it was positive.
1334 * @param currency return value for parsed currency, for generic
1335 * currency parsing mode, or NULL for normal parsing. In generic
1336 * currency parsing mode, any currency is parsed, not just the
1337 * currency that this formatter is set to.
1339 UBool
DecimalFormat::subparse(const UnicodeString
& text
, ParsePosition
& parsePosition
,
1340 DigitList
& digits
, UBool
* status
,
1341 UChar
* currency
) const
1343 int32_t position
= parsePosition
.getIndex();
1344 int32_t oldStart
= position
;
1346 // Match padding before prefix
1347 if (fFormatWidth
> 0 && fPadPosition
== kPadBeforePrefix
) {
1348 position
= skipPadding(text
, position
);
1351 // Match positive and negative prefixes; prefer longest match.
1352 int32_t posMatch
= compareAffix(text
, position
, FALSE
, TRUE
, currency
);
1353 int32_t negMatch
= compareAffix(text
, position
, TRUE
, TRUE
, currency
);
1354 if (posMatch
>= 0 && negMatch
>= 0) {
1355 if (posMatch
> negMatch
) {
1357 } else if (negMatch
> posMatch
) {
1361 if (posMatch
>= 0) {
1362 position
+= posMatch
;
1363 } else if (negMatch
>= 0) {
1364 position
+= negMatch
;
1366 parsePosition
.setErrorIndex(position
);
1370 // Match padding before prefix
1371 if (fFormatWidth
> 0 && fPadPosition
== kPadAfterPrefix
) {
1372 position
= skipPadding(text
, position
);
1375 // process digits or Inf, find decimal position
1376 const UnicodeString
*inf
= &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
);
1377 int32_t infLen
= (text
.compare(position
, inf
->length(), *inf
)
1378 ? 0 : inf
->length());
1379 position
+= infLen
; // infLen is non-zero when it does equal to infinity
1380 status
[fgStatusInfinite
] = (UBool
)infLen
;
1383 // We now have a string of digits, possibly with grouping symbols,
1384 // and decimal points. We want to process these into a DigitList.
1385 // We don't want to put a bunch of leading zeros into the DigitList
1386 // though, so we keep track of the location of the decimal point,
1387 // put only significant digits into the DigitList, and adjust the
1388 // exponent as needed.
1390 digits
.fDecimalAt
= digits
.fCount
= 0;
1391 UChar32 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
1393 const UnicodeString
*decimal
;
1394 if(fIsCurrencyFormat
) {
1395 decimal
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1397 decimal
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
1399 const UnicodeString
*grouping
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
);
1400 UBool sawDecimal
= FALSE
;
1401 UBool sawDigit
= FALSE
;
1402 int32_t backup
= -1;
1404 int32_t textLength
= text
.length(); // One less pointer to follow
1405 int32_t groupingLen
= grouping
->length();
1406 int32_t decimalLen
= decimal
->length();
1408 // We have to track digitCount ourselves, because digits.fCount will
1409 // pin when the maximum allowable digits is reached.
1410 int32_t digitCount
= 0;
1412 for (; position
< textLength
; )
1414 UChar32 ch
= text
.char32At(position
);
1416 /* We recognize all digit ranges, not only the Latin digit range
1417 * '0'..'9'. We do so by using the Character.digit() method,
1418 * which converts a valid Unicode digit to the range 0..9.
1420 * The character 'ch' may be a digit. If so, place its value
1421 * from 0 to 9 in 'digit'. First try using the locale digit,
1422 * which may or MAY NOT be a standard Unicode digit range. If
1423 * this fails, try using the standard Unicode digit ranges by
1424 * calling Character.digit(). If this also fails, digit will
1425 * have a value outside the range 0..9.
1428 if (digit
< 0 || digit
> 9)
1430 digit
= u_charDigitValue(ch
);
1433 if (digit
> 0 && digit
<= 9)
1435 // Cancel out backup setting (see grouping handler below)
1439 // output a regular non-zero digit.
1441 digits
.append((char)(digit
+ '0'));
1442 position
+= U16_LENGTH(ch
);
1444 else if (digit
== 0)
1446 // Cancel out backup setting (see grouping handler below)
1450 // Check for leading zeros
1451 if (digits
.fCount
!= 0)
1453 // output a regular zero digit.
1455 digits
.append((char)(digit
+ '0'));
1457 else if (sawDecimal
)
1459 // If we have seen the decimal, but no significant digits yet,
1460 // then we account for leading zeros by decrementing the
1461 // digits.fDecimalAt into negative values.
1462 --digits
.fDecimalAt
;
1464 // else ignore leading zeros in integer part of number.
1465 position
+= U16_LENGTH(ch
);
1467 else if (!text
.compare(position
, groupingLen
, *grouping
) && isGroupingUsed())
1469 // Ignore grouping characters, if we are using them, but require
1470 // that they be followed by a digit. Otherwise we backup and
1473 position
+= groupingLen
;
1475 else if (!text
.compare(position
, decimalLen
, *decimal
) && !isParseIntegerOnly() && !sawDecimal
)
1477 // If we're only parsing integers, or if we ALREADY saw the
1478 // decimal, then don't parse this one.
1480 digits
.fDecimalAt
= digitCount
; // Not digits.fCount!
1482 position
+= decimalLen
;
1485 const UnicodeString
*tmp
;
1486 tmp
= &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
1487 if (!text
.caseCompare(position
, tmp
->length(), *tmp
, U_FOLD_CASE_DEFAULT
)) // error code is set below if !sawDigit
1489 // Parse sign, if present
1490 int32_t pos
= position
+ tmp
->length();
1491 DigitList exponentDigits
;
1493 if (pos
< textLength
)
1495 tmp
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
1496 if (!text
.compare(pos
, tmp
->length(), *tmp
))
1498 pos
+= tmp
->length();
1501 tmp
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
1502 if (!text
.compare(pos
, tmp
->length(), *tmp
))
1504 pos
+= tmp
->length();
1505 exponentDigits
.fIsPositive
= FALSE
;
1510 while (pos
< textLength
) {
1511 ch
= text
[(int32_t)pos
];
1514 if (digit
< 0 || digit
> 9) {
1515 digit
= u_charDigitValue(ch
);
1517 if (0 <= digit
&& digit
<= 9) {
1519 exponentDigits
.append((char)(digit
+ '0'));
1525 if (exponentDigits
.fCount
> 0) {
1526 exponentDigits
.fDecimalAt
= exponentDigits
.fCount
;
1527 digits
.fDecimalAt
+= exponentDigits
.getLong();
1528 position
= pos
; // Advance past the exponent
1531 break; // Whether we fail or succeed, we exit this loop
1544 // If there was no decimal point we have an integer
1547 digits
.fDecimalAt
+= digitCount
; // Not digits.fCount!
1550 // If none of the text string was recognized. For example, parse
1551 // "x" with pattern "#0.00" (return index and error index both 0)
1552 // parse "$" with pattern "$#0.00". (return index 0 and error index
1554 if (!sawDigit
&& digitCount
== 0) {
1555 parsePosition
.setIndex(oldStart
);
1556 parsePosition
.setErrorIndex(oldStart
);
1561 // Match padding before suffix
1562 if (fFormatWidth
> 0 && fPadPosition
== kPadBeforeSuffix
) {
1563 position
= skipPadding(text
, position
);
1566 // Match positive and negative suffixes; prefer longest match.
1567 if (posMatch
>= 0) {
1568 posMatch
= compareAffix(text
, position
, FALSE
, FALSE
, currency
);
1570 if (negMatch
>= 0) {
1571 negMatch
= compareAffix(text
, position
, TRUE
, FALSE
, currency
);
1573 if (posMatch
>= 0 && negMatch
>= 0) {
1574 if (posMatch
> negMatch
) {
1576 } else if (negMatch
> posMatch
) {
1581 // Fail if neither or both
1582 if ((posMatch
>= 0) == (negMatch
>= 0)) {
1583 parsePosition
.setErrorIndex(position
);
1587 position
+= (posMatch
>=0 ? posMatch
: negMatch
);
1589 // Match padding before suffix
1590 if (fFormatWidth
> 0 && fPadPosition
== kPadAfterSuffix
) {
1591 position
= skipPadding(text
, position
);
1594 parsePosition
.setIndex(position
);
1596 digits
.fIsPositive
= (posMatch
>= 0);
1598 if(parsePosition
.getIndex() == oldStart
)
1600 parsePosition
.setErrorIndex(position
);
1607 * Starting at position, advance past a run of pad characters, if any.
1608 * Return the index of the first character after position that is not a pad
1609 * character. Result is >= position.
1611 int32_t DecimalFormat::skipPadding(const UnicodeString
& text
, int32_t position
) const {
1612 int32_t padLen
= U16_LENGTH(fPad
);
1613 while (position
< text
.length() &&
1614 text
.char32At(position
) == fPad
) {
1621 * Return the length matched by the given affix, or -1 if none.
1622 * Runs of white space in the affix, match runs of white space in
1623 * the input. Pattern white space and input white space are
1624 * determined differently; see code.
1625 * @param text input text
1626 * @param pos offset into input at which to begin matching
1629 * @param currency return value for parsed currency, for generic
1630 * currency parsing mode, or null for normal parsing. In generic
1631 * currency parsing mode, any currency is parsed, not just the
1632 * currency that this formatter is set to.
1633 * @return length of input that matches, or -1 if match failure
1635 int32_t DecimalFormat::compareAffix(const UnicodeString
& text
,
1639 UChar
* currency
) const {
1640 if (fCurrencyChoice
!= NULL
|| currency
!= NULL
) {
1642 return compareComplexAffix(isNegative
? *fNegPrefixPattern
: *fPosPrefixPattern
,
1643 text
, pos
, currency
);
1645 return compareComplexAffix(isNegative
? *fNegSuffixPattern
: *fPosSuffixPattern
,
1646 text
, pos
, currency
);
1651 return compareSimpleAffix(isNegative
? fNegativePrefix
: fPositivePrefix
,
1654 return compareSimpleAffix(isNegative
? fNegativeSuffix
: fPositiveSuffix
,
1660 * Return the length matched by the given affix, or -1 if none.
1661 * Runs of white space in the affix, match runs of white space in
1662 * the input. Pattern white space and input white space are
1663 * determined differently; see code.
1664 * @param affix pattern string, taken as a literal
1665 * @param input input text
1666 * @param pos offset into input at which to begin matching
1667 * @return length of input that matches, or -1 if match failure
1669 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString
& affix
,
1670 const UnicodeString
& input
,
1672 int32_t start
= pos
;
1673 for (int32_t i
=0; i
<affix
.length(); ) {
1674 UChar32 c
= affix
.char32At(i
);
1675 int32_t len
= U16_LENGTH(c
);
1676 if (uprv_isRuleWhiteSpace(c
)) {
1677 // We may have a pattern like: \u200F \u0020
1678 // and input text like: \u200F \u0020
1679 // Note that U+200F and U+0020 are RuleWhiteSpace but only
1680 // U+0020 is UWhiteSpace. So we have to first do a direct
1681 // match of the run of RULE whitespace in the pattern,
1682 // then match any extra characters.
1683 UBool literalMatch
= FALSE
;
1684 while (pos
< input
.length() &&
1685 input
.char32At(pos
) == c
) {
1686 literalMatch
= TRUE
;
1689 if (i
== affix
.length()) {
1692 c
= affix
.char32At(i
);
1693 len
= U16_LENGTH(c
);
1694 if (!uprv_isRuleWhiteSpace(c
)) {
1699 // Advance over run in pattern
1700 i
= skipRuleWhiteSpace(affix
, i
);
1702 // Advance over run in input text
1703 // Must see at least one white space char in input,
1704 // unless we've already matched some characters literally.
1706 pos
= skipUWhiteSpace(input
, pos
);
1707 if (pos
== s
&& !literalMatch
) {
1711 if (pos
< input
.length() &&
1712 input
.char32At(pos
) == c
) {
1724 * Skip over a run of zero or more isRuleWhiteSpace() characters at
1727 int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString
& text
, int32_t pos
) {
1728 while (pos
< text
.length()) {
1729 UChar32 c
= text
.char32At(pos
);
1730 if (!uprv_isRuleWhiteSpace(c
)) {
1733 pos
+= U16_LENGTH(c
);
1739 * Skip over a run of zero or more isUWhiteSpace() characters at pos
1742 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString
& text
, int32_t pos
) {
1743 while (pos
< text
.length()) {
1744 UChar32 c
= text
.char32At(pos
);
1745 if (!u_isUWhiteSpace(c
)) {
1748 pos
+= U16_LENGTH(c
);
1754 * Return the length matched by the given affix, or -1 if none.
1755 * @param affixPat pattern string
1756 * @param input input text
1757 * @param pos offset into input at which to begin matching
1758 * @param currency return value for parsed currency, for generic
1759 * currency parsing mode, or null for normal parsing. In generic
1760 * currency parsing mode, any currency is parsed, not just the
1761 * currency that this formatter is set to.
1762 * @return length of input that matches, or -1 if match failure
1764 int32_t DecimalFormat::compareComplexAffix(const UnicodeString
& affixPat
,
1765 const UnicodeString
& text
,
1767 UChar
* currency
) const {
1768 U_ASSERT(currency
!= NULL
||
1769 (fCurrencyChoice
!= NULL
&& *getCurrency() != 0));
1771 for (int32_t i
=0; i
<affixPat
.length() && pos
>= 0; ) {
1772 UChar32 c
= affixPat
.char32At(i
);
1776 U_ASSERT(i
<= affixPat
.length());
1777 c
= affixPat
.char32At(i
);
1780 const UnicodeString
* affix
= NULL
;
1783 case kCurrencySign
: {
1784 // If currency != null, then perform generic currency matching.
1785 // Otherwise, do currency choice parsing.
1786 UBool intl
= i
<affixPat
.length() &&
1787 affixPat
.char32At(i
) == kCurrencySign
;
1788 // Parse generic currency -- anything for which we
1789 // have a display name, or any 3-letter ISO code.
1790 if (currency
!= NULL
) {
1791 // Try to parse display name for our locale; first
1792 // determine our locale.
1793 UErrorCode ec
= U_ZERO_ERROR
;
1794 const char* loc
= getLocaleID(ULOC_VALID_LOCALE
, ec
);
1795 if (U_FAILURE(ec
) || loc
== NULL
|| *loc
== 0) {
1796 // applyPattern has been called; use the symbols
1797 loc
= fSymbols
->getLocale().getName();
1800 // Delegate parse of display name => ISO code to Currency
1801 ParsePosition
ppos(pos
);
1803 uprv_parseCurrency(loc
, text
, ppos
, curr
, ec
);
1805 // If parse succeeds, populate currency[0]
1806 if (U_SUCCESS(ec
) && ppos
.getIndex() != pos
) {
1807 u_strcpy(currency
, curr
);
1808 pos
= ppos
.getIndex();
1815 pos
= match(text
, pos
, getCurrency());
1817 ParsePosition
ppos(pos
);
1819 fCurrencyChoice
->parse(text
, result
, ppos
);
1820 pos
= (ppos
.getIndex() == pos
) ? -1 : ppos
.getIndex();
1825 case kPatternPercent
:
1826 affix
= &getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
1828 case kPatternPerMill
:
1829 affix
= &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
1832 affix
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
1835 affix
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
1838 // fall through to affix!=0 test, which will fail
1842 if (affix
!= NULL
) {
1843 pos
= match(text
, pos
, *affix
);
1848 pos
= match(text
, pos
, c
);
1849 if (uprv_isRuleWhiteSpace(c
)) {
1850 i
= skipRuleWhiteSpace(affixPat
, i
);
1857 * Match a single character at text[pos] and return the index of the
1858 * next character upon success. Return -1 on failure. If
1859 * isRuleWhiteSpace(ch) then match a run of white space in text.
1861 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, UChar32 ch
) {
1862 if (uprv_isRuleWhiteSpace(ch
)) {
1863 // Advance over run of white space in input text
1864 // Must see at least one white space char in input
1866 pos
= skipUWhiteSpace(text
, pos
);
1872 return (pos
>= 0 && text
.char32At(pos
) == ch
) ?
1873 (pos
+ U16_LENGTH(ch
)) : -1;
1877 * Match a string at text[pos] and return the index of the next
1878 * character upon success. Return -1 on failure. Match a run of
1879 * white space in str with a run of white space in text.
1881 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, const UnicodeString
& str
) {
1882 for (int32_t i
=0; i
<str
.length() && pos
>= 0; ) {
1883 UChar32 ch
= str
.char32At(i
);
1884 i
+= U16_LENGTH(ch
);
1885 if (uprv_isRuleWhiteSpace(ch
)) {
1886 i
= skipRuleWhiteSpace(str
, i
);
1888 pos
= match(text
, pos
, ch
);
1893 //------------------------------------------------------------------------------
1894 // Gets the pointer to the localized decimal format symbols
1896 const DecimalFormatSymbols
*
1897 DecimalFormat::getDecimalFormatSymbols() const
1902 //------------------------------------------------------------------------------
1903 // De-owning the current localized symbols and adopt the new symbols.
1906 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols
* symbolsToAdopt
)
1908 if (symbolsToAdopt
== NULL
) {
1909 return; // do not allow caller to set fSymbols to NULL
1912 UBool sameSymbols
= FALSE
;
1913 if (fSymbols
!= NULL
) {
1914 sameSymbols
= (UBool
)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) ==
1915 symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) &&
1916 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) ==
1917 symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1921 fSymbols
= symbolsToAdopt
;
1923 // If the currency symbols are the same, there is no need to recalculate.
1924 setCurrencyForSymbols();
1928 //------------------------------------------------------------------------------
1929 // Setting the symbols is equlivalent to adopting a newly created localized
1933 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols
& symbols
)
1935 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols
));
1939 * Update the currency object to match the symbols. This method
1940 * is used only when the caller has passed in a symbols object
1941 * that may not be the default object for its locale.
1944 DecimalFormat::setCurrencyForSymbols() {
1946 Update the affix strings accroding to symbols in order to keep
1947 the affix strings up to date.
1951 // With the introduction of the Currency object, the currency
1952 // symbols in the DFS object are ignored. For backward
1953 // compatibility, we check any explicitly set DFS object. If it
1954 // is a default symbols object for its locale, we change the
1955 // currency object to one for that locale. If it is custom,
1956 // we set the currency to null.
1957 UErrorCode ec
= U_ZERO_ERROR
;
1958 const UChar
* c
= NULL
;
1959 const char* loc
= fSymbols
->getLocale().getName();
1960 UChar intlCurrencySymbol
[4];
1961 ucurr_forLocale(loc
, intlCurrencySymbol
, 4, &ec
);
1962 UnicodeString currencySymbol
;
1964 uprv_getStaticCurrencyName(intlCurrencySymbol
, loc
, currencySymbol
, ec
);
1966 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) == currencySymbol
1967 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) == intlCurrencySymbol
)
1969 // Trap an error in mapping locale to currency. If we can't
1970 // map, then don't fail and set the currency to "".
1971 c
= intlCurrencySymbol
;
1973 ec
= U_ZERO_ERROR
; // reset local error code!
1978 //------------------------------------------------------------------------------
1979 // Gets the positive prefix of the number pattern.
1982 DecimalFormat::getPositivePrefix(UnicodeString
& result
) const
1984 result
= fPositivePrefix
;
1988 //------------------------------------------------------------------------------
1989 // Sets the positive prefix of the number pattern.
1992 DecimalFormat::setPositivePrefix(const UnicodeString
& newValue
)
1994 fPositivePrefix
= newValue
;
1995 delete fPosPrefixPattern
;
1996 fPosPrefixPattern
= 0;
1999 //------------------------------------------------------------------------------
2000 // Gets the negative prefix of the number pattern.
2003 DecimalFormat::getNegativePrefix(UnicodeString
& result
) const
2005 result
= fNegativePrefix
;
2009 //------------------------------------------------------------------------------
2010 // Gets the negative prefix of the number pattern.
2013 DecimalFormat::setNegativePrefix(const UnicodeString
& newValue
)
2015 fNegativePrefix
= newValue
;
2016 delete fNegPrefixPattern
;
2017 fNegPrefixPattern
= 0;
2020 //------------------------------------------------------------------------------
2021 // Gets the positive suffix of the number pattern.
2024 DecimalFormat::getPositiveSuffix(UnicodeString
& result
) const
2026 result
= fPositiveSuffix
;
2030 //------------------------------------------------------------------------------
2031 // Sets the positive suffix of the number pattern.
2034 DecimalFormat::setPositiveSuffix(const UnicodeString
& newValue
)
2036 fPositiveSuffix
= newValue
;
2037 delete fPosSuffixPattern
;
2038 fPosSuffixPattern
= 0;
2041 //------------------------------------------------------------------------------
2042 // Gets the negative suffix of the number pattern.
2045 DecimalFormat::getNegativeSuffix(UnicodeString
& result
) const
2047 result
= fNegativeSuffix
;
2051 //------------------------------------------------------------------------------
2052 // Sets the negative suffix of the number pattern.
2055 DecimalFormat::setNegativeSuffix(const UnicodeString
& newValue
)
2057 fNegativeSuffix
= newValue
;
2058 delete fNegSuffixPattern
;
2059 fNegSuffixPattern
= 0;
2062 //------------------------------------------------------------------------------
2063 // Gets the multiplier of the number pattern.
2065 int32_t DecimalFormat::getMultiplier() const
2070 //------------------------------------------------------------------------------
2071 // Sets the multiplier of the number pattern.
2073 DecimalFormat::setMultiplier(int32_t newValue
)
2075 // This shouldn't be set to 0.
2076 // Due to compatibility with ICU4J we cannot set an error code and refuse 0.
2077 // So the rest of the code should ignore fMultiplier when it's 0. [grhoten]
2078 fMultiplier
= newValue
;
2082 * Get the rounding increment.
2083 * @return A positive rounding increment, or 0.0 if rounding
2085 * @see #setRoundingIncrement
2086 * @see #getRoundingMode
2087 * @see #setRoundingMode
2089 double DecimalFormat::getRoundingIncrement() const {
2090 return fRoundingDouble
;
2094 * Set the rounding increment. This method also controls whether
2095 * rounding is enabled.
2096 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
2097 * Negative increments are equivalent to 0.0.
2098 * @see #getRoundingIncrement
2099 * @see #getRoundingMode
2100 * @see #setRoundingMode
2102 void DecimalFormat::setRoundingIncrement(double newValue
) {
2103 if (newValue
> 0.0) {
2104 if (fRoundingIncrement
== NULL
) {
2105 fRoundingIncrement
= new DigitList();
2107 fRoundingIncrement
->set((int32_t)newValue
);
2108 fRoundingDouble
= newValue
;
2110 delete fRoundingIncrement
;
2111 fRoundingIncrement
= NULL
;
2112 fRoundingDouble
= 0.0;
2117 * Get the rounding mode.
2118 * @return A rounding mode
2119 * @see #setRoundingIncrement
2120 * @see #getRoundingIncrement
2121 * @see #setRoundingMode
2123 DecimalFormat::ERoundingMode
DecimalFormat::getRoundingMode() const {
2124 return fRoundingMode
;
2128 * Set the rounding mode. This has no effect unless the rounding
2129 * increment is greater than zero.
2130 * @param roundingMode A rounding mode
2131 * @see #setRoundingIncrement
2132 * @see #getRoundingIncrement
2133 * @see #getRoundingMode
2135 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode
) {
2136 fRoundingMode
= roundingMode
;
2140 * Get the width to which the output of <code>format()</code> is padded.
2141 * @return the format width, or zero if no padding is in effect
2142 * @see #setFormatWidth
2143 * @see #getPadCharacter
2144 * @see #setPadCharacter
2145 * @see #getPadPosition
2146 * @see #setPadPosition
2148 int32_t DecimalFormat::getFormatWidth() const {
2149 return fFormatWidth
;
2153 * Set the width to which the output of <code>format()</code> is padded.
2154 * This method also controls whether padding is enabled.
2155 * @param width the width to which to pad the result of
2156 * <code>format()</code>, or zero to disable padding. A negative
2157 * width is equivalent to 0.
2158 * @see #getFormatWidth
2159 * @see #getPadCharacter
2160 * @see #setPadCharacter
2161 * @see #getPadPosition
2162 * @see #setPadPosition
2164 void DecimalFormat::setFormatWidth(int32_t width
) {
2165 fFormatWidth
= (width
> 0) ? width
: 0;
2168 UnicodeString
DecimalFormat::getPadCharacterString() const {
2172 void DecimalFormat::setPadCharacter(const UnicodeString
&padChar
) {
2173 if (padChar
.length() > 0) {
2174 fPad
= padChar
.char32At(0);
2182 * Get the position at which padding will take place. This is the location
2183 * at which padding will be inserted if the result of <code>format()</code>
2184 * is shorter than the format width.
2185 * @return the pad position, one of <code>kPadBeforePrefix</code>,
2186 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2187 * <code>kPadAfterSuffix</code>.
2188 * @see #setFormatWidth
2189 * @see #getFormatWidth
2190 * @see #setPadCharacter
2191 * @see #getPadCharacter
2192 * @see #setPadPosition
2193 * @see #kPadBeforePrefix
2194 * @see #kPadAfterPrefix
2195 * @see #kPadBeforeSuffix
2196 * @see #kPadAfterSuffix
2198 DecimalFormat::EPadPosition
DecimalFormat::getPadPosition() const {
2199 return fPadPosition
;
2203 * <strong><font face=helvetica color=red>NEW</font></strong>
2204 * Set the position at which padding will take place. This is the location
2205 * at which padding will be inserted if the result of <code>format()</code>
2206 * is shorter than the format width. This has no effect unless padding is
2208 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
2209 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2210 * <code>kPadAfterSuffix</code>.
2211 * @see #setFormatWidth
2212 * @see #getFormatWidth
2213 * @see #setPadCharacter
2214 * @see #getPadCharacter
2215 * @see #getPadPosition
2216 * @see #kPadBeforePrefix
2217 * @see #kPadAfterPrefix
2218 * @see #kPadBeforeSuffix
2219 * @see #kPadAfterSuffix
2221 void DecimalFormat::setPadPosition(EPadPosition padPos
) {
2222 fPadPosition
= padPos
;
2226 * Return whether or not scientific notation is used.
2227 * @return TRUE if this object formats and parses scientific notation
2228 * @see #setScientificNotation
2229 * @see #getMinimumExponentDigits
2230 * @see #setMinimumExponentDigits
2231 * @see #isExponentSignAlwaysShown
2232 * @see #setExponentSignAlwaysShown
2234 UBool
DecimalFormat::isScientificNotation() {
2235 return fUseExponentialNotation
;
2239 * Set whether or not scientific notation is used.
2240 * @param useScientific TRUE if this object formats and parses scientific
2242 * @see #isScientificNotation
2243 * @see #getMinimumExponentDigits
2244 * @see #setMinimumExponentDigits
2245 * @see #isExponentSignAlwaysShown
2246 * @see #setExponentSignAlwaysShown
2248 void DecimalFormat::setScientificNotation(UBool useScientific
) {
2249 fUseExponentialNotation
= useScientific
;
2253 * Return the minimum exponent digits that will be shown.
2254 * @return the minimum exponent digits that will be shown
2255 * @see #setScientificNotation
2256 * @see #isScientificNotation
2257 * @see #setMinimumExponentDigits
2258 * @see #isExponentSignAlwaysShown
2259 * @see #setExponentSignAlwaysShown
2261 int8_t DecimalFormat::getMinimumExponentDigits() const {
2262 return fMinExponentDigits
;
2266 * Set the minimum exponent digits that will be shown. This has no
2267 * effect unless scientific notation is in use.
2268 * @param minExpDig a value >= 1 indicating the fewest exponent digits
2269 * that will be shown. Values less than 1 will be treated as 1.
2270 * @see #setScientificNotation
2271 * @see #isScientificNotation
2272 * @see #getMinimumExponentDigits
2273 * @see #isExponentSignAlwaysShown
2274 * @see #setExponentSignAlwaysShown
2276 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig
) {
2277 fMinExponentDigits
= (int8_t)((minExpDig
> 0) ? minExpDig
: 1);
2281 * Return whether the exponent sign is always shown.
2282 * @return TRUE if the exponent is always prefixed with either the
2283 * localized minus sign or the localized plus sign, false if only negative
2284 * exponents are prefixed with the localized minus sign.
2285 * @see #setScientificNotation
2286 * @see #isScientificNotation
2287 * @see #setMinimumExponentDigits
2288 * @see #getMinimumExponentDigits
2289 * @see #setExponentSignAlwaysShown
2291 UBool
DecimalFormat::isExponentSignAlwaysShown() {
2292 return fExponentSignAlwaysShown
;
2296 * Set whether the exponent sign is always shown. This has no effect
2297 * unless scientific notation is in use.
2298 * @param expSignAlways TRUE if the exponent is always prefixed with either
2299 * the localized minus sign or the localized plus sign, false if only
2300 * negative exponents are prefixed with the localized minus sign.
2301 * @see #setScientificNotation
2302 * @see #isScientificNotation
2303 * @see #setMinimumExponentDigits
2304 * @see #getMinimumExponentDigits
2305 * @see #isExponentSignAlwaysShown
2307 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways
) {
2308 fExponentSignAlwaysShown
= expSignAlways
;
2311 //------------------------------------------------------------------------------
2312 // Gets the grouping size of the number pattern. For example, thousand or 10
2313 // thousand groupings.
2316 DecimalFormat::getGroupingSize() const
2318 return fGroupingSize
;
2321 //------------------------------------------------------------------------------
2322 // Gets the grouping size of the number pattern.
2325 DecimalFormat::setGroupingSize(int32_t newValue
)
2327 fGroupingSize
= newValue
;
2330 //------------------------------------------------------------------------------
2333 DecimalFormat::getSecondaryGroupingSize() const
2335 return fGroupingSize2
;
2338 //------------------------------------------------------------------------------
2341 DecimalFormat::setSecondaryGroupingSize(int32_t newValue
)
2343 fGroupingSize2
= newValue
;
2346 //------------------------------------------------------------------------------
2347 // Checks if to show the decimal separator.
2350 DecimalFormat::isDecimalSeparatorAlwaysShown() const
2352 return fDecimalSeparatorAlwaysShown
;
2355 //------------------------------------------------------------------------------
2356 // Sets to always show the decimal separator.
2359 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue
)
2361 fDecimalSeparatorAlwaysShown
= newValue
;
2364 //------------------------------------------------------------------------------
2365 // Emits the pattern of this DecimalFormat instance.
2368 DecimalFormat::toPattern(UnicodeString
& result
) const
2370 return toPattern(result
, FALSE
);
2373 //------------------------------------------------------------------------------
2374 // Emits the localized pattern this DecimalFormat instance.
2377 DecimalFormat::toLocalizedPattern(UnicodeString
& result
) const
2379 return toPattern(result
, TRUE
);
2382 //------------------------------------------------------------------------------
2384 * Expand the affix pattern strings into the expanded affix strings. If any
2385 * affix pattern string is null, do not expand it. This method should be
2386 * called any time the symbols or the affix patterns change in order to keep
2387 * the expanded affix strings up to date.
2389 void DecimalFormat::expandAffixes() {
2390 if (fPosPrefixPattern
!= 0) {
2391 expandAffix(*fPosPrefixPattern
, fPositivePrefix
, 0, FALSE
);
2393 if (fPosSuffixPattern
!= 0) {
2394 expandAffix(*fPosSuffixPattern
, fPositiveSuffix
, 0, FALSE
);
2396 if (fNegPrefixPattern
!= 0) {
2397 expandAffix(*fNegPrefixPattern
, fNegativePrefix
, 0, FALSE
);
2399 if (fNegSuffixPattern
!= 0) {
2400 expandAffix(*fNegSuffixPattern
, fNegativeSuffix
, 0, FALSE
);
2405 .append(*fPosPrefixPattern
).append("|").append(*fPosSuffixPattern
)
2406 .append(";") .append(*fNegPrefixPattern
).append("|").append(*fNegSuffixPattern
)
2408 .append(fPositivePrefix
).append("|").append(fPositiveSuffix
)
2409 .append(";") .append(fNegativePrefix
).append("|").append(fNegativeSuffix
)
2416 * Expand an affix pattern into an affix string. All characters in the
2417 * pattern are literal unless prefixed by kQuote. The following characters
2418 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2419 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote +
2420 * kCurrencySign + kCurrencySign), it is interpreted as an international
2421 * currency sign. Any other character after a kQuote represents itself.
2422 * kQuote must be followed by another character; kQuote may not occur by
2423 * itself at the end of the pattern.
2425 * This method is used in two distinct ways. First, it is used to expand
2426 * the stored affix patterns into actual affixes. For this usage, doFormat
2427 * must be false. Second, it is used to expand the stored affix patterns
2428 * given a specific number (doFormat == true), for those rare cases in
2429 * which a currency format references a ChoiceFormat (e.g., en_IN display
2430 * name for INR). The number itself is taken from digitList.
2432 * When used in the first way, this method has a side effect: It sets
2433 * currencyChoice to a ChoiceFormat object, if the currency's display name
2434 * in this locale is a ChoiceFormat pattern (very rare). It only does this
2435 * if currencyChoice is null to start with.
2437 * @param pattern the non-null, fPossibly empty pattern
2438 * @param affix string to receive the expanded equivalent of pattern.
2439 * Previous contents are deleted.
2440 * @param doFormat if false, then the pattern will be expanded, and if a
2441 * currency symbol is encountered that expands to a ChoiceFormat, the
2442 * currencyChoice member variable will be initialized if it is null. If
2443 * doFormat is true, then it is assumed that the currencyChoice has been
2444 * created, and it will be used to format the value in digitList.
2446 void DecimalFormat::expandAffix(const UnicodeString
& pattern
,
2447 UnicodeString
& affix
,
2449 UBool doFormat
) const {
2451 for (int i
=0; i
<pattern
.length(); ) {
2452 UChar32 c
= pattern
.char32At(i
);
2455 c
= pattern
.char32At(i
);
2458 case kCurrencySign
: {
2459 // As of ICU 2.2 we use the currency object, and
2460 // ignore the currency symbols in the DFS, unless
2461 // we have a null currency object. This occurs if
2462 // resurrecting a pre-2.2 object or if the user
2463 // sets a custom DFS.
2464 UBool intl
= i
<pattern
.length() &&
2465 pattern
.char32At(i
) == kCurrencySign
;
2469 const UChar
* currencyUChars
= getCurrency();
2470 if (currencyUChars
[0] != 0) {
2471 UErrorCode ec
= U_ZERO_ERROR
;
2473 affix
+= currencyUChars
;
2476 UBool isChoiceFormat
;
2477 const UChar
* s
= ucurr_getName(currencyUChars
, fSymbols
->getLocale().getName(),
2478 UCURR_SYMBOL_NAME
, &isChoiceFormat
, &len
, &ec
);
2479 if (isChoiceFormat
) {
2480 // Two modes here: If doFormat is false, we set up
2481 // currencyChoice. If doFormat is true, we use the
2482 // previously created currencyChoice to format the
2483 // value in digitList.
2485 // If the currency is handled by a ChoiceFormat,
2486 // then we're not going to use the expanded
2487 // patterns. Instantiate the ChoiceFormat and
2489 if (fCurrencyChoice
== NULL
) {
2490 // TODO Replace double-check with proper thread-safe code
2491 ChoiceFormat
* fmt
= new ChoiceFormat(s
, ec
);
2492 if (U_SUCCESS(ec
)) {
2494 if (fCurrencyChoice
== NULL
) {
2496 ((DecimalFormat
*)this)->fCurrencyChoice
= fmt
;
2503 // We could almost return null or "" here, since the
2504 // expanded affixes are almost not used at all
2505 // in this situation. However, one method --
2506 // toPattern() -- still does use the expanded
2507 // affixes, in order to set up a padding
2508 // pattern. We use the CURRENCY_SIGN as a
2510 affix
.append(kCurrencySign
);
2512 if (fCurrencyChoice
!= NULL
) {
2513 FieldPosition
pos(0); // ignored
2517 fCurrencyChoice
->format(number
, affix
, pos
);
2519 // We only arrive here if the currency choice
2520 // format in the locale data is INVALID.
2521 affix
+= currencyUChars
;
2526 affix
+= UnicodeString(s
, len
);
2530 affix
+= getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
2532 affix
+= getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
);
2537 case kPatternPercent
:
2538 affix
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
2540 case kPatternPerMill
:
2541 affix
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
2544 affix
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2547 affix
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
2561 * Append an affix to the given StringBuffer.
2562 * @param buf buffer to append to
2566 int32_t DecimalFormat::appendAffix(UnicodeString
& buf
, double number
,
2567 UBool isNegative
, UBool isPrefix
) const {
2568 if (fCurrencyChoice
!= 0) {
2569 const UnicodeString
* affixPat
= 0;
2571 affixPat
= isNegative
? fNegPrefixPattern
: fPosPrefixPattern
;
2573 affixPat
= isNegative
? fNegSuffixPattern
: fPosSuffixPattern
;
2575 UnicodeString affixBuf
;
2576 expandAffix(*affixPat
, affixBuf
, number
, TRUE
);
2577 buf
.append(affixBuf
);
2578 return affixBuf
.length();
2581 const UnicodeString
* affix
= NULL
;
2583 affix
= isNegative
? &fNegativePrefix
: &fPositivePrefix
;
2585 affix
= isNegative
? &fNegativeSuffix
: &fPositiveSuffix
;
2588 return affix
->length();
2592 * Appends an affix pattern to the given StringBuffer, quoting special
2593 * characters as needed. Uses the internal affix pattern, if that exists,
2594 * or the literal affix, if the internal affix pattern is null. The
2595 * appended string will generate the same affix pattern (or literal affix)
2596 * when passed to toPattern().
2598 * @param appendTo the affix string is appended to this
2599 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
2600 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
2601 * Ignored unless affixPattern is null. If affixPattern is null, then
2602 * expAffix is appended as a literal affix.
2603 * @param localized true if the appended pattern should contain localized
2604 * pattern characters; otherwise, non-localized pattern chars are appended
2606 void DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
,
2607 const UnicodeString
* affixPattern
,
2608 const UnicodeString
& expAffix
,
2609 UBool localized
) const {
2610 if (affixPattern
== 0) {
2611 appendAffixPattern(appendTo
, expAffix
, localized
);
2614 for (int pos
=0; pos
<affixPattern
->length(); pos
=i
) {
2615 i
= affixPattern
->indexOf(kQuote
, pos
);
2618 affixPattern
->extractBetween(pos
, affixPattern
->length(), s
);
2619 appendAffixPattern(appendTo
, s
, localized
);
2624 affixPattern
->extractBetween(pos
, i
, s
);
2625 appendAffixPattern(appendTo
, s
, localized
);
2627 UChar32 c
= affixPattern
->char32At(++i
);
2630 appendTo
.append(c
).append(c
);
2631 // Fall through and append another kQuote below
2632 } else if (c
== kCurrencySign
&&
2633 i
<affixPattern
->length() &&
2634 affixPattern
->char32At(i
) == kCurrencySign
) {
2636 appendTo
.append(c
).append(c
);
2637 } else if (localized
) {
2639 case kPatternPercent
:
2640 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
2642 case kPatternPerMill
:
2643 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
2646 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2649 appendTo
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
2662 * Append an affix to the given StringBuffer, using quotes if
2663 * there are special characters. Single quotes themselves must be
2664 * escaped in either case.
2667 DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
,
2668 const UnicodeString
& affix
,
2669 UBool localized
) const {
2672 needQuote
= affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
)) >= 0
2673 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
)) >= 0
2674 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
)) >= 0
2675 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
)) >= 0
2676 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
)) >= 0
2677 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
)) >= 0
2678 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
)) >= 0
2679 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
)) >= 0
2680 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) >= 0
2681 || affix
.indexOf(kCurrencySign
) >= 0;
2684 needQuote
= affix
.indexOf(kPatternZeroDigit
) >= 0
2685 || affix
.indexOf(kPatternGroupingSeparator
) >= 0
2686 || affix
.indexOf(kPatternDecimalSeparator
) >= 0
2687 || affix
.indexOf(kPatternPercent
) >= 0
2688 || affix
.indexOf(kPatternPerMill
) >= 0
2689 || affix
.indexOf(kPatternDigit
) >= 0
2690 || affix
.indexOf(kPatternSeparator
) >= 0
2691 || affix
.indexOf(kPatternExponent
) >= 0
2692 || affix
.indexOf(kPatternPlus
) >= 0
2693 || affix
.indexOf(kPatternMinus
) >= 0
2694 || affix
.indexOf(kCurrencySign
) >= 0;
2697 appendTo
+= (UChar
)0x0027 /*'\''*/;
2698 if (affix
.indexOf((UChar
)0x0027 /*'\''*/) < 0)
2701 for (int32_t j
= 0; j
< affix
.length(); ) {
2702 UChar32 c
= affix
.char32At(j
);
2705 if (c
== 0x0027 /*'\''*/)
2710 appendTo
+= (UChar
)0x0027 /*'\''*/;
2713 //------------------------------------------------------------------------------
2715 /* Tell the VC++ compiler not to spew out the warnings about integral size conversion */
2718 #pragma warning( disable : 4761 )
2723 DecimalFormat::toPattern(UnicodeString
& result
, UBool localized
) const
2726 UChar32 zero
, sigDigit
= kPatternSignificantDigit
;
2727 UnicodeString digit
, group
;
2729 int32_t roundingDecimalPos
= 0; // Pos of decimal in roundingDigits
2730 UnicodeString roundingDigits
;
2731 int32_t padPos
= (fFormatWidth
> 0) ? fPadPosition
: -1;
2732 UnicodeString padSpec
;
2733 UBool useSigDig
= areSignificantDigitsUsed();
2736 digit
.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
));
2737 group
.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
));
2738 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
2740 sigDigit
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0);
2744 digit
.append((UChar
)kPatternDigit
);
2745 group
.append((UChar
)kPatternGroupingSeparator
);
2746 zero
= (UChar32
)kPatternZeroDigit
;
2748 if (fFormatWidth
> 0) {
2750 padSpec
.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
));
2753 padSpec
.append((UChar
)kPatternPadEscape
);
2755 padSpec
.append(fPad
);
2757 if (fRoundingIncrement
!= NULL
) {
2758 for(i
=0; i
<fRoundingIncrement
->fCount
; ++i
) {
2759 roundingDigits
.append((UChar
)fRoundingIncrement
->fDigits
[i
]);
2761 roundingDecimalPos
= fRoundingIncrement
->fDecimalAt
;
2763 for (int32_t part
=0; part
<2; ++part
) {
2764 if (padPos
== kPadBeforePrefix
) {
2765 result
.append(padSpec
);
2767 appendAffixPattern(result
,
2768 (part
==0 ? fPosPrefixPattern
: fNegPrefixPattern
),
2769 (part
==0 ? fPositivePrefix
: fNegativePrefix
),
2771 if (padPos
== kPadAfterPrefix
&& ! padSpec
.isEmpty()) {
2772 result
.append(padSpec
);
2774 int32_t sub0Start
= result
.length();
2775 int32_t g
= isGroupingUsed() ? _max(0, fGroupingSize
) : 0;
2776 if (g
> 0 && fGroupingSize2
> 0 && fGroupingSize2
!= fGroupingSize
) {
2777 g
+= fGroupingSize2
;
2779 int32_t maxDig
= 0, minDig
= 0, maxSigDig
= 0;
2781 minDig
= getMinimumSignificantDigits();
2782 maxDig
= maxSigDig
= getMaximumSignificantDigits();
2784 minDig
= getMinimumIntegerDigits();
2785 maxDig
= getMaximumIntegerDigits();
2787 if (fUseExponentialNotation
) {
2788 if (maxDig
> kMaxScientificIntegerDigits
) {
2791 } else if (useSigDig
) {
2792 maxDig
= _max(maxDig
, g
+1);
2794 maxDig
= _max(_max(g
, getMinimumIntegerDigits()),
2795 roundingDecimalPos
) + 1;
2797 for (i
= maxDig
; i
> 0; --i
) {
2798 if (!fUseExponentialNotation
&& i
<maxDig
&&
2799 isGroupingPosition(i
)) {
2800 result
.append(group
);
2803 // #@,@### (maxSigDig == 5, minSigDig == 2)
2804 // 65 4321 (1-based pos, count from the right)
2805 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
2806 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
2807 if (maxSigDig
>= i
&& i
> (maxSigDig
- minDig
)) {
2808 result
.append(sigDigit
);
2810 result
.append(digit
);
2813 if (! roundingDigits
.isEmpty()) {
2814 int32_t pos
= roundingDecimalPos
- i
;
2815 if (pos
>= 0 && pos
< roundingDigits
.length()) {
2816 result
.append((UChar
) (roundingDigits
.char32At(pos
) - kPatternZeroDigit
+ zero
));
2821 result
.append(zero
);
2823 result
.append(digit
);
2828 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown
) {
2830 result
+= getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
2833 result
.append((UChar
)kPatternDecimalSeparator
);
2836 int32_t pos
= roundingDecimalPos
;
2837 for (i
= 0; i
< getMaximumFractionDigits(); ++i
) {
2838 if (! roundingDigits
.isEmpty() && pos
< roundingDigits
.length()) {
2840 result
.append(zero
);
2843 result
.append((UChar
)(roundingDigits
.char32At(pos
) - kPatternZeroDigit
+ zero
));
2848 if (i
<getMinimumFractionDigits()) {
2849 result
.append(zero
);
2852 result
.append(digit
);
2856 if (fUseExponentialNotation
) {
2858 result
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
2861 result
.append((UChar
)kPatternExponent
);
2863 if (fExponentSignAlwaysShown
) {
2865 result
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2868 result
.append((UChar
)kPatternPlus
);
2871 for (i
=0; i
<fMinExponentDigits
; ++i
) {
2872 result
.append(zero
);
2875 if (! padSpec
.isEmpty() && !fUseExponentialNotation
) {
2876 int32_t add
= fFormatWidth
- result
.length() + sub0Start
2878 ? fPositivePrefix
.length() + fPositiveSuffix
.length()
2879 : fNegativePrefix
.length() + fNegativeSuffix
.length());
2881 result
.insert(sub0Start
, digit
);
2884 // Only add a grouping separator if we have at least
2885 // 2 additional characters to be added, so we don't
2886 // end up with ",###".
2887 if (add
>1 && isGroupingPosition(maxDig
)) {
2888 result
.insert(sub0Start
, group
);
2893 if (fPadPosition
== kPadBeforeSuffix
&& ! padSpec
.isEmpty()) {
2894 result
.append(padSpec
);
2897 appendAffixPattern(result
, fPosSuffixPattern
, fPositiveSuffix
, localized
);
2898 if (fPadPosition
== kPadAfterSuffix
&& ! padSpec
.isEmpty()) {
2899 result
.append(padSpec
);
2901 UBool isDefault
= FALSE
;
2902 if ((fNegSuffixPattern
== fPosSuffixPattern
&& // both null
2903 fNegativeSuffix
== fPositiveSuffix
)
2904 || (fNegSuffixPattern
!= 0 && fPosSuffixPattern
!= 0 &&
2905 *fNegSuffixPattern
== *fPosSuffixPattern
))
2907 if (fNegPrefixPattern
!= NULL
&& fPosPrefixPattern
!= NULL
)
2909 int32_t length
= fPosPrefixPattern
->length();
2910 isDefault
= fNegPrefixPattern
->length() == (length
+2) &&
2911 (*fNegPrefixPattern
)[(int32_t)0] == kQuote
&&
2912 (*fNegPrefixPattern
)[(int32_t)1] == kPatternMinus
&&
2913 fNegPrefixPattern
->compare(2, length
, *fPosPrefixPattern
, 0, length
) == 0;
2916 fNegPrefixPattern
== NULL
&& fPosPrefixPattern
== NULL
)
2918 int32_t length
= fPositivePrefix
.length();
2919 isDefault
= fNegativePrefix
.length() == (length
+1) &&
2920 fNegativePrefix
.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) == 0 &&
2921 fNegativePrefix
.compare(1, length
, fPositivePrefix
, 0, length
) == 0;
2925 break; // Don't output default negative subpattern
2928 result
+= getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
);
2931 result
.append((UChar
)kPatternSeparator
);
2935 appendAffixPattern(result
, fNegSuffixPattern
, fNegativeSuffix
, localized
);
2936 if (fPadPosition
== kPadAfterSuffix
&& ! padSpec
.isEmpty()) {
2937 result
.append(padSpec
);
2945 //------------------------------------------------------------------------------
2948 DecimalFormat::applyPattern(const UnicodeString
& pattern
, UErrorCode
& status
)
2950 UParseError parseError
;
2951 applyPattern(pattern
, FALSE
, parseError
, status
);
2954 //------------------------------------------------------------------------------
2957 DecimalFormat::applyPattern(const UnicodeString
& pattern
,
2958 UParseError
& parseError
,
2961 applyPattern(pattern
, FALSE
, parseError
, status
);
2963 //------------------------------------------------------------------------------
2966 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
, UErrorCode
& status
)
2968 UParseError parseError
;
2969 applyPattern(pattern
, TRUE
,parseError
,status
);
2972 //------------------------------------------------------------------------------
2975 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
,
2976 UParseError
& parseError
,
2979 applyPattern(pattern
, TRUE
,parseError
,status
);
2982 //------------------------------------------------------------------------------
2985 DecimalFormat::applyPattern(const UnicodeString
& pattern
,
2987 UParseError
& parseError
,
2990 if (U_FAILURE(status
))
2994 // Clear error struct
2995 parseError
.offset
= -1;
2996 parseError
.preContext
[0] = parseError
.postContext
[0] = (UChar
)0;
2998 // Set the significant pattern symbols
2999 UChar32 zeroDigit
= kPatternZeroDigit
; // '0'
3000 UChar32 sigDigit
= kPatternSignificantDigit
; // '@'
3001 UnicodeString
groupingSeparator ((UChar
)kPatternGroupingSeparator
);
3002 UnicodeString
decimalSeparator ((UChar
)kPatternDecimalSeparator
);
3003 UnicodeString
percent ((UChar
)kPatternPercent
);
3004 UnicodeString
perMill ((UChar
)kPatternPerMill
);
3005 UnicodeString
digit ((UChar
)kPatternDigit
); // '#'
3006 UnicodeString
separator ((UChar
)kPatternSeparator
);
3007 UnicodeString
exponent ((UChar
)kPatternExponent
);
3008 UnicodeString
plus ((UChar
)kPatternPlus
);
3009 UnicodeString
minus ((UChar
)kPatternMinus
);
3010 UnicodeString
padEscape ((UChar
)kPatternPadEscape
);
3011 // Substitute with the localized symbols if necessary
3013 zeroDigit
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
3014 sigDigit
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0);
3015 groupingSeparator
. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
));
3016 decimalSeparator
. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
));
3017 percent
. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
));
3018 perMill
. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
));
3019 digit
. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
));
3020 separator
. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
));
3021 exponent
. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
));
3022 plus
. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
));
3023 minus
. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
));
3024 padEscape
. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
));
3026 UChar nineDigit
= (UChar
)(zeroDigit
+ 9);
3027 int32_t digitLen
= digit
.length();
3028 int32_t groupSepLen
= groupingSeparator
.length();
3029 int32_t decimalSepLen
= decimalSeparator
.length();
3032 int32_t patLen
= pattern
.length();
3033 // Part 0 is the positive pattern. Part 1, if present, is the negative
3035 for (int32_t part
=0; part
<2 && pos
<patLen
; ++part
) {
3036 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
3037 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is
3038 // between the prefix and suffix, and consists of pattern
3039 // characters. In the prefix and suffix, percent, perMill, and
3040 // currency symbols are recognized and translated.
3041 int32_t subpart
= 1, sub0Start
= 0, sub0Limit
= 0, sub2Limit
= 0;
3043 // It's important that we don't change any fields of this object
3044 // prematurely. We set the following variables for the multiplier,
3045 // grouping, etc., and then only change the actual object fields if
3046 // everything parses correctly. This also lets us register
3047 // the data from part 0 and ignore the part 1, except for the
3048 // prefix and suffix.
3049 UnicodeString prefix
;
3050 UnicodeString suffix
;
3051 int32_t decimalPos
= -1;
3052 int32_t multiplier
= 1;
3053 int32_t digitLeftCount
= 0, zeroDigitCount
= 0, digitRightCount
= 0, sigDigitCount
= 0;
3054 int8_t groupingCount
= -1;
3055 int8_t groupingCount2
= -1;
3056 int32_t padPos
= -1;
3057 UChar32 padChar
= 0;
3058 int32_t roundingPos
= -1;
3059 DigitList roundingInc
;
3060 int8_t expDigits
= -1;
3061 UBool expSignAlways
= FALSE
;
3062 UBool isCurrency
= FALSE
;
3064 // The affix is either the prefix or the suffix.
3065 UnicodeString
* affix
= &prefix
;
3067 int32_t start
= pos
;
3068 UBool isPartDone
= FALSE
;
3071 for (; !isPartDone
&& pos
< patLen
; ) {
3072 // Todo: account for surrogate pairs
3073 ch
= pattern
.char32At(pos
);
3075 case 0: // Pattern proper subpart (between prefix & suffix)
3076 // Process the digits, decimal, and grouping characters. We
3077 // record five pieces of information. We expect the digits
3078 // to occur in the pattern ####00.00####, and we record the
3079 // number of left digits, zero (central) digits, and right
3080 // digits. The position of the last grouping character is
3081 // recorded (should be somewhere within the first two blocks
3082 // of characters), as is the position of the decimal point,
3083 // if any (should be in the zero digits). If there is no
3084 // decimal point, then there should be no right digits.
3085 if (pattern
.compare(pos
, digitLen
, digit
) == 0) {
3086 if (zeroDigitCount
> 0 || sigDigitCount
> 0) {
3091 if (groupingCount
>= 0 && decimalPos
< 0) {
3095 } else if ((ch
>= zeroDigit
&& ch
<= nineDigit
) ||
3097 if (digitRightCount
> 0) {
3099 debug("Unexpected '0'")
3100 status
= U_UNEXPECTED_TOKEN
;
3101 syntaxError(pattern
,pos
,parseError
);
3104 if (ch
== sigDigit
) {
3108 if (ch
!= zeroDigit
&& roundingPos
< 0) {
3109 roundingPos
= digitLeftCount
+ zeroDigitCount
;
3111 if (roundingPos
>= 0) {
3112 roundingInc
.append((char)(ch
- zeroDigit
+ '0'));
3115 if (groupingCount
>= 0 && decimalPos
< 0) {
3118 pos
+= U16_LENGTH(ch
);
3119 } else if (pattern
.compare(pos
, groupSepLen
, groupingSeparator
) == 0) {
3120 if (decimalPos
>= 0) {
3121 // Grouping separator after decimal
3122 debug("Grouping separator after decimal")
3123 status
= U_UNEXPECTED_TOKEN
;
3124 syntaxError(pattern
,pos
,parseError
);
3127 groupingCount2
= groupingCount
;
3130 } else if (pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) == 0) {
3131 if (decimalPos
>= 0) {
3132 // Multiple decimal separators
3133 debug("Multiple decimal separators")
3134 status
= U_MULTIPLE_DECIMAL_SEPARATORS
;
3135 syntaxError(pattern
,pos
,parseError
);
3138 // Intentionally incorporate the digitRightCount,
3139 // even though it is illegal for this to be > 0
3140 // at this point. We check pattern syntax below.
3141 decimalPos
= digitLeftCount
+ zeroDigitCount
+ digitRightCount
;
3142 pos
+= decimalSepLen
;
3144 if (pattern
.compare(pos
, exponent
.length(), exponent
) == 0) {
3145 if (expDigits
>= 0) {
3146 // Multiple exponential symbols
3147 debug("Multiple exponential symbols")
3148 status
= U_MULTIPLE_EXPONENTIAL_SYMBOLS
;
3149 syntaxError(pattern
,pos
,parseError
);
3152 if (groupingCount
>= 0) {
3153 // Grouping separator in exponential pattern
3154 debug("Grouping separator in exponential pattern")
3155 status
= U_MALFORMED_EXPONENTIAL_PATTERN
;
3156 syntaxError(pattern
,pos
,parseError
);
3159 pos
+= exponent
.length();
3160 // Check for positive prefix
3162 && pattern
.compare(pos
, plus
.length(), plus
) == 0) {
3163 expSignAlways
= TRUE
;
3164 pos
+= plus
.length();
3166 // Use lookahead to parse out the exponential part of the
3167 // pattern, then jump into suffix subpart.
3169 while (pos
< patLen
&&
3170 pattern
.char32At(pos
) == zeroDigit
) {
3172 pos
+= U16_LENGTH(zeroDigit
);
3175 // 1. Require at least one mantissa pattern digit
3176 // 2. Disallow "#+ @" in mantissa
3177 // 3. Require at least one exponent pattern digit
3178 if (((digitLeftCount
+ zeroDigitCount
) < 1 &&
3179 (sigDigitCount
+ digitRightCount
) < 1) ||
3180 (sigDigitCount
> 0 && digitLeftCount
> 0) ||
3182 // Malformed exponential pattern
3183 debug("Malformed exponential pattern")
3184 status
= U_MALFORMED_EXPONENTIAL_PATTERN
;
3185 syntaxError(pattern
,pos
,parseError
);
3189 // Transition to suffix subpart
3190 subpart
= 2; // suffix subpart
3196 case 1: // Prefix subpart
3197 case 2: // Suffix subpart
3198 // Process the prefix / suffix characters
3199 // Process unquoted characters seen in prefix or suffix
3202 // Several syntax characters implicitly begins the
3203 // next subpart if we are in the prefix; otherwise
3204 // they are illegal if unquoted.
3205 if (!pattern
.compare(pos
, digitLen
, digit
) ||
3206 !pattern
.compare(pos
, groupSepLen
, groupingSeparator
) ||
3207 !pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) ||
3208 (ch
>= zeroDigit
&& ch
<= nineDigit
) ||
3210 if (subpart
== 1) { // prefix subpart
3211 subpart
= 0; // pattern proper subpart
3212 sub0Start
= pos
; // Reprocess this character
3215 status
= U_UNQUOTED_SPECIAL
;
3216 syntaxError(pattern
,pos
,parseError
);
3219 } else if (ch
== kCurrencySign
) {
3220 affix
->append(kQuote
); // Encode currency
3221 // Use lookahead to determine if the currency sign is
3223 U_ASSERT(U16_LENGTH(kCurrencySign
) == 1);
3224 if ((pos
+1) < pattern
.length() && pattern
[pos
+1] == kCurrencySign
) {
3225 affix
->append(kCurrencySign
);
3226 ++pos
; // Skip over the doubled character
3229 // Fall through to append(ch)
3230 } else if (ch
== kQuote
) {
3231 // A quote outside quotes indicates either the opening
3232 // quote or two quotes, which is a quote literal. That is,
3233 // we have the first quote in 'do' or o''clock.
3234 U_ASSERT(U16_LENGTH(kQuote
) == 1);
3236 if (pos
< pattern
.length() && pattern
[pos
] == kQuote
) {
3237 affix
->append(kQuote
); // Encode quote
3238 // Fall through to append(ch)
3240 subpart
+= 2; // open quote
3243 } else if (pattern
.compare(pos
, separator
.length(), separator
) == 0) {
3244 // Don't allow separators in the prefix, and don't allow
3245 // separators in the second pattern (part == 1).
3246 if (subpart
== 1 || part
== 1) {
3247 // Unexpected separator
3248 debug("Unexpected separator")
3249 status
= U_UNEXPECTED_TOKEN
;
3250 syntaxError(pattern
,pos
,parseError
);
3254 isPartDone
= TRUE
; // Go to next part
3255 pos
+= separator
.length();
3257 } else if (pattern
.compare(pos
, percent
.length(), percent
) == 0) {
3258 // Next handle characters which are appended directly.
3259 if (multiplier
!= 1) {
3260 // Too many percent/perMill characters
3261 debug("Too many percent characters")
3262 status
= U_MULTIPLE_PERCENT_SYMBOLS
;
3263 syntaxError(pattern
,pos
,parseError
);
3266 affix
->append(kQuote
); // Encode percent/perMill
3267 affix
->append(kPatternPercent
); // Use unlocalized pattern char
3269 pos
+= percent
.length();
3271 } else if (pattern
.compare(pos
, perMill
.length(), perMill
) == 0) {
3272 // Next handle characters which are appended directly.
3273 if (multiplier
!= 1) {
3274 // Too many percent/perMill characters
3275 debug("Too many perMill characters")
3276 status
= U_MULTIPLE_PERMILL_SYMBOLS
;
3277 syntaxError(pattern
,pos
,parseError
);
3280 affix
->append(kQuote
); // Encode percent/perMill
3281 affix
->append(kPatternPerMill
); // Use unlocalized pattern char
3283 pos
+= perMill
.length();
3285 } else if (pattern
.compare(pos
, padEscape
.length(), padEscape
) == 0) {
3286 if (padPos
>= 0 || // Multiple pad specifiers
3287 (pos
+1) == pattern
.length()) { // Nothing after padEscape
3288 debug("Multiple pad specifiers")
3289 status
= U_MULTIPLE_PAD_SPECIFIERS
;
3290 syntaxError(pattern
,pos
,parseError
);
3294 pos
+= padEscape
.length();
3295 padChar
= pattern
.char32At(pos
);
3296 pos
+= U16_LENGTH(padChar
);
3298 } else if (pattern
.compare(pos
, minus
.length(), minus
) == 0) {
3299 affix
->append(kQuote
); // Encode minus
3300 affix
->append(kPatternMinus
);
3301 pos
+= minus
.length();
3303 } else if (pattern
.compare(pos
, plus
.length(), plus
) == 0) {
3304 affix
->append(kQuote
); // Encode plus
3305 affix
->append(kPatternPlus
);
3306 pos
+= plus
.length();
3309 // Unquoted, non-special characters fall through to here, as
3310 // well as other code which needs to append something to the
3313 pos
+= U16_LENGTH(ch
);
3315 case 3: // Prefix subpart, in quote
3316 case 4: // Suffix subpart, in quote
3317 // A quote within quotes indicates either the closing
3318 // quote or two quotes, which is a quote literal. That is,
3319 // we have the second quote in 'do' or 'don''t'.
3322 if (pos
< pattern
.length() && pattern
[pos
] == kQuote
) {
3323 affix
->append(kQuote
); // Encode quote
3324 // Fall through to append(ch)
3326 subpart
-= 2; // close quote
3331 pos
+= U16_LENGTH(ch
);
3336 if (sub0Limit
== 0) {
3337 sub0Limit
= pattern
.length();
3340 if (sub2Limit
== 0) {
3341 sub2Limit
= pattern
.length();
3344 /* Handle patterns with no '0' pattern character. These patterns
3345 * are legal, but must be recodified to make sense. "##.###" ->
3346 * "#0.###". ".###" -> ".0##".
3348 * We allow patterns of the form "####" to produce a zeroDigitCount
3349 * of zero (got that?); although this seems like it might make it
3350 * possible for format() to produce empty strings, format() checks
3351 * for this condition and outputs a zero digit in this situation.
3352 * Having a zeroDigitCount of zero yields a minimum integer digits
3353 * of zero, which allows proper round-trip patterns. We don't want
3354 * "#" to become "#0" when toPattern() is called (even though that's
3355 * what it really is, semantically).
3357 if (zeroDigitCount
== 0 && sigDigitCount
== 0 &&
3358 digitLeftCount
> 0 && decimalPos
>= 0) {
3359 // Handle "###.###" and "###." and ".###"
3362 ++n
; // Handle ".###"
3363 digitRightCount
= digitLeftCount
- n
;
3364 digitLeftCount
= n
- 1;
3368 // Do syntax checking on the digits, decimal points, and quotes.
3369 if ((decimalPos
< 0 && digitRightCount
> 0 && sigDigitCount
== 0) ||
3371 (sigDigitCount
> 0 ||
3372 decimalPos
< digitLeftCount
||
3373 decimalPos
> (digitLeftCount
+ zeroDigitCount
))) ||
3374 groupingCount
== 0 || groupingCount2
== 0 ||
3375 (sigDigitCount
> 0 && zeroDigitCount
> 0) ||
3377 { // subpart > 2 == unmatched quote
3378 debug("Syntax error")
3379 status
= U_PATTERN_SYNTAX_ERROR
;
3380 syntaxError(pattern
,pos
,parseError
);
3384 // Make sure pad is at legal position before or after affix.
3386 if (padPos
== start
) {
3387 padPos
= kPadBeforePrefix
;
3388 } else if (padPos
+2 == sub0Start
) {
3389 padPos
= kPadAfterPrefix
;
3390 } else if (padPos
== sub0Limit
) {
3391 padPos
= kPadBeforeSuffix
;
3392 } else if (padPos
+2 == sub2Limit
) {
3393 padPos
= kPadAfterSuffix
;
3395 // Illegal pad position
3396 debug("Illegal pad position")
3397 status
= U_ILLEGAL_PAD_POSITION
;
3398 syntaxError(pattern
,pos
,parseError
);
3404 delete fPosPrefixPattern
;
3405 delete fPosSuffixPattern
;
3406 delete fNegPrefixPattern
;
3407 delete fNegSuffixPattern
;
3408 fPosPrefixPattern
= new UnicodeString(prefix
);
3410 if (fPosPrefixPattern
== 0) {
3411 status
= U_MEMORY_ALLOCATION_ERROR
;
3414 fPosSuffixPattern
= new UnicodeString(suffix
);
3416 if (fPosSuffixPattern
== 0) {
3417 status
= U_MEMORY_ALLOCATION_ERROR
;
3418 delete fPosPrefixPattern
;
3421 fNegPrefixPattern
= 0;
3422 fNegSuffixPattern
= 0;
3424 fUseExponentialNotation
= (expDigits
>= 0);
3425 if (fUseExponentialNotation
) {
3426 fMinExponentDigits
= expDigits
;
3428 fExponentSignAlwaysShown
= expSignAlways
;
3429 fIsCurrencyFormat
= isCurrency
;
3430 int32_t digitTotalCount
= digitLeftCount
+ zeroDigitCount
+ digitRightCount
;
3431 // The effectiveDecimalPos is the position the decimal is at or
3432 // would be at if there is no decimal. Note that if
3433 // decimalPos<0, then digitTotalCount == digitLeftCount +
3435 int32_t effectiveDecimalPos
= decimalPos
>= 0 ? decimalPos
: digitTotalCount
;
3436 UBool isSigDig
= (sigDigitCount
> 0);
3437 setSignificantDigitsUsed(isSigDig
);
3439 setMinimumSignificantDigits(sigDigitCount
);
3440 setMaximumSignificantDigits(sigDigitCount
+ digitRightCount
);
3442 int32_t minInt
= effectiveDecimalPos
- digitLeftCount
;
3443 setMinimumIntegerDigits(minInt
);
3444 setMaximumIntegerDigits(fUseExponentialNotation
3445 ? digitLeftCount
+ getMinimumIntegerDigits()
3446 : kDoubleIntegerDigits
);
3447 setMaximumFractionDigits(decimalPos
>= 0
3448 ? (digitTotalCount
- decimalPos
) : 0);
3449 setMinimumFractionDigits(decimalPos
>= 0
3450 ? (digitLeftCount
+ zeroDigitCount
- decimalPos
) : 0);
3452 setGroupingUsed(groupingCount
> 0);
3453 fGroupingSize
= (groupingCount
> 0) ? groupingCount
: 0;
3454 fGroupingSize2
= (groupingCount2
> 0 && groupingCount2
!= groupingCount
)
3455 ? groupingCount2
: 0;
3456 fMultiplier
= multiplier
;
3457 setDecimalSeparatorAlwaysShown(decimalPos
== 0
3458 || decimalPos
== digitTotalCount
);
3460 fPadPosition
= (EPadPosition
) padPos
;
3461 // To compute the format width, first set up sub0Limit -
3462 // sub0Start. Add in prefix/suffix length later.
3464 // fFormatWidth = prefix.length() + suffix.length() +
3465 // sub0Limit - sub0Start;
3466 fFormatWidth
= sub0Limit
- sub0Start
;
3471 if (roundingPos
>= 0) {
3472 roundingInc
.fDecimalAt
= effectiveDecimalPos
- roundingPos
;
3473 if (fRoundingIncrement
!= NULL
) {
3474 *fRoundingIncrement
= roundingInc
;
3476 fRoundingIncrement
= new DigitList(roundingInc
);
3478 if (fRoundingIncrement
== 0) {
3479 status
= U_MEMORY_ALLOCATION_ERROR
;
3480 delete fPosPrefixPattern
;
3481 delete fPosSuffixPattern
;
3485 fRoundingDouble
= fRoundingIncrement
->getDouble();
3486 fRoundingMode
= kRoundHalfEven
;
3488 setRoundingIncrement(0.0);
3491 fNegPrefixPattern
= new UnicodeString(prefix
);
3493 if (fNegPrefixPattern
== 0) {
3494 status
= U_MEMORY_ALLOCATION_ERROR
;
3497 fNegSuffixPattern
= new UnicodeString(suffix
);
3499 if (fNegSuffixPattern
== 0) {
3500 delete fNegPrefixPattern
;
3501 status
= U_MEMORY_ALLOCATION_ERROR
;
3507 if (pattern
.length() == 0) {
3508 delete fNegPrefixPattern
;
3509 delete fNegSuffixPattern
;
3510 fNegPrefixPattern
= NULL
;
3511 fNegSuffixPattern
= NULL
;
3512 if (fPosPrefixPattern
!= NULL
) {
3513 fPosPrefixPattern
->remove();
3515 fPosPrefixPattern
= new UnicodeString();
3517 if (fPosPrefixPattern
== 0) {
3518 status
= U_MEMORY_ALLOCATION_ERROR
;
3522 if (fPosSuffixPattern
!= NULL
) {
3523 fPosSuffixPattern
->remove();
3525 fPosSuffixPattern
= new UnicodeString();
3527 if (fPosSuffixPattern
== 0) {
3528 delete fPosPrefixPattern
;
3529 status
= U_MEMORY_ALLOCATION_ERROR
;
3534 setMinimumIntegerDigits(0);
3535 setMaximumIntegerDigits(kDoubleIntegerDigits
);
3536 setMinimumFractionDigits(0);
3537 setMaximumFractionDigits(kDoubleFractionDigits
);
3539 fUseExponentialNotation
= FALSE
;
3540 fIsCurrencyFormat
= FALSE
;
3541 setGroupingUsed(FALSE
);
3545 setDecimalSeparatorAlwaysShown(FALSE
);
3547 setRoundingIncrement(0.0);
3550 // If there was no negative pattern, or if the negative pattern is
3551 // identical to the positive pattern, then prepend the minus sign to the
3552 // positive pattern to form the negative pattern.
3553 if (fNegPrefixPattern
== NULL
||
3554 (*fNegPrefixPattern
== *fPosPrefixPattern
3555 && *fNegSuffixPattern
== *fPosSuffixPattern
)) {
3556 _copy_us_ptr(&fNegSuffixPattern
, fPosSuffixPattern
);
3557 if (fNegPrefixPattern
== NULL
) {
3558 fNegPrefixPattern
= new UnicodeString();
3560 if (fNegPrefixPattern
== 0) {
3561 status
= U_MEMORY_ALLOCATION_ERROR
;
3565 fNegPrefixPattern
->remove();
3567 fNegPrefixPattern
->append(kQuote
).append(kPatternMinus
)
3568 .append(*fPosPrefixPattern
);
3572 s
.append("\"").append(pattern
).append("\"->");
3576 if (fFormatWidth
> 0) {
3577 // Finish computing format width (see above)
3578 fFormatWidth
+= fPositivePrefix
.length() + fPositiveSuffix
.length();
3583 * Sets the maximum number of digits allowed in the integer portion of a
3584 * number. This override limits the integer digit count to 309.
3585 * @see NumberFormat#setMaximumIntegerDigits
3587 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue
) {
3588 NumberFormat::setMaximumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
));
3592 * Sets the minimum number of digits allowed in the integer portion of a
3593 * number. This override limits the integer digit count to 309.
3594 * @see NumberFormat#setMinimumIntegerDigits
3596 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue
) {
3597 NumberFormat::setMinimumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
));
3601 * Sets the maximum number of digits allowed in the fraction portion of a
3602 * number. This override limits the fraction digit count to 340.
3603 * @see NumberFormat#setMaximumFractionDigits
3605 void DecimalFormat::setMaximumFractionDigits(int32_t newValue
) {
3606 NumberFormat::setMaximumFractionDigits(_min(newValue
, kDoubleFractionDigits
));
3610 * Sets the minimum number of digits allowed in the fraction portion of a
3611 * number. This override limits the fraction digit count to 340.
3612 * @see NumberFormat#setMinimumFractionDigits
3614 void DecimalFormat::setMinimumFractionDigits(int32_t newValue
) {
3615 NumberFormat::setMinimumFractionDigits(_min(newValue
, kDoubleFractionDigits
));
3618 int32_t DecimalFormat::getMinimumSignificantDigits() const {
3619 return fMinSignificantDigits
;
3622 int32_t DecimalFormat::getMaximumSignificantDigits() const {
3623 return fMaxSignificantDigits
;
3626 void DecimalFormat::setMinimumSignificantDigits(int32_t min
) {
3630 // pin max sig dig to >= min
3631 int32_t max
= _max(fMaxSignificantDigits
, min
);
3632 fMinSignificantDigits
= min
;
3633 fMaxSignificantDigits
= max
;
3636 void DecimalFormat::setMaximumSignificantDigits(int32_t max
) {
3640 // pin min sig dig to 1..max
3641 U_ASSERT(fMinSignificantDigits
>= 1);
3642 int32_t min
= _min(fMinSignificantDigits
, max
);
3643 fMinSignificantDigits
= min
;
3644 fMaxSignificantDigits
= max
;
3647 UBool
DecimalFormat::areSignificantDigitsUsed() const {
3648 return fUseSignificantDigits
;
3651 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits
) {
3652 fUseSignificantDigits
= useSignificantDigits
;
3655 void DecimalFormat::setCurrency(const UChar
* theCurrency
, UErrorCode
& ec
) {
3656 // If we are a currency format, then modify our affixes to
3657 // encode the currency symbol for the given currency in our
3658 // locale, and adjust the decimal digits and rounding for the
3661 // Note: The code is ordered so that this object is *not changed*
3662 // until we are sure we are going to succeed.
3664 // NULL or empty currency is *legal* and indicates no currency.
3665 UBool isCurr
= (theCurrency
&& *theCurrency
);
3667 double rounding
= 0.0;
3669 if (fIsCurrencyFormat
&& isCurr
) {
3670 rounding
= ucurr_getRoundingIncrement(theCurrency
, &ec
);
3671 frac
= ucurr_getDefaultFractionDigits(theCurrency
, &ec
);
3674 NumberFormat::setCurrency(theCurrency
, ec
);
3675 if (U_FAILURE(ec
)) return;
3677 if (fIsCurrencyFormat
) {
3678 // NULL or empty currency is *legal* and indicates no currency.
3680 setRoundingIncrement(rounding
);
3681 setMinimumFractionDigits(frac
);
3682 setMaximumFractionDigits(frac
);
3688 // Deprecated variant with no UErrorCode parameter
3689 void DecimalFormat::setCurrency(const UChar
* theCurrency
) {
3690 UErrorCode ec
= U_ZERO_ERROR
;
3691 setCurrency(theCurrency
, ec
);
3694 void DecimalFormat::getEffectiveCurrency(UChar
* result
, UErrorCode
& /*ec*/) const {
3695 const UChar
* c
= getCurrency();
3697 const UnicodeString
&intl
=
3698 fSymbols
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
3699 c
= intl
.getBuffer(); // ok for intl to go out of scope
3701 u_strncpy(result
, c
, 3);
3706 * Return the number of fraction digits to display, or the total
3707 * number of digits for significant digit formats and exponential
3711 DecimalFormat::precision(UBool isIntegral
) const {
3712 if (areSignificantDigitsUsed()) {
3713 return getMaximumSignificantDigits();
3714 } else if (fUseExponentialNotation
) {
3715 return getMinimumIntegerDigits() + getMaximumFractionDigits();
3717 return isIntegral
? 0 : getMaximumFractionDigits();
3723 #endif /* #if !UCONFIG_NO_FORMATTING */