1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /* Modification History:
9 * Date Name Description
10 * 07/15/99 helena Ported to HPUX 10/11 CC.
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_FORMATTING
18 #include "unicode/currpinf.h"
19 #include "unicode/dcfmtsym.h"
20 #include "unicode/decimfmt.h"
21 #include "unicode/localpointer.h"
22 #include "unicode/ucurr.h"
23 #include "unicode/ustring.h"
24 #include "unicode/measfmt.h"
25 #include "unicode/curramt.h"
26 #include "unicode/strenum.h"
39 #include "unicode/numsys.h"
40 #include "fmtableimp.h"
41 #include "numberformattesttuple.h"
42 #include "unicode/msgfmt.h"
43 #include "number_decimalquantity.h"
44 #include "unicode/numberformatter.h"
46 #if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390)
47 // These should not be macros. If they are,
48 // replace them with std::isnan and std::isinf
52 bool isnan(double x
) {
60 bool isinf(double x
) {
67 using icu::number::impl::DecimalQuantity
;
68 using namespace icu::number
;
70 //#define NUMFMTST_CACHE_DEBUG 1
71 #include "stdio.h" /* for sprintf */
72 // #include "iostream" // for cout
74 //#define NUMFMTST_DEBUG 1
76 static const UChar EUR
[] = {69,85,82,0}; // "EUR"
77 static const UChar ISO_CURRENCY_USD
[] = {0x55, 0x53, 0x44, 0}; // "USD"
80 // *****************************************************************************
81 // class NumberFormatTest
82 // *****************************************************************************
84 #define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
85 #define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
87 void NumberFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
90 TESTCASE_AUTO(TestCurrencySign
);
91 TESTCASE_AUTO(TestCurrency
);
92 TESTCASE_AUTO(TestParse
);
93 TESTCASE_AUTO(TestRounding487
);
94 TESTCASE_AUTO(TestQuotes
);
95 TESTCASE_AUTO(TestExponential
);
96 TESTCASE_AUTO(TestPatterns
);
98 // Upgrade to alphaWorks - liu 5/99
99 TESTCASE_AUTO(TestExponent
);
100 TESTCASE_AUTO(TestScientific
);
101 TESTCASE_AUTO(TestPad
);
102 TESTCASE_AUTO(TestPatterns2
);
103 TESTCASE_AUTO(TestSecondaryGrouping
);
104 TESTCASE_AUTO(TestSurrogateSupport
);
105 TESTCASE_AUTO(TestAPI
);
107 TESTCASE_AUTO(TestCurrencyObject
);
108 TESTCASE_AUTO(TestCurrencyPatterns
);
109 //TESTCASE_AUTO(TestDigitList);
110 TESTCASE_AUTO(TestWhiteSpaceParsing
);
111 TESTCASE_AUTO(TestComplexCurrency
); // This test removed because CLDR no longer uses choice formats in currency symbols.
112 TESTCASE_AUTO(TestRegCurrency
);
113 TESTCASE_AUTO(TestSymbolsWithBadLocale
);
114 TESTCASE_AUTO(TestAdoptDecimalFormatSymbols
);
116 TESTCASE_AUTO(TestScientific2
);
117 TESTCASE_AUTO(TestScientificGrouping
);
118 TESTCASE_AUTO(TestInt64
);
120 TESTCASE_AUTO(TestPerMill
);
121 TESTCASE_AUTO(TestIllegalPatterns
);
122 TESTCASE_AUTO(TestCases
);
124 TESTCASE_AUTO(TestCurrencyNames
);
125 TESTCASE_AUTO(TestCurrencyAmount
);
126 TESTCASE_AUTO(TestCurrencyUnit
);
127 TESTCASE_AUTO(TestCoverage
);
128 //TESTCASE_AUTO(TestLocalizedPatternSymbolCoverage);
129 TESTCASE_AUTO(TestJB3832
);
130 TESTCASE_AUTO(TestHost
);
131 TESTCASE_AUTO(TestHostClone
);
132 TESTCASE_AUTO(TestCurrencyFormat
);
133 TESTCASE_AUTO(TestRounding
);
134 TESTCASE_AUTO(TestNonpositiveMultiplier
);
135 TESTCASE_AUTO(TestNumberingSystems
);
136 TESTCASE_AUTO(TestSpaceParsing
);
137 TESTCASE_AUTO(TestMultiCurrencySign
);
138 TESTCASE_AUTO(TestCurrencyFormatForMixParsing
);
139 //TESTCASE_AUTO(TestMismatchedCurrencyFormatFail);
140 TESTCASE_AUTO(TestDecimalFormatCurrencyParse
);
141 TESTCASE_AUTO(TestCurrencyIsoPluralFormat
);
142 TESTCASE_AUTO(TestCurrencyParsing
);
143 TESTCASE_AUTO(TestParseCurrencyInUCurr
);
144 TESTCASE_AUTO(TestFormatAttributes
);
145 TESTCASE_AUTO(TestFieldPositionIterator
);
146 TESTCASE_AUTO(TestDecimal
);
147 TESTCASE_AUTO(TestCurrencyFractionDigits
);
148 TESTCASE_AUTO(TestExponentParse
);
149 TESTCASE_AUTO(TestExplicitParents
);
150 TESTCASE_AUTO(TestLenientParse
);
151 TESTCASE_AUTO(TestAvailableNumberingSystems
);
152 TESTCASE_AUTO(TestRoundingPattern
);
153 TESTCASE_AUTO(Test9087
);
154 TESTCASE_AUTO(TestFormatFastpaths
);
155 TESTCASE_AUTO(TestFormattableSize
);
156 TESTCASE_AUTO(TestUFormattable
);
157 TESTCASE_AUTO(TestSignificantDigits
);
158 TESTCASE_AUTO(TestShowZero
);
159 TESTCASE_AUTO(TestCompatibleCurrencies
);
160 TESTCASE_AUTO(TestBug9936
);
161 TESTCASE_AUTO(TestParseNegativeWithFaLocale
);
162 TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign
);
163 TESTCASE_AUTO(TestCustomCurrencySignAndSeparator
);
164 TESTCASE_AUTO(TestParseSignsAndMarks
);
165 TESTCASE_AUTO(Test10419RoundingWith0FractionDigits
);
166 TESTCASE_AUTO(Test10468ApplyPattern
);
167 TESTCASE_AUTO(TestRoundingScientific10542
);
168 TESTCASE_AUTO(TestZeroScientific10547
);
169 TESTCASE_AUTO(TestAccountingCurrency
);
170 TESTCASE_AUTO(TestEquality
);
171 TESTCASE_AUTO(TestCurrencyUsage
);
172 TESTCASE_AUTO(TestDoubleLimit11439
);
173 TESTCASE_AUTO(TestGetAffixes
);
174 TESTCASE_AUTO(TestToPatternScientific11648
);
175 TESTCASE_AUTO(TestBenchmark
);
176 TESTCASE_AUTO(TestCtorApplyPatternDifference
);
177 TESTCASE_AUTO(TestFractionalDigitsForCurrency
);
178 TESTCASE_AUTO(TestFormatCurrencyPlural
);
179 TESTCASE_AUTO(Test11868
);
180 TESTCASE_AUTO(Test11739_ParseLongCurrency
);
181 //TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern);
182 TESTCASE_AUTO(Test13737_ParseScientificStrict
);
183 TESTCASE_AUTO(Test10727_RoundingZero
);
184 TESTCASE_AUTO(Test11376_getAndSetPositivePrefix
);
185 TESTCASE_AUTO(Test11475_signRecognition
);
186 TESTCASE_AUTO(Test11640_getAffixes
);
187 TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency
);
188 TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow
);
189 TESTCASE_AUTO(Test13391_chakmaParsing
);
190 TESTCASE_AUTO(Test11735_ExceptionIssue
);
191 TESTCASE_AUTO(Test11035_FormatCurrencyAmount
);
192 TESTCASE_AUTO(Test11318_DoubleConversion
);
193 TESTCASE_AUTO(TestParsePercentRegression
);
194 TESTCASE_AUTO(TestMultiplierWithScale
);
195 TESTCASE_AUTO(TestFastFormatInt32
);
196 TESTCASE_AUTO(Test11646_Equality
);
197 TESTCASE_AUTO(TestParseNaN
);
198 TESTCASE_AUTO(Test11897_LocalizedPatternSeparator
);
199 TESTCASE_AUTO(Test13055_PercentageRounding
);
200 TESTCASE_AUTO(Test11839
);
201 TESTCASE_AUTO(Test10354
);
202 TESTCASE_AUTO(Test11645_ApplyPatternEquality
);
203 TESTCASE_AUTO(Test12567
);
204 TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo
);
205 TESTCASE_AUTO(Test13056_GroupingSize
);
206 TESTCASE_AUTO(Test11025_CurrencyPadding
);
207 TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern
);
208 //TESTCASE_AUTO(Test11649_DecFmtCurrencies);
209 TESTCASE_AUTO(Test13148_ParseGroupingSeparators
);
210 TESTCASE_AUTO(Test12753_PatternDecimalPoint
);
211 TESTCASE_AUTO(Test11647_PatternCurrencySymbols
);
212 TESTCASE_AUTO(Test11913_BigDecimal
);
213 TESTCASE_AUTO(Test11020_RoundingInScientificNotation
);
214 TESTCASE_AUTO(Test11640_TripleCurrencySymbol
);
215 TESTCASE_AUTO(Test13763_FieldPositionIteratorOffset
);
216 TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode
);
217 TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing
);
221 // -------------------------------------
223 // Test API (increase code coverage)
225 NumberFormatTest::TestAPI(void)
228 UErrorCode status
= U_ZERO_ERROR
;
229 NumberFormat
*test
= NumberFormat::createInstance("root", status
);
230 if(U_FAILURE(status
)) {
231 dataerrln("unable to create format object - %s", u_errorName(status
));
234 test
->setMinimumIntegerDigits(10);
235 test
->setMaximumIntegerDigits(1);
237 test
->setMinimumFractionDigits(10);
238 test
->setMaximumFractionDigits(1);
240 UnicodeString result
;
242 Formattable
bla("Paja Patak"); // Donald Duck for non Serbian speakers
243 test
->format(bla
, result
, pos
, status
);
244 if(U_SUCCESS(status
)) {
245 errln("Yuck... Formatted a duck... As a number!");
247 status
= U_ZERO_ERROR
;
252 test
->format(ll
, result
);
253 assertEquals("format int64_t error", u
"2.0", result
);
255 test
->setMinimumIntegerDigits(4);
256 test
->setMinimumFractionDigits(4);
259 test
->format(ll
, result
);
260 assertEquals("format int64_t error", u
"0,012.0000", result
);
263 LocalPointer
<CurrencyAmount
> currAmt(test
->parseCurrency("",ppos
));
264 // old test for (U_FAILURE(status)) was bogus here, method does not set status!
265 if (ppos
.getIndex()) {
266 errln("Parsed empty string as currency");
273 class StubNumberFormat
:public NumberFormat
{
275 StubNumberFormat(){};
276 virtual UnicodeString
& format(double ,UnicodeString
& appendTo
,FieldPosition
& ) const {
279 virtual UnicodeString
& format(int32_t ,UnicodeString
& appendTo
,FieldPosition
& ) const {
280 return appendTo
.append((UChar
)0x0033);
282 virtual UnicodeString
& format(int64_t number
,UnicodeString
& appendTo
,FieldPosition
& pos
) const {
283 return NumberFormat::format(number
, appendTo
, pos
);
285 virtual UnicodeString
& format(const Formattable
& , UnicodeString
& appendTo
, FieldPosition
& , UErrorCode
& ) const {
288 virtual void parse(const UnicodeString
& ,
290 ParsePosition
& ) const {}
291 virtual void parse( const UnicodeString
& ,
293 UErrorCode
& ) const {}
294 virtual UClassID
getDynamicClassID(void) const {
295 static char classID
= 0;
296 return (UClassID
)&classID
;
298 virtual Format
* clone() const {return NULL
;}
302 NumberFormatTest::TestCoverage(void){
303 StubNumberFormat stub
;
304 UnicodeString
agent("agent");
307 if (stub
.format(num
, agent
, pos
) != UnicodeString("agent3")){
308 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
312 void NumberFormatTest::TestLocalizedPatternSymbolCoverage() {
313 IcuTestErrorCode
errorCode(*this, "TestLocalizedPatternSymbolCoverage");
314 // Ticket #12961: DecimalFormat::toLocalizedPattern() is not working as designed.
315 DecimalFormatSymbols
dfs(errorCode
);
316 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
'⁖');
317 dfs
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
'⁘');
318 dfs
.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
, u
'⁙');
319 dfs
.setSymbol(DecimalFormatSymbols::kDigitSymbol
, u
'▰');
320 dfs
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, u
'໐');
321 dfs
.setSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
, u
'⁕');
322 dfs
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
'†');
323 dfs
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
'‡');
324 dfs
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, u
'⁜');
325 dfs
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, u
'‱');
326 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"⁑⁑"); // tests multi-char sequence
327 dfs
.setSymbol(DecimalFormatSymbols::kPadEscapeSymbol
, u
'⁂');
330 UnicodeString
standardPattern(u
"#,##0.05+%;#,##0.05-%");
331 UnicodeString
localizedPattern(u
"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");
333 DecimalFormat
df1("#", new DecimalFormatSymbols(dfs
), errorCode
);
334 df1
.applyPattern(standardPattern
, errorCode
);
335 DecimalFormat
df2("#", new DecimalFormatSymbols(dfs
), errorCode
);
336 df2
.applyLocalizedPattern(localizedPattern
, errorCode
);
337 assertTrue("DecimalFormat instances should be equal", df1
== df2
);
339 assertEquals("toPattern should match on localizedPattern instance",
340 standardPattern
, df2
.toPattern(p2
));
342 assertEquals("toLocalizedPattern should match on standardPattern instance",
343 localizedPattern
, df1
.toLocalizedPattern(lp1
));
347 UnicodeString
standardPattern(u
"* @@@E0‰");
348 UnicodeString
localizedPattern(u
"⁂ ⁕⁕⁕⁑⁑໐‱");
350 DecimalFormat
df1("#", new DecimalFormatSymbols(dfs
), errorCode
);
351 df1
.applyPattern(standardPattern
, errorCode
);
352 DecimalFormat
df2("#", new DecimalFormatSymbols(dfs
), errorCode
);
353 df2
.applyLocalizedPattern(localizedPattern
, errorCode
);
354 assertTrue("DecimalFormat instances should be equal", df1
== df2
);
356 assertEquals("toPattern should match on localizedPattern instance",
357 standardPattern
, df2
.toPattern(p2
));
359 assertEquals("toLocalizedPattern should match on standardPattern instance",
360 localizedPattern
, df1
.toLocalizedPattern(lp1
));
364 // Test various patterns
366 NumberFormatTest::TestPatterns(void)
368 UErrorCode status
= U_ZERO_ERROR
;
369 DecimalFormatSymbols
sym(Locale::getUS(), status
);
370 if (U_FAILURE(status
)) { errcheckln(status
, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status
)); return; }
372 const char* pat
[] = { "#.#", "#.", ".#", "#" };
373 int32_t pat_length
= UPRV_LENGTHOF(pat
);
374 const char* newpat
[] = { "#0.#", "#0.", "#.0", "#" }; // use ICU 61 behavior
375 const char* num
[] = { "0", "0.", ".0", "0" };
376 for (int32_t i
=0; i
<pat_length
; ++i
)
378 status
= U_ZERO_ERROR
;
379 DecimalFormat
fmt(pat
[i
], sym
, status
);
380 if (U_FAILURE(status
)) { errln((UnicodeString
)"FAIL: DecimalFormat constructor failed for " + pat
[i
]); continue; }
381 UnicodeString newp
; fmt
.toPattern(newp
);
382 if (!(newp
== newpat
[i
]))
383 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should transmute to " + newpat
[i
] +
384 "; " + newp
+ " seen instead");
386 UnicodeString s
; (*(NumberFormat
*)&fmt
).format((int32_t)0, s
);
389 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should format zero as " + num
[i
] +
390 "; " + s
+ " seen instead");
391 logln((UnicodeString
)"Min integer digits = " + fmt
.getMinimumIntegerDigits());
397 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
398 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
399 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
403 NumberFormatTest::TestDigitList(void)
405 // API coverage for DigitList
408 list1.fDecimalAt = 1;
410 list2.set((int32_t)1);
411 if (list1 != list2) {
412 errln("digitlist append, operator!= or set failed ");
414 if (!(list1 == list2)) {
415 errln("digitlist append, operator== or set failed ");
420 // -------------------------------------
422 // Test exponential pattern
424 NumberFormatTest::TestExponential(void)
426 UErrorCode status
= U_ZERO_ERROR
;
427 DecimalFormatSymbols
sym(Locale::getUS(), status
);
428 if (U_FAILURE(status
)) { errcheckln(status
, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status
)); return; }
429 const char* pat
[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
430 int32_t pat_length
= UPRV_LENGTHOF(pat
);
432 // The following #if statements allow this test to be built and run on
433 // platforms that do not have standard IEEE numerics. For example,
434 // S/390 doubles have an exponent range of -78 to +75. For the
435 // following #if statements to work, float.h must define
436 // DBL_MAX_10_EXP to be a compile-time constant.
438 // This section may be expanded as needed.
440 #if DBL_MAX_10_EXP > 300
441 double val
[] = { 0.01234, 123456789, 1.23e300
, -3.141592653e-271 };
442 int32_t val_length
= UPRV_LENGTHOF(val
);
443 const char* valFormat
[] =
446 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
448 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
450 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
452 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
456 0.01234, 123460000, 1.23E300
, -3.1416E-271,
457 0.01234, 123460000, 1.23E300
, -3.1416E-271,
458 0.01234, 123456800, 1.23E300
, -3.141593E-271,
459 0.01234, 123500000, 1.23E300
, -3.142E-271,
461 #elif DBL_MAX_10_EXP > 70
462 double val
[] = { 0.01234, 123456789, 1.23e70
, -3.141592653e-71 };
463 int32_t val_length
= UPRV_LENGTHOF(val
);
467 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
469 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
471 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
473 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
477 0.01234, 123460000, 1.23E70
, -3.1416E-71,
478 0.01234, 123460000, 1.23E70
, -3.1416E-71,
479 0.01234, 123456800, 1.23E70
, -3.141593E-71,
480 0.01234, 123500000, 1.23E70
, -3.142E-71,
483 // Don't test double conversion
485 int32_t val_length
= 0;
486 char** valFormat
= 0;
487 double* valParse
= 0;
488 logln("Warning: Skipping double conversion tests");
491 int32_t lval
[] = { 0, -1, 1, 123456789 };
492 int32_t lval_length
= UPRV_LENGTHOF(lval
);
493 const char* lvalFormat
[] =
496 "0E0", "-1E0", "1E0", "1.2346E8",
498 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
500 "0E000", "-1E000", "1E000", "123.4568E006",
502 "0E0", "[1E0]", "1E0", "1.235E8"
504 int32_t lvalParse
[] =
511 int32_t ival
= 0, ilval
= 0;
512 for (int32_t p
=0; p
<pat_length
; ++p
)
514 DecimalFormat
fmt(pat
[p
], sym
, status
);
515 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
516 UnicodeString pattern
;
517 logln((UnicodeString
)"Pattern \"" + pat
[p
] + "\" -toPattern-> \"" +
518 fmt
.toPattern(pattern
) + "\"");
520 for (v
=0; v
<val_length
; ++v
)
522 UnicodeString s
; (*(NumberFormat
*)&fmt
).format(val
[v
], s
);
523 logln((UnicodeString
)" " + val
[v
] + " -format-> " + s
);
524 if (s
!= valFormat
[v
+ival
])
525 errln((UnicodeString
)"FAIL: Expected " + valFormat
[v
+ival
]);
527 ParsePosition
pos(0);
529 fmt
.parse(s
, af
, pos
);
531 UBool useEpsilon
= FALSE
;
532 if (af
.getType() == Formattable::kLong
)
534 else if (af
.getType() == Formattable::kDouble
) {
536 #if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
537 // S/390 will show a failure like this:
538 //| -3.141592652999999e-271 -format-> -3.1416E-271
539 //| -parse-> -3.1416e-271
540 //| FAIL: Expected -3.141599999999999e-271
541 // To compensate, we use an epsilon-based equality
542 // test on S/390 only. We don't want to do this in
543 // general because it's less exacting.
548 errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern
+ " " + s
);
551 if (pos
.getIndex() == s
.length())
553 logln((UnicodeString
)" -parse-> " + a
);
554 // Use epsilon comparison as necessary
556 (uprv_fabs(a
- valParse
[v
+ival
]) / a
> (2*DBL_EPSILON
))) ||
557 (!useEpsilon
&& a
!= valParse
[v
+ival
]))
559 errln((UnicodeString
)"FAIL: Expected " + valParse
[v
+ival
] + " but got " + a
564 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
565 errln((UnicodeString
)" should be (" + s
.length() + " chars) -> " + valParse
[v
+ival
]);
568 for (v
=0; v
<lval_length
; ++v
)
571 (*(NumberFormat
*)&fmt
).format(lval
[v
], s
);
572 logln((UnicodeString
)" " + lval
[v
] + "L -format-> " + s
);
573 if (s
!= lvalFormat
[v
+ilval
])
574 errln((UnicodeString
)"ERROR: Expected " + lvalFormat
[v
+ilval
] + " Got: " + s
);
576 ParsePosition
pos(0);
578 fmt
.parse(s
, af
, pos
);
579 if (af
.getType() == Formattable::kLong
||
580 af
.getType() == Formattable::kInt64
) {
581 UErrorCode status
= U_ZERO_ERROR
;
582 int32_t a
= af
.getLong(status
);
583 if (pos
.getIndex() == s
.length())
585 logln((UnicodeString
)" -parse-> " + a
);
586 if (a
!= lvalParse
[v
+ilval
])
587 errln((UnicodeString
)"FAIL: Expected " + lvalParse
[v
+ilval
] + " but got " + a
);
590 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
593 errln((UnicodeString
)"FAIL: Non-long Formattable returned for " + s
594 + " Double: " + af
.getDouble()
595 + ", Long: " + af
.getLong());
598 ilval
+= lval_length
;
603 NumberFormatTest::TestScientific2() {
605 UErrorCode status
= U_ZERO_ERROR
;
606 DecimalFormat
* fmt
= (DecimalFormat
*)NumberFormat::createCurrencyInstance("en_US", status
);
607 if (U_SUCCESS(status
)) {
609 expect(*fmt
, num
, "$12.34");
610 fmt
->setScientificNotation(TRUE
);
611 expect(*fmt
, num
, "$1.23E1");
612 fmt
->setScientificNotation(FALSE
);
613 expect(*fmt
, num
, "$12.34");
619 NumberFormatTest::TestScientificGrouping() {
621 UErrorCode status
= U_ZERO_ERROR
;
622 DecimalFormat
fmt("##0.00E0",status
);
623 if (assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
624 expect(fmt
, .01234, "12.3E-3");
625 expect(fmt
, .1234, "123E-3");
626 expect(fmt
, 1.234, "1.23E0");
627 expect(fmt
, 12.34, "12.3E0");
628 expect(fmt
, 123.4, "123E0");
629 expect(fmt
, 1234., "1.23E3");
633 /*static void setFromString(DigitList& dl, const char* str) {
635 UBool decimalSet = FALSE;
637 while ((c = *str++)) {
639 dl.fIsPositive = FALSE;
640 } else if (c == '+') {
641 dl.fIsPositive = TRUE;
642 } else if (c == '.') {
643 dl.fDecimalAt = dl.fCount;
650 dl.fDecimalAt = dl.fCount;
655 NumberFormatTest::TestInt64() {
656 UErrorCode status
= U_ZERO_ERROR
;
657 DecimalFormat
fmt("#.#E0",status
);
658 if (U_FAILURE(status
)) {
659 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
662 fmt
.setMaximumFractionDigits(20);
663 if (U_SUCCESS(status
)) {
664 expect(fmt
, (Formattable
)(int64_t)0, "0E0");
665 expect(fmt
, (Formattable
)(int64_t)-1, "-1E0");
666 expect(fmt
, (Formattable
)(int64_t)1, "1E0");
667 expect(fmt
, (Formattable
)(int64_t)2147483647, "2.147483647E9");
668 expect(fmt
, (Formattable
)((int64_t)-2147483647-1), "-2.147483648E9");
669 expect(fmt
, (Formattable
)(int64_t)U_INT64_MAX
, "9.223372036854775807E18");
670 expect(fmt
, (Formattable
)(int64_t)U_INT64_MIN
, "-9.223372036854775808E18");
673 // also test digitlist
674 /* int64_t int64max = U_INT64_MAX;
675 int64_t int64min = U_INT64_MIN;
676 const char* int64maxstr = "9223372036854775807";
677 const char* int64minstr = "-9223372036854775808";
678 UnicodeString fail("fail: ");
680 // test max int64 value
682 setFromString(dl, int64maxstr);
684 if (!dl.fitsIntoInt64(FALSE)) {
685 errln(fail + int64maxstr + " didn't fit");
687 int64_t int64Value = dl.getInt64();
688 if (int64Value != int64max) {
689 errln(fail + int64maxstr);
692 int64Value = dl.getInt64();
693 if (int64Value != int64max) {
694 errln(fail + int64maxstr);
697 // test negative of max int64 value (1 shy of min int64 value)
698 dl.fIsPositive = FALSE;
700 if (!dl.fitsIntoInt64(FALSE)) {
701 errln(fail + "-" + int64maxstr + " didn't fit");
703 int64_t int64Value = dl.getInt64();
704 if (int64Value != -int64max) {
705 errln(fail + "-" + int64maxstr);
708 int64Value = dl.getInt64();
709 if (int64Value != -int64max) {
710 errln(fail + "-" + int64maxstr);
713 // test min int64 value
714 setFromString(dl, int64minstr);
716 if (!dl.fitsIntoInt64(FALSE)) {
717 errln(fail + "-" + int64minstr + " didn't fit");
719 int64_t int64Value = dl.getInt64();
720 if (int64Value != int64min) {
721 errln(fail + int64minstr);
724 int64Value = dl.getInt64();
725 if (int64Value != int64min) {
726 errln(fail + int64minstr);
729 // test negative of min int 64 value (1 more than max int64 value)
730 dl.fIsPositive = TRUE; // won't fit
732 if (dl.fitsIntoInt64(FALSE)) {
733 errln(fail + "-(" + int64minstr + ") didn't fit");
738 // -------------------------------------
740 // Test the handling of quotes
742 NumberFormatTest::TestQuotes(void)
744 UErrorCode status
= U_ZERO_ERROR
;
746 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
747 if (U_FAILURE(status
)) {
748 errcheckln(status
, "Fail to create DecimalFormatSymbols - %s", u_errorName(status
));
752 pat
= new UnicodeString("a'fo''o'b#");
753 DecimalFormat
*fmt
= new DecimalFormat(*pat
, *sym
, status
);
755 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
756 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
757 logln((UnicodeString
)" Format 123 -> " + escape(s
));
758 if (!(s
=="afo'ob123"))
759 errln((UnicodeString
)"FAIL: Expected afo'ob123");
765 pat
= new UnicodeString("a''b#");
766 fmt
= new DecimalFormat(*pat
, *sym
, status
);
767 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
768 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
769 logln((UnicodeString
)" Format 123 -> " + escape(s
));
771 errln((UnicodeString
)"FAIL: Expected a'b123");
778 * Test the handling of the currency symbol in patterns.
781 NumberFormatTest::TestCurrencySign(void)
783 UErrorCode status
= U_ZERO_ERROR
;
784 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
786 UChar currency
= 0x00A4;
787 if (U_FAILURE(status
)) {
788 errcheckln(status
, "Fail to create DecimalFormatSymbols - %s", u_errorName(status
));
792 // "\xA4#,##0.00;-\xA4#,##0.00"
793 pat
.append(currency
).append("#,##0.00;-").
794 append(currency
).append("#,##0.00");
795 DecimalFormat
*fmt
= new DecimalFormat(pat
, *sym
, status
);
796 UnicodeString s
; ((NumberFormat
*)fmt
)->format(1234.56, s
);
798 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
799 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
800 if (s
!= "$1,234.56") dataerrln((UnicodeString
)"FAIL: Expected $1,234.56");
802 ((NumberFormat
*)fmt
)->format(- 1234.56, s
);
803 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
804 if (s
!= "-$1,234.56") dataerrln((UnicodeString
)"FAIL: Expected -$1,234.56");
807 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
808 pat
.append(currency
).append(currency
).
809 append(" #,##0.00;").
810 append(currency
).append(currency
).
811 append(" -#,##0.00");
812 fmt
= new DecimalFormat(pat
, *sym
, status
);
814 ((NumberFormat
*)fmt
)->format(1234.56, s
);
815 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
816 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
817 if (s
!= "USD 1,234.56") dataerrln((UnicodeString
)"FAIL: Expected USD 1,234.56");
819 ((NumberFormat
*)fmt
)->format(-1234.56, s
);
820 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
821 if (s
!= "USD -1,234.56") dataerrln((UnicodeString
)"FAIL: Expected USD -1,234.56");
824 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + u_errorName(status
));
827 // -------------------------------------
829 static UChar
toHexString(int32_t i
) { return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10))); }
832 NumberFormatTest::escape(UnicodeString
& s
)
835 for (int32_t i
=0; i
<s
.length(); ++i
)
837 UChar c
= s
[(int32_t)i
];
838 if (c
<= (UChar
)0x7F) buf
+= c
;
840 buf
+= (UChar
)0x5c; buf
+= (UChar
)0x55;
841 buf
+= toHexString((c
& 0xF000) >> 12);
842 buf
+= toHexString((c
& 0x0F00) >> 8);
843 buf
+= toHexString((c
& 0x00F0) >> 4);
844 buf
+= toHexString(c
& 0x000F);
851 // -------------------------------------
852 static const char* testCases
[][2]= {
853 /* locale ID */ /* expected */
854 {"ca_ES_PREEURO", "\\u20A7\\u00A01.150" },
855 {"de_LU_PREEURO", "1,150\\u00A0F" },
856 {"el_GR_PREEURO", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
857 {"en_BE_PREEURO", "1.150,50\\u00A0BEF" },
858 {"es_ES_PREEURO", "1.150\\u00A0\\u20A7" },
859 {"eu_ES_PREEURO", "\\u20A7\\u00A01.150" },
860 {"gl_ES_PREEURO", "1.150\\u00A0\\u20A7" },
861 {"it_IT_PREEURO", "ITL\\u00A01.150" },
862 {"pt_PT_PREEURO", "1,150$50\\u00A0\\u200B"}, // per cldrbug 7670
863 {"en_US@currency=JPY", "\\u00A51,150"},
864 {"en_US@currency=jpy", "\\u00A51,150"},
865 {"en-US-u-cu-jpy", "\\u00A51,150"}
868 * Test localized currency patterns.
871 NumberFormatTest::TestCurrency(void)
873 UErrorCode status
= U_ZERO_ERROR
;
874 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
875 if (U_FAILURE(status
)) {
876 dataerrln("Error calling NumberFormat::createCurrencyInstance()");
880 UnicodeString s
; currencyFmt
->format(1.50, s
);
881 logln((UnicodeString
)"Un pauvre ici a..........." + s
);
882 if (!(s
==CharsToUnicodeString("1,50\\u00A0$")))
883 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>$ but got " + s
);
887 int len
= uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
888 (void)len
; // Suppress unused variable warning.
889 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
),status
);
890 currencyFmt
->format(1.50, s
);
891 logln((UnicodeString
)"Un pauvre en Allemagne a.." + s
);
892 if (!(s
==CharsToUnicodeString("1,50\\u00A0DM")))
893 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>DM but got " + s
);
896 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
897 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
898 currencyFmt
->format(1.50, s
);
899 logln((UnicodeString
)"Un pauvre en France a....." + s
);
900 if (!(s
==CharsToUnicodeString("1,50\\u00A0F")))
901 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>F");
903 if (U_FAILURE(status
))
904 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
906 for(int i
=0; i
< UPRV_LENGTHOF(testCases
); i
++){
907 status
= U_ZERO_ERROR
;
908 const char *localeID
= testCases
[i
][0];
909 UnicodeString
expected(testCases
[i
][1], -1, US_INV
);
910 expected
= expected
.unescape();
913 uloc_canonicalize(localeID
, loc
, 256, &status
);
914 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
915 if(U_FAILURE(status
)){
916 errln("Could not create currency formatter for locale %s",localeID
);
919 currencyFmt
->format(1150.50, s
);
921 errln(UnicodeString("FAIL: Expected: ")+expected
922 + UnicodeString(" Got: ") + s
923 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
925 if (U_FAILURE(status
)){
926 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
932 // -------------------------------------
935 * Test the Currency object handling, new as of ICU 2.2.
937 void NumberFormatTest::TestCurrencyObject() {
938 UErrorCode ec
= U_ZERO_ERROR
;
940 NumberFormat::createCurrencyInstance(Locale::getUS(), ec
);
943 dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec
));
948 Locale
null("", "", "");
950 expectCurrency(*fmt
, null
, 1234.56, "$1,234.56");
952 expectCurrency(*fmt
, Locale::getFrance(),
953 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
955 expectCurrency(*fmt
, Locale::getJapan(),
956 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
958 expectCurrency(*fmt
, Locale("fr", "CH", ""),
959 1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548 // use ICU 61 behavior
961 expectCurrency(*fmt
, Locale::getUS(),
962 1234.56, "$1,234.56");
965 fmt
= NumberFormat::createCurrencyInstance(Locale::getFrance(), ec
);
968 errln("FAIL: getCurrencyInstance(FRANCE)");
973 expectCurrency(*fmt
, null
, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
975 expectCurrency(*fmt
, Locale::getJapan(),
976 1234.56, CharsToUnicodeString("1 235 JPY")); // Yen
978 expectCurrency(*fmt
, Locale("fr", "CH", ""),
979 1234.56, "1 234,56 CHF"); // no more 0.05 rounding here, see cldrbug 5548
981 expectCurrency(*fmt
, Locale::getUS(),
982 1234.56, "1 234,56 $US");
984 expectCurrency(*fmt
, Locale::getFrance(),
985 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
990 // -------------------------------------
993 * Do rudimentary testing of parsing.
996 NumberFormatTest::TestParse(void)
998 UErrorCode status
= U_ZERO_ERROR
;
999 UnicodeString
arg("0");
1000 DecimalFormat
* format
= new DecimalFormat("00", status
);
1002 Formattable n
; format
->parse(arg
, n
, status
);
1003 logln((UnicodeString
)"parse(" + arg
+ ") = " + n
.getLong());
1004 if (n
.getType() != Formattable::kLong
||
1005 n
.getLong() != 0) errln((UnicodeString
)"FAIL: Expected 0");
1007 if (U_FAILURE(status
)) errcheckln(status
, (UnicodeString
)"FAIL: Status " + u_errorName(status
));
1009 //catch(Exception e) {
1010 // errln((UnicodeString)"Exception caught: " + e);
1014 // -------------------------------------
1016 static const char *lenientAffixTestCases
[] = {
1023 static const char *lenientMinusTestCases
[] = {
1029 static const char *lenientCurrencyTestCases
[] = {
1040 // changed from () to - per cldrbug 5674
1041 static const char *lenientNegativeCurrencyTestCases
[] = {
1049 "-$ 1\\u00A0000.00",
1053 static const char *lenientPercentTestCases
[] = {
1062 static const char *lenientNegativePercentTestCases
[] = {
1074 static const char *strictFailureTestCases
[] = {
1081 * Test lenient parsing.
1084 NumberFormatTest::TestLenientParse(void)
1086 UErrorCode status
= U_ZERO_ERROR
;
1087 DecimalFormat
*format
= new DecimalFormat("(#,##0)", status
);
1090 if (format
== NULL
|| U_FAILURE(status
)) {
1091 dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status
));
1093 format
->setLenient(TRUE
);
1094 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientAffixTestCases
); t
+= 1) {
1095 UnicodeString testCase
= ctou(lenientAffixTestCases
[t
]);
1097 format
->parse(testCase
, n
, status
);
1098 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1100 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
||
1102 dataerrln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientAffixTestCases
[t
]
1103 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1104 status
= U_ZERO_ERROR
;
1110 Locale
en_US("en_US");
1111 Locale
sv_SE("sv_SE");
1113 NumberFormat
*mFormat
= NumberFormat::createInstance(sv_SE
, UNUM_DECIMAL
, status
);
1115 if (mFormat
== NULL
|| U_FAILURE(status
)) {
1116 dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status
));
1118 mFormat
->setLenient(TRUE
);
1119 for (int32_t t
= 0; t
< UPRV_LENGTHOF(lenientMinusTestCases
); t
+= 1) {
1120 UnicodeString testCase
= ctou(lenientMinusTestCases
[t
]);
1122 mFormat
->parse(testCase
, n
, status
);
1123 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1125 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
|| n
.getLong() != -5) {
1126 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientMinusTestCases
[t
]
1127 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1128 status
= U_ZERO_ERROR
;
1134 mFormat
= NumberFormat::createInstance(en_US
, UNUM_DECIMAL
, status
);
1136 if (mFormat
== NULL
|| U_FAILURE(status
)) {
1137 dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status
));
1139 mFormat
->setLenient(TRUE
);
1140 for (int32_t t
= 0; t
< UPRV_LENGTHOF(lenientMinusTestCases
); t
+= 1) {
1141 UnicodeString testCase
= ctou(lenientMinusTestCases
[t
]);
1143 mFormat
->parse(testCase
, n
, status
);
1144 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1146 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
|| n
.getLong() != -5) {
1147 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientMinusTestCases
[t
]
1148 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1149 status
= U_ZERO_ERROR
;
1155 NumberFormat
*cFormat
= NumberFormat::createInstance(en_US
, UNUM_CURRENCY
, status
);
1157 if (cFormat
== NULL
|| U_FAILURE(status
)) {
1158 dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status
));
1160 cFormat
->setLenient(TRUE
);
1161 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientCurrencyTestCases
); t
+= 1) {
1162 UnicodeString testCase
= ctou(lenientCurrencyTestCases
[t
]);
1164 cFormat
->parse(testCase
, n
, status
);
1165 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1167 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1168 n
.getLong() != 1000) {
1169 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientCurrencyTestCases
[t
]
1170 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1171 status
= U_ZERO_ERROR
;
1175 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientNegativeCurrencyTestCases
); t
+= 1) {
1176 UnicodeString testCase
= ctou(lenientNegativeCurrencyTestCases
[t
]);
1178 cFormat
->parse(testCase
, n
, status
);
1179 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1181 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1182 n
.getLong() != -1000) {
1183 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientNegativeCurrencyTestCases
[t
]
1184 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1185 status
= U_ZERO_ERROR
;
1192 NumberFormat
*pFormat
= NumberFormat::createPercentInstance(en_US
, status
);
1194 if (pFormat
== NULL
|| U_FAILURE(status
)) {
1195 dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status
));
1197 pFormat
->setLenient(TRUE
);
1198 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientPercentTestCases
); t
+= 1) {
1199 UnicodeString testCase
= ctou(lenientPercentTestCases
[t
]);
1201 pFormat
->parse(testCase
, n
, status
);
1202 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getDouble());
1204 if (U_FAILURE(status
) ||n
.getType() != Formattable::kDouble
||
1205 n
.getDouble() != 0.25) {
1206 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientPercentTestCases
[t
]
1207 + (UnicodeString
) "\"; error code = " + u_errorName(status
)
1208 + "; got: " + n
.getDouble(status
));
1209 status
= U_ZERO_ERROR
;
1213 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientNegativePercentTestCases
); t
+= 1) {
1214 UnicodeString testCase
= ctou(lenientNegativePercentTestCases
[t
]);
1216 pFormat
->parse(testCase
, n
, status
);
1217 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getDouble());
1219 if (U_FAILURE(status
) ||n
.getType() != Formattable::kDouble
||
1220 n
.getDouble() != -0.25) {
1221 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientNegativePercentTestCases
[t
]
1222 + (UnicodeString
) "\"; error code = " + u_errorName(status
)
1223 + "; got: " + n
.getDouble(status
));
1224 status
= U_ZERO_ERROR
;
1231 // Test cases that should fail with a strict parse and pass with a
1233 NumberFormat
*nFormat
= NumberFormat::createInstance(en_US
, status
);
1235 if (nFormat
== NULL
|| U_FAILURE(status
)) {
1236 dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status
));
1238 // first, make sure that they fail with a strict parse
1239 for (int32_t t
= 0; t
< UPRV_LENGTHOF(strictFailureTestCases
); t
+= 1) {
1240 UnicodeString testCase
= ctou(strictFailureTestCases
[t
]);
1242 nFormat
->parse(testCase
, n
, status
);
1243 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1245 if (! U_FAILURE(status
)) {
1246 errln((UnicodeString
)"Strict Parse succeeded for \"" + (UnicodeString
) strictFailureTestCases
[t
]
1247 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1250 status
= U_ZERO_ERROR
;
1253 // then, make sure that they pass with a lenient parse
1254 nFormat
->setLenient(TRUE
);
1255 for (int32_t t
= 0; t
< UPRV_LENGTHOF(strictFailureTestCases
); t
+= 1) {
1256 UnicodeString testCase
= ctou(strictFailureTestCases
[t
]);
1258 nFormat
->parse(testCase
, n
, status
);
1259 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1261 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1262 n
.getLong() != 1000) {
1263 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) strictFailureTestCases
[t
]
1264 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1265 status
= U_ZERO_ERROR
;
1273 // -------------------------------------
1276 * Test proper rounding by the format method.
1279 NumberFormatTest::TestRounding487(void)
1281 UErrorCode status
= U_ZERO_ERROR
;
1282 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1283 if (U_FAILURE(status
)) {
1284 dataerrln("Error calling NumberFormat::createInstance()");
1288 roundingTest(*nf
, 0.00159999, 4, "0.0016");
1289 roundingTest(*nf
, 0.00995, 4, "0.01");
1291 roundingTest(*nf
, 12.3995, 3, "12.4");
1293 roundingTest(*nf
, 12.4999, 0, "12");
1294 roundingTest(*nf
, - 19.5, 0, "-20");
1296 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
1300 * Test the functioning of the secondary grouping value.
1302 void NumberFormatTest::TestSecondaryGrouping(void) {
1303 UErrorCode status
= U_ZERO_ERROR
;
1304 DecimalFormatSymbols
US(Locale::getUS(), status
);
1305 CHECK(status
, "DecimalFormatSymbols ct");
1307 DecimalFormat
f("#,##,###", US
, status
);
1308 CHECK(status
, "DecimalFormat ct");
1310 expect2(f
, (int32_t)123456789L, "12,34,56,789");
1311 expectPat(f
, "#,##,###"); // use ICU 61 behavior
1312 f
.applyPattern("#,###", status
);
1313 CHECK(status
, "applyPattern");
1315 f
.setSecondaryGroupingSize(4);
1316 expect2(f
, (int32_t)123456789L, "12,3456,789");
1317 expectPat(f
, "#,####,###"); // use ICU 61 behavior
1318 NumberFormat
*g
= NumberFormat::createInstance(Locale("hi", "IN"), status
);
1319 CHECK_DATA(status
, "createInstance(hi_IN)");
1322 int32_t l
= (int32_t)1876543210L;
1325 // expect "1,87,65,43,210", but with Hindi digits
1328 if (out
.length() != 14) {
1331 for (int32_t i
=0; i
<out
.length(); ++i
) {
1332 UBool expectGroup
= FALSE
;
1341 // Later -- fix this to get the actual grouping
1342 // character from the resource bundle.
1343 UBool isGroup
= (out
.charAt(i
) == 0x002C);
1344 if (isGroup
!= expectGroup
) {
1351 errln((UnicodeString
)"FAIL Expected " + l
+
1352 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1353 escape(out
) + "\"");
1355 logln((UnicodeString
)"Ok " + l
+
1357 escape(out
) + "\"");
1361 void NumberFormatTest::TestWhiteSpaceParsing(void) {
1362 UErrorCode ec
= U_ZERO_ERROR
;
1363 DecimalFormatSymbols
US(Locale::getUS(), ec
);
1364 DecimalFormat
fmt("a b#0c ", US
, ec
);
1365 if (U_FAILURE(ec
)) {
1366 errcheckln(ec
, "FAIL: Constructor - %s", u_errorName(ec
));
1369 // From ICU 62, flexible whitespace needs lenient mode
1370 fmt
.setLenient(TRUE
);
1372 expect(fmt
, "a b1234c ", n
);
1373 expect(fmt
, "a b1234c ", n
);
1377 * Test currencies whose display name is a ChoiceFormat.
1379 void NumberFormatTest::TestComplexCurrency() {
1381 // UErrorCode ec = U_ZERO_ERROR;
1382 // Locale loc("kn", "IN", "");
1383 // NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
1384 // if (U_SUCCESS(ec)) {
1385 // expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
1386 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
1387 // expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
1388 // expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
1389 // expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
1390 // expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
1391 // expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
1393 // errln("FAIL: getCurrencyInstance(kn_IN)");
1399 // -------------------------------------
1402 NumberFormatTest::roundingTest(NumberFormat
& nf
, double x
, int32_t maxFractionDigits
, const char* expected
)
1404 nf
.setMaximumFractionDigits(maxFractionDigits
);
1405 UnicodeString out
; nf
.format(x
, out
);
1406 logln((UnicodeString
)"" + x
+ " formats with " + maxFractionDigits
+ " fractional digits to " + out
);
1407 if (!(out
==expected
)) errln((UnicodeString
)"FAIL: Expected " + expected
);
1411 * Upgrade to alphaWorks
1413 void NumberFormatTest::TestExponent(void) {
1414 UErrorCode status
= U_ZERO_ERROR
;
1415 DecimalFormatSymbols
US(Locale::getUS(), status
);
1416 CHECK(status
, "DecimalFormatSymbols constructor");
1417 DecimalFormat
fmt1(UnicodeString("0.###E0"), US
, status
);
1418 CHECK(status
, "DecimalFormat(0.###E0)");
1419 DecimalFormat
fmt2(UnicodeString("0.###E+0"), US
, status
);
1420 CHECK(status
, "DecimalFormat(0.###E+0)");
1422 expect2(fmt1
, n
, "1.234E3");
1423 expect2(fmt2
, n
, "1.234E+3");
1424 expect(fmt1
, "1.234E+3", n
); // Either format should parse "E+3"
1428 * Upgrade to alphaWorks
1430 void NumberFormatTest::TestScientific(void) {
1431 UErrorCode status
= U_ZERO_ERROR
;
1432 DecimalFormatSymbols
US(Locale::getUS(), status
);
1433 CHECK(status
, "DecimalFormatSymbols constructor");
1435 // Test pattern round-trip
1436 const char* PAT
[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1437 "0.###E0;[0.###E0]" };
1438 int32_t PAT_length
= UPRV_LENGTHOF(PAT
);
1439 int32_t DIGITS
[] = {
1440 // min int, max int, min frac, max frac
1441 0, 1, 0, 0, // "#E0" // expect ICU 61 behavior
1442 1, 1, 0, 4, // "0.####E0"
1443 2, 2, 3, 3, // "00.000E00"
1444 1, 3, 0, 4, // "##0.####E000"
1445 1, 1, 0, 3, // "0.###E0;[0.###E0]"
1447 for (int32_t i
=0; i
<PAT_length
; ++i
) {
1448 UnicodeString
pat(PAT
[i
]);
1449 DecimalFormat
df(pat
, US
, status
);
1450 CHECK(status
, "DecimalFormat constructor");
1454 logln(UnicodeString("Ok Pattern rt \"") +
1458 errln(UnicodeString("FAIL Pattern rt \"") +
1462 // Make sure digit counts match what we expect
1463 if (df
.getMinimumIntegerDigits() != DIGITS
[4*i
] ||
1464 df
.getMaximumIntegerDigits() != DIGITS
[4*i
+1] ||
1465 df
.getMinimumFractionDigits() != DIGITS
[4*i
+2] ||
1466 df
.getMaximumFractionDigits() != DIGITS
[4*i
+3]) {
1467 errln(UnicodeString("FAIL \"" + pat
+
1468 "\" min/max int; min/max frac = ") +
1469 df
.getMinimumIntegerDigits() + "/" +
1470 df
.getMaximumIntegerDigits() + ";" +
1471 df
.getMinimumFractionDigits() + "/" +
1472 df
.getMaximumFractionDigits() + ", expect " +
1474 DIGITS
[4*i
+1] + ";" +
1475 DIGITS
[4*i
+2] + "/" +
1481 // Test the constructor for default locale. We have to
1482 // manually set the default locale, as there is no
1483 // guarantee that the default locale has the same
1484 // scientific format.
1485 Locale def
= Locale::getDefault();
1486 Locale::setDefault(Locale::getUS(), status
);
1487 expect2(NumberFormat::createScientificInstance(status
),
1489 "1.2345678901E4", status
);
1490 Locale::setDefault(def
, status
);
1492 expect2(new DecimalFormat("#E0", US
, status
),
1494 "1.2345E4", status
);
1495 expect(new DecimalFormat("0E0", US
, status
),
1498 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status
),
1500 "1.2345678901E4", status
);
1501 expect(new DecimalFormat("##0.###E0", US
, status
),
1504 expect(new DecimalFormat("##0.###E0", US
, status
),
1507 expect2(new DecimalFormat("##0.####E0", US
, status
),
1509 "12.345E3", status
);
1510 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status
),
1512 "1,2345678901E4", status
);
1513 expect(new DecimalFormat("##0.####E0", US
, status
),
1515 "789.12E-9", status
);
1516 expect2(new DecimalFormat("##0.####E0", US
, status
),
1519 expect(new DecimalFormat(".###E0", US
, status
),
1522 expect2(new DecimalFormat(".###E0", US
, status
),
1526 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1527 new DecimalFormat("##E0", US),
1528 new DecimalFormat("####E0", US),
1529 new DecimalFormat("0E0", US),
1530 new DecimalFormat("00E0", US),
1531 new DecimalFormat("000E0", US),
1534 new String[] { "4.5678E7",
1543 ! Unroll this test into individual tests below...
1546 expect2(new DecimalFormat("#E0", US
, status
),
1547 (int32_t) 45678000, "4.5678E7", status
);
1548 expect2(new DecimalFormat("##E0", US
, status
),
1549 (int32_t) 45678000, "45.678E6", status
);
1550 expect2(new DecimalFormat("####E0", US
, status
),
1551 (int32_t) 45678000, "4567.8E4", status
);
1552 expect(new DecimalFormat("0E0", US
, status
),
1553 (int32_t) 45678000, "5E7", status
);
1554 expect(new DecimalFormat("00E0", US
, status
),
1555 (int32_t) 45678000, "46E6", status
);
1556 expect(new DecimalFormat("000E0", US
, status
),
1557 (int32_t) 45678000, "457E5", status
);
1559 expect(new DecimalFormat("###E0", US, status),
1560 new Object[] { new Double(0.0000123), "12.3E-6",
1561 new Double(0.000123), "123E-6",
1562 new Double(0.00123), "1.23E-3",
1563 new Double(0.0123), "12.3E-3",
1564 new Double(0.123), "123E-3",
1565 new Double(1.23), "1.23E0",
1566 new Double(12.3), "12.3E0",
1567 new Double(123), "123E0",
1568 new Double(1230), "1.23E3",
1571 ! Unroll this test into individual tests below...
1574 expect2(new DecimalFormat("###E0", US
, status
),
1575 0.0000123, "12.3E-6", status
);
1576 expect2(new DecimalFormat("###E0", US
, status
),
1577 0.000123, "123E-6", status
);
1578 expect2(new DecimalFormat("###E0", US
, status
),
1579 0.00123, "1.23E-3", status
);
1580 expect2(new DecimalFormat("###E0", US
, status
),
1581 0.0123, "12.3E-3", status
);
1582 expect2(new DecimalFormat("###E0", US
, status
),
1583 0.123, "123E-3", status
);
1584 expect2(new DecimalFormat("###E0", US
, status
),
1585 1.23, "1.23E0", status
);
1586 expect2(new DecimalFormat("###E0", US
, status
),
1587 12.3, "12.3E0", status
);
1588 expect2(new DecimalFormat("###E0", US
, status
),
1589 123.0, "123E0", status
);
1590 expect2(new DecimalFormat("###E0", US
, status
),
1591 1230.0, "1.23E3", status
);
1593 expect(new DecimalFormat("0.#E+00", US, status),
1594 new Object[] { new Double(0.00012), "1.2E-04",
1595 new Long(12000), "1.2E+04",
1598 ! Unroll this test into individual tests below...
1601 expect2(new DecimalFormat("0.#E+00", US
, status
),
1602 0.00012, "1.2E-04", status
);
1603 expect2(new DecimalFormat("0.#E+00", US
, status
),
1604 (int32_t) 12000, "1.2E+04", status
);
1608 * Upgrade to alphaWorks
1610 void NumberFormatTest::TestPad(void) {
1611 UErrorCode status
= U_ZERO_ERROR
;
1612 DecimalFormatSymbols
US(Locale::getUS(), status
);
1613 CHECK(status
, "DecimalFormatSymbols constructor");
1615 expect2(new DecimalFormat("*^##.##", US
, status
),
1616 int32_t(0), "^^^^0", status
);
1617 expect2(new DecimalFormat("*^##.##", US
, status
),
1618 -1.3, "^-1.3", status
);
1619 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1620 int32_t(0), "0.0E0______ g-m/s^2", status
);
1621 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1622 1.0/3, "333.333E-3_ g-m/s^2", status
);
1623 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1624 int32_t(0), "0.0______ g-m/s^2", status
);
1625 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1626 1.0/3, "0.33333__ g-m/s^2", status
);
1628 // Test padding before a sign
1629 const char *formatStr
= "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1630 expect2(new DecimalFormat(formatStr
, US
, status
),
1631 int32_t(-10), "xxxxxxxxxx(10.0)", status
);
1632 expect2(new DecimalFormat(formatStr
, US
, status
),
1633 int32_t(-1000),"xxxxxxx(1,000.0)", status
);
1634 expect2(new DecimalFormat(formatStr
, US
, status
),
1635 int32_t(-1000000),"xxx(1,000,000.0)", status
);
1636 expect2(new DecimalFormat(formatStr
, US
, status
),
1637 -100.37, "xxxxxxxx(100.37)", status
);
1638 expect2(new DecimalFormat(formatStr
, US
, status
),
1639 -10456.37, "xxxxx(10,456.37)", status
);
1640 expect2(new DecimalFormat(formatStr
, US
, status
),
1641 -1120456.37, "xx(1,120,456.37)", status
);
1642 expect2(new DecimalFormat(formatStr
, US
, status
),
1643 -112045600.37, "(112,045,600.37)", status
);
1644 expect2(new DecimalFormat(formatStr
, US
, status
),
1645 -1252045600.37,"(1,252,045,600.37)", status
);
1647 expect2(new DecimalFormat(formatStr
, US
, status
),
1648 int32_t(10), "xxxxxxxxxxxx10.0", status
);
1649 expect2(new DecimalFormat(formatStr
, US
, status
),
1650 int32_t(1000),"xxxxxxxxx1,000.0", status
);
1651 expect2(new DecimalFormat(formatStr
, US
, status
),
1652 int32_t(1000000),"xxxxx1,000,000.0", status
);
1653 expect2(new DecimalFormat(formatStr
, US
, status
),
1654 100.37, "xxxxxxxxxx100.37", status
);
1655 expect2(new DecimalFormat(formatStr
, US
, status
),
1656 10456.37, "xxxxxxx10,456.37", status
);
1657 expect2(new DecimalFormat(formatStr
, US
, status
),
1658 1120456.37, "xxxx1,120,456.37", status
);
1659 expect2(new DecimalFormat(formatStr
, US
, status
),
1660 112045600.37, "xx112,045,600.37", status
);
1661 expect2(new DecimalFormat(formatStr
, US
, status
),
1662 10252045600.37,"10,252,045,600.37", status
);
1665 // Test padding between a sign and a number
1666 const char *formatStr2
= "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1667 expect2(new DecimalFormat(formatStr2
, US
, status
),
1668 int32_t(-10), "(10.0xxxxxxxxxx)", status
);
1669 expect2(new DecimalFormat(formatStr2
, US
, status
),
1670 int32_t(-1000),"(1,000.0xxxxxxx)", status
);
1671 expect2(new DecimalFormat(formatStr2
, US
, status
),
1672 int32_t(-1000000),"(1,000,000.0xxx)", status
);
1673 expect2(new DecimalFormat(formatStr2
, US
, status
),
1674 -100.37, "(100.37xxxxxxxx)", status
);
1675 expect2(new DecimalFormat(formatStr2
, US
, status
),
1676 -10456.37, "(10,456.37xxxxx)", status
);
1677 expect2(new DecimalFormat(formatStr2
, US
, status
),
1678 -1120456.37, "(1,120,456.37xx)", status
);
1679 expect2(new DecimalFormat(formatStr2
, US
, status
),
1680 -112045600.37, "(112,045,600.37)", status
);
1681 expect2(new DecimalFormat(formatStr2
, US
, status
),
1682 -1252045600.37,"(1,252,045,600.37)", status
);
1684 expect2(new DecimalFormat(formatStr2
, US
, status
),
1685 int32_t(10), "10.0xxxxxxxxxxxx", status
);
1686 expect2(new DecimalFormat(formatStr2
, US
, status
),
1687 int32_t(1000),"1,000.0xxxxxxxxx", status
);
1688 expect2(new DecimalFormat(formatStr2
, US
, status
),
1689 int32_t(1000000),"1,000,000.0xxxxx", status
);
1690 expect2(new DecimalFormat(formatStr2
, US
, status
),
1691 100.37, "100.37xxxxxxxxxx", status
);
1692 expect2(new DecimalFormat(formatStr2
, US
, status
),
1693 10456.37, "10,456.37xxxxxxx", status
);
1694 expect2(new DecimalFormat(formatStr2
, US
, status
),
1695 1120456.37, "1,120,456.37xxxx", status
);
1696 expect2(new DecimalFormat(formatStr2
, US
, status
),
1697 112045600.37, "112,045,600.37xx", status
);
1698 expect2(new DecimalFormat(formatStr2
, US
, status
),
1699 10252045600.37,"10,252,045,600.37", status
);
1701 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1702 DecimalFormat
fmt("#", US
, status
);
1703 CHECK(status
, "DecimalFormat constructor");
1704 UnicodeString
padString("P");
1705 fmt
.setPadCharacter(padString
);
1706 expectPad(fmt
, "*P##.##", DecimalFormat::kPadBeforePrefix
, 5, padString
);
1707 fmt
.setPadCharacter((UnicodeString
)"^");
1708 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, (UnicodeString
)"^");
1709 //commented untill implementation is complete
1710 /* fmt.setPadCharacter((UnicodeString)"^^^");
1711 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1713 padString.append((UChar)0x0061);
1714 padString.append((UChar)0x0302);
1715 fmt.setPadCharacter(padString);
1716 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1717 UnicodeString pattern(patternChars);
1718 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1724 * Upgrade to alphaWorks
1726 void NumberFormatTest::TestPatterns2(void) {
1727 UErrorCode status
= U_ZERO_ERROR
;
1728 DecimalFormatSymbols
US(Locale::getUS(), status
);
1729 CHECK(status
, "DecimalFormatSymbols constructor");
1731 DecimalFormat
fmt("#", US
, status
);
1732 CHECK(status
, "DecimalFormat constructor");
1734 UChar hat
= 0x005E; /*^*/
1736 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, hat
);
1737 expectPad(fmt
, "$*^#", DecimalFormat::kPadAfterPrefix
, 2, hat
);
1738 expectPad(fmt
, "#*^", DecimalFormat::kPadBeforeSuffix
, 1, hat
);
1739 expectPad(fmt
, "#$*^", DecimalFormat::kPadAfterSuffix
, 2, hat
);
1740 expectPad(fmt
, "$*^$#", ILLEGAL
);
1741 expectPad(fmt
, "#$*^$", ILLEGAL
);
1742 expectPad(fmt
, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix
,
1743 12, (UChar
)0x0078 /*x*/);
1744 expectPad(fmt
, "''#0*x", DecimalFormat::kPadBeforeSuffix
,
1745 3, (UChar
)0x0078 /*x*/);
1746 expectPad(fmt
, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix
,
1747 10, (UChar
)0x0061 /*a*/);
1749 fmt
.applyPattern("AA#,##0.00ZZ", status
);
1750 CHECK(status
, "applyPattern");
1751 fmt
.setPadCharacter(hat
);
1753 fmt
.setFormatWidth(10);
1755 fmt
.setPadPosition(DecimalFormat::kPadBeforePrefix
);
1756 expectPat(fmt
, "*^AA#,##0.00ZZ");
1758 fmt
.setPadPosition(DecimalFormat::kPadBeforeSuffix
);
1759 expectPat(fmt
, "AA#,##0.00*^ZZ");
1761 fmt
.setPadPosition(DecimalFormat::kPadAfterSuffix
);
1762 expectPat(fmt
, "AA#,##0.00ZZ*^");
1765 UnicodeString
exp("AA*^#,##0.00ZZ", "");
1766 fmt
.setFormatWidth(12);
1767 fmt
.setPadPosition(DecimalFormat::kPadAfterPrefix
);
1768 expectPat(fmt
, exp
);
1770 fmt
.setFormatWidth(13);
1772 expectPat(fmt
, "AA*^##,##0.00ZZ");
1774 fmt
.setFormatWidth(14);
1776 expectPat(fmt
, "AA*^###,##0.00ZZ");
1778 fmt
.setFormatWidth(15);
1780 expectPat(fmt
, "AA*^####,##0.00ZZ"); // This is the interesting case
1782 fmt
.setFormatWidth(16);
1783 // 12 34567890123456
1784 expectPat(fmt
, "AA*^#,###,##0.00ZZ"); // use ICU 61 behavior
1787 void NumberFormatTest::TestSurrogateSupport(void) {
1788 UErrorCode status
= U_ZERO_ERROR
;
1789 DecimalFormatSymbols
custom(Locale::getUS(), status
);
1790 CHECK(status
, "DecimalFormatSymbols constructor");
1792 custom
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, "decimal");
1793 custom
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, "plus");
1794 custom
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, " minus ");
1795 custom
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, "exponent");
1797 UnicodeString
patternStr("*\\U00010000##.##", "");
1798 patternStr
= patternStr
.unescape();
1799 UnicodeString
expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1800 expStr
= expStr
.unescape();
1801 expect2(new DecimalFormat(patternStr
, custom
, status
),
1802 int32_t(0), expStr
, status
);
1804 status
= U_ZERO_ERROR
;
1805 expect2(new DecimalFormat("*^##.##", custom
, status
),
1806 int32_t(0), "^^^^0", status
);
1807 status
= U_ZERO_ERROR
;
1808 expect2(new DecimalFormat("##.##", custom
, status
),
1809 -1.3, " minus 1decimal3", status
);
1810 status
= U_ZERO_ERROR
;
1811 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1812 int32_t(0), "0decimal0exponent0 g-m/s^2", status
);
1813 status
= U_ZERO_ERROR
;
1814 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1815 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status
);
1816 status
= U_ZERO_ERROR
;
1817 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1818 int32_t(0), "0decimal0 g-m/s^2", status
);
1819 status
= U_ZERO_ERROR
;
1820 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1821 1.0/3, "0decimal33333 g-m/s^2", status
);
1823 UnicodeString
zero((UChar32
)0x10000);
1824 UnicodeString
one((UChar32
)0x10001);
1825 UnicodeString
two((UChar32
)0x10002);
1826 UnicodeString
five((UChar32
)0x10005);
1827 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, zero
);
1828 custom
.setSymbol(DecimalFormatSymbols::kOneDigitSymbol
, one
);
1829 custom
.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol
, two
);
1830 custom
.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol
, five
);
1831 expStr
= UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1832 expStr
= expStr
.unescape();
1833 status
= U_ZERO_ERROR
;
1834 expect2(new DecimalFormat("##0.000", custom
, status
),
1835 1.25, expStr
, status
);
1837 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, (UChar
)0x30);
1838 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "units of money");
1839 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, "money separator");
1840 patternStr
= UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
1841 patternStr
= patternStr
.unescape();
1842 expStr
= UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1843 status
= U_ZERO_ERROR
;
1844 expect2(new DecimalFormat(patternStr
, custom
, status
),
1845 int32_t(-20), expStr
, status
);
1847 custom
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, "percent");
1848 patternStr
= "'You''ve lost ' -0.00 %' of your money today'";
1849 patternStr
= patternStr
.unescape();
1850 expStr
= UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
1851 status
= U_ZERO_ERROR
;
1852 expect2(new DecimalFormat(patternStr
, custom
, status
),
1853 int32_t(-20), expStr
, status
);
1856 void NumberFormatTest::TestCurrencyPatterns(void) {
1857 int32_t i
, locCount
;
1858 const Locale
* locs
= NumberFormat::getAvailableLocales(locCount
);
1859 for (i
=0; i
<locCount
; ++i
) {
1860 UErrorCode ec
= U_ZERO_ERROR
;
1861 NumberFormat
* nf
= NumberFormat::createCurrencyInstance(locs
[i
], ec
);
1862 if (U_FAILURE(ec
)) {
1863 errln("FAIL: Can't create NumberFormat(%s) - %s", locs
[i
].getName(), u_errorName(ec
));
1865 // Make sure currency formats do not have a variable number
1866 // of fraction digits
1867 int32_t min
= nf
->getMinimumFractionDigits();
1868 int32_t max
= nf
->getMaximumFractionDigits();
1872 nf
->format(1.125, b
);
1873 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1874 " min fraction digits != max fraction digits; "
1875 "x 1.0 => " + escape(a
) +
1876 "; x 1.125 => " + escape(b
));
1879 // Make sure EURO currency formats have exactly 2 fraction digits
1880 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
1882 if (u_strcmp(EUR
, df
->getCurrency()) == 0) {
1883 if (min
!= 2 || max
!= 2) {
1886 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1887 " is a EURO format but it does not have 2 fraction digits; "
1898 void NumberFormatTest::TestRegCurrency(void) {
1899 #if !UCONFIG_NO_SERVICE
1900 UErrorCode status
= U_ZERO_ERROR
;
1902 ucurr_forLocale("en_US", USD
, 4, &status
);
1904 ucurr_forLocale("ja_JP", YEN
, 4, &status
);
1906 static const UChar QQQ
[] = {0x51, 0x51, 0x51, 0};
1907 if(U_FAILURE(status
)) {
1908 errcheckln(status
, "Unable to get currency for locale, error %s", u_errorName(status
));
1912 UCurrRegistryKey enkey
= ucurr_register(YEN
, "en_US", &status
);
1913 UCurrRegistryKey enUSEUROkey
= ucurr_register(QQQ
, "en_US_EURO", &status
);
1915 ucurr_forLocale("en_US", TMP
, 4, &status
);
1916 if (u_strcmp(YEN
, TMP
) != 0) {
1917 errln("FAIL: didn't return YEN registered for en_US");
1920 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1921 if (u_strcmp(QQQ
, TMP
) != 0) {
1922 errln("FAIL: didn't return QQQ for en_US_EURO");
1925 int32_t fallbackLen
= ucurr_forLocale("en_XX_BAR", TMP
, 4, &status
);
1927 errln("FAIL: tried to fallback en_XX_BAR");
1929 status
= U_ZERO_ERROR
; // reset
1931 if (!ucurr_unregister(enkey
, &status
)) {
1932 errln("FAIL: couldn't unregister enkey");
1935 ucurr_forLocale("en_US", TMP
, 4, &status
);
1936 if (u_strcmp(USD
, TMP
) != 0) {
1937 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1939 status
= U_ZERO_ERROR
; // reset
1941 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1942 if (u_strcmp(QQQ
, TMP
) != 0) {
1943 errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
1946 ucurr_forLocale("en_US_BLAH", TMP
, 4, &status
);
1947 if (u_strcmp(USD
, TMP
) != 0) {
1948 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1950 status
= U_ZERO_ERROR
; // reset
1952 if (!ucurr_unregister(enUSEUROkey
, &status
)) {
1953 errln("FAIL: couldn't unregister enUSEUROkey");
1956 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1957 if (u_strcmp(EUR
, TMP
) != 0) {
1958 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
1960 status
= U_ZERO_ERROR
; // reset
1964 void NumberFormatTest::TestCurrencyNames(void) {
1965 // Do a basic check of getName()
1966 // USD { "US$", "US Dollar" } // 04/04/1792-
1967 UErrorCode ec
= U_ZERO_ERROR
;
1968 static const UChar USD
[] = {0x55, 0x53, 0x44, 0}; /*USD*/
1969 static const UChar USX
[] = {0x55, 0x53, 0x58, 0}; /*USX*/
1970 static const UChar CAD
[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1971 static const UChar ITL
[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
1972 UBool isChoiceFormat
;
1974 const UBool possibleDataError
= TRUE
;
1975 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
1976 // THE LOCALE DATA before diving into the code.
1977 assertEquals("USD.getName(SYMBOL_NAME, en)",
1979 UnicodeString(ucurr_getName(USD
, "en",
1981 &isChoiceFormat
, &len
, &ec
)),
1983 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)",
1985 UnicodeString(ucurr_getName(USD
, "en",
1986 UCURR_NARROW_SYMBOL_NAME
,
1987 &isChoiceFormat
, &len
, &ec
)),
1989 assertEquals("USD.getName(LONG_NAME, en)",
1990 UnicodeString("US Dollar"),
1991 UnicodeString(ucurr_getName(USD
, "en",
1993 &isChoiceFormat
, &len
, &ec
)),
1995 assertEquals("CAD.getName(SYMBOL_NAME, en)",
1996 UnicodeString("CA$"),
1997 UnicodeString(ucurr_getName(CAD
, "en",
1999 &isChoiceFormat
, &len
, &ec
)),
2001 assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)",
2003 UnicodeString(ucurr_getName(CAD
, "en",
2004 UCURR_NARROW_SYMBOL_NAME
,
2005 &isChoiceFormat
, &len
, &ec
)),
2007 assertEquals("CAD.getName(SYMBOL_NAME, en_CA)",
2009 UnicodeString(ucurr_getName(CAD
, "en_CA",
2011 &isChoiceFormat
, &len
, &ec
)),
2013 assertEquals("USD.getName(SYMBOL_NAME, en_CA)",
2014 UnicodeString("US$"),
2015 UnicodeString(ucurr_getName(USD
, "en_CA",
2017 &isChoiceFormat
, &len
, &ec
)),
2019 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)",
2021 UnicodeString(ucurr_getName(USD
, "en_CA",
2022 UCURR_NARROW_SYMBOL_NAME
,
2023 &isChoiceFormat
, &len
, &ec
)),
2025 assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
2026 UnicodeString("US$"),
2027 UnicodeString(ucurr_getName(USD
, "en_NZ",
2029 &isChoiceFormat
, &len
, &ec
)),
2031 assertEquals("CAD.getName(SYMBOL_NAME)",
2032 UnicodeString("CA$"),
2033 UnicodeString(ucurr_getName(CAD
, "en_NZ",
2035 &isChoiceFormat
, &len
, &ec
)),
2037 assertEquals("USX.getName(SYMBOL_NAME)",
2038 UnicodeString("USX"),
2039 UnicodeString(ucurr_getName(USX
, "en_US",
2041 &isChoiceFormat
, &len
, &ec
)),
2043 assertEquals("USX.getName(NARROW_SYMBOL_NAME)",
2044 UnicodeString("USX"),
2045 UnicodeString(ucurr_getName(USX
, "en_US",
2046 UCURR_NARROW_SYMBOL_NAME
,
2047 &isChoiceFormat
, &len
, &ec
)),
2049 assertEquals("USX.getName(LONG_NAME)",
2050 UnicodeString("USX"),
2051 UnicodeString(ucurr_getName(USX
, "en_US",
2053 &isChoiceFormat
, &len
, &ec
)),
2055 assertSuccess("ucurr_getName", ec
);
2059 // Test that a default or fallback warning is being returned. JB 4239.
2060 ucurr_getName(CAD
, "es_ES", UCURR_LONG_NAME
, &isChoiceFormat
,
2062 assertTrue("ucurr_getName (es_ES fallback)",
2063 U_USING_FALLBACK_WARNING
== ec
, TRUE
, possibleDataError
);
2065 ucurr_getName(CAD
, "zh_TW", UCURR_LONG_NAME
, &isChoiceFormat
,
2067 assertTrue("ucurr_getName (zh_TW fallback)",
2068 U_USING_FALLBACK_WARNING
== ec
, TRUE
, possibleDataError
);
2070 ucurr_getName(CAD
, "en_US", UCURR_LONG_NAME
, &isChoiceFormat
,
2072 assertTrue("ucurr_getName (en_US default)",
2073 U_USING_DEFAULT_WARNING
== ec
|| U_USING_FALLBACK_WARNING
== ec
, TRUE
);
2075 ucurr_getName(CAD
, "ti", UCURR_LONG_NAME
, &isChoiceFormat
,
2077 assertTrue("ucurr_getName (ti default)",
2078 U_USING_DEFAULT_WARNING
== ec
, TRUE
);
2080 // Test that a default warning is being returned when falling back to root. JB 4536.
2081 ucurr_getName(ITL
, "cy", UCURR_LONG_NAME
, &isChoiceFormat
,
2083 assertTrue("ucurr_getName (cy default to root)",
2084 U_USING_DEFAULT_WARNING
== ec
, TRUE
);
2086 // TODO add more tests later
2089 void NumberFormatTest::TestCurrencyUnit(void){
2090 UErrorCode ec
= U_ZERO_ERROR
;
2091 static const UChar USD
[] = u
"USD";
2092 static const char USD8
[] = "USD";
2093 static const UChar BAD
[] = u
"???";
2094 static const UChar BAD2
[] = u
"??A";
2095 static const UChar XXX
[] = u
"XXX";
2096 static const char XXX8
[] = "XXX";
2097 CurrencyUnit
cu(USD
, ec
);
2098 assertSuccess("CurrencyUnit", ec
);
2100 assertEquals("getISOCurrency()", USD
, cu
.getISOCurrency());
2101 assertEquals("getSubtype()", USD8
, cu
.getSubtype());
2103 CurrencyUnit
cu2(cu
);
2105 errln("CurrencyUnit copy constructed object should be same");
2108 CurrencyUnit
* cu3
= (CurrencyUnit
*)cu
.clone();
2110 errln("CurrencyUnit cloned object should be same");
2112 CurrencyUnit
bad(BAD
, ec
);
2113 assertSuccess("CurrencyUnit", ec
);
2114 if (cu
.getIndex() == bad
.getIndex()) {
2115 errln("Indexes of different currencies should differ.");
2117 CurrencyUnit
bad2(BAD2
, ec
);
2118 assertSuccess("CurrencyUnit", ec
);
2119 if (bad2
.getIndex() != bad
.getIndex()) {
2120 errln("Indexes of unrecognized currencies should be the same.");
2123 errln("Different unrecognized currencies should not be equal.");
2127 errln("Currency unit assignment should be the same.");
2131 // Test default constructor
2133 assertEquals("Default currency", XXX
, def
.getISOCurrency());
2134 assertEquals("Default currency as subtype", XXX8
, def
.getSubtype());
2137 MeasureUnit sliced1
= cu
;
2138 MeasureUnit sliced2
= cu
;
2139 assertEquals("Subtype after slicing 1", USD8
, sliced1
.getSubtype());
2140 assertEquals("Subtype after slicing 2", USD8
, sliced2
.getSubtype());
2141 CurrencyUnit
restored1(sliced1
, ec
);
2142 CurrencyUnit
restored2(sliced2
, ec
);
2143 assertSuccess("Restoring from MeasureUnit", ec
);
2144 assertEquals("Subtype after restoring 1", USD8
, restored1
.getSubtype());
2145 assertEquals("Subtype after restoring 2", USD8
, restored2
.getSubtype());
2146 assertEquals("ISO Code after restoring 1", USD
, restored1
.getISOCurrency());
2147 assertEquals("ISO Code after restoring 2", USD
, restored2
.getISOCurrency());
2149 // Test copy constructor failure
2150 LocalPointer
<MeasureUnit
> meter(MeasureUnit::createMeter(ec
));
2151 assertSuccess("Creating meter", ec
);
2152 CurrencyUnit
failure(*meter
, ec
);
2153 assertEquals("Copying from meter should fail", ec
, U_ILLEGAL_ARGUMENT_ERROR
);
2154 assertEquals("Copying should not give uninitialized ISO code", u
"", failure
.getISOCurrency());
2157 void NumberFormatTest::TestCurrencyAmount(void){
2158 UErrorCode ec
= U_ZERO_ERROR
;
2159 static const UChar USD
[] = {85, 83, 68, 0}; /*USD*/
2160 CurrencyAmount
ca(9, USD
, ec
);
2161 assertSuccess("CurrencyAmount", ec
);
2163 CurrencyAmount
ca2(ca
);
2165 errln("CurrencyAmount copy constructed object should be same");
2170 errln("CurrencyAmount assigned object should be same");
2173 CurrencyAmount
*ca3
= (CurrencyAmount
*)ca
.clone();
2175 errln("CurrencyAmount cloned object should be same");
2180 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
2182 static const char *badLocales
[] = {
2183 // length < ULOC_FULLNAME_CAPACITY
2184 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
2186 // length > ULOC_FULLNAME_CAPACITY
2187 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME"
2188 }; // expect U_USING_DEFAULT_WARNING for both
2191 for (i
= 0; i
< UPRV_LENGTHOF(badLocales
); i
++) {
2192 const char *localeName
= badLocales
[i
];
2193 Locale
locBad(localeName
);
2194 TEST_ASSERT_TRUE(!locBad
.isBogus());
2195 UErrorCode status
= U_ZERO_ERROR
;
2196 UnicodeString
intlCurrencySymbol((UChar
)0xa4);
2198 intlCurrencySymbol
.append((UChar
)0xa4);
2200 logln("Current locale is %s", Locale::getDefault().getName());
2201 Locale::setDefault(locBad
, status
);
2202 logln("Current locale is %s", Locale::getDefault().getName());
2203 DecimalFormatSymbols
mySymbols(status
);
2204 if (status
!= U_USING_DEFAULT_WARNING
) {
2205 errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
2207 if (strcmp(mySymbols
.getLocale().getName(), locBad
.getName()) != 0) {
2208 errln("DecimalFormatSymbols does not have the right locale.", locBad
.getName());
2210 int symbolEnum
= (int)DecimalFormatSymbols::kDecimalSeparatorSymbol
;
2211 for (; symbolEnum
< (int)DecimalFormatSymbols::kFormatSymbolCount
; symbolEnum
++) {
2212 UnicodeString symbolString
= mySymbols
.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbolEnum
);
2213 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum
+ UnicodeString("] = ") + prettify(symbolString
));
2214 if (symbolString
.length() == 0
2215 && symbolEnum
!= (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
2216 && symbolEnum
!= (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
)
2218 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum
);
2222 status
= U_ZERO_ERROR
;
2223 Locale::setDefault(locDefault
, status
);
2224 logln("Current locale is %s", Locale::getDefault().getName());
2229 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
2230 * behave the same, except for memory ownership semantics. (No
2231 * version of this test on Java, since Java has only one method.)
2233 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
2234 UErrorCode ec
= U_ZERO_ERROR
;
2235 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2236 if (U_FAILURE(ec
)) {
2237 errcheckln(ec
, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec
));
2241 UnicodeString
pat(" #,##0.00");
2242 pat
.insert(0, (UChar
)0x00A4);
2243 DecimalFormat
fmt(pat
, sym
, ec
);
2244 if (U_FAILURE(ec
)) {
2245 errln("Fail: DecimalFormat constructor");
2250 fmt
.format(2350.75, str
);
2251 if (str
== "$ 2,350.75") {
2254 dataerrln("Fail: " + str
+ ", expected $ 2,350.75");
2257 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2258 if (U_FAILURE(ec
)) {
2259 errln("Fail: DecimalFormatSymbols constructor");
2263 sym
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
2264 fmt
.adoptDecimalFormatSymbols(sym
);
2267 fmt
.format(2350.75, str
);
2268 if (str
== "Q 2,350.75") {
2271 dataerrln("Fail: adoptDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
2274 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2275 if (U_FAILURE(ec
)) {
2276 errln("Fail: DecimalFormatSymbols constructor");
2280 DecimalFormat
fmt2(pat
, sym
, ec
);
2281 if (U_FAILURE(ec
)) {
2282 errln("Fail: DecimalFormat constructor");
2286 DecimalFormatSymbols
sym2(Locale::getUS(), ec
);
2287 if (U_FAILURE(ec
)) {
2288 errln("Fail: DecimalFormatSymbols constructor");
2291 sym2
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
2292 fmt2
.setDecimalFormatSymbols(sym2
);
2295 fmt2
.format(2350.75, str
);
2296 if (str
== "Q 2,350.75") {
2299 dataerrln("Fail: setDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
2303 void NumberFormatTest::TestPerMill() {
2304 UErrorCode ec
= U_ZERO_ERROR
;
2306 DecimalFormat
fmt(ctou("###.###\\u2030"), ec
);
2307 if (!assertSuccess("DecimalFormat ct", ec
)) return;
2308 assertEquals("0.4857 x ###.###\\u2030",
2309 ctou("485.7\\u2030"), fmt
.format(0.4857, str
), true);
2311 DecimalFormatSymbols
sym(Locale::getUS(), ec
);
2312 if (!assertSuccess("", ec
, true, __FILE__
, __LINE__
)) {
2315 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, ctou("m"));
2316 DecimalFormat
fmt2("", sym
, ec
);
2317 if (!assertSuccess("", ec
, true, __FILE__
, __LINE__
)) {
2320 fmt2
.applyLocalizedPattern("###.###m", ec
);
2321 if (!assertSuccess("setup", ec
)) return;
2323 assertEquals("0.4857 x ###.###m",
2324 "485.7m", fmt2
.format(0.4857, str
));
2328 * Generic test for patterns that should be legal/illegal.
2330 void NumberFormatTest::TestIllegalPatterns() {
2332 // Prefix with "-:" for illegal patterns
2333 // Prefix with "+:" for legal patterns
2334 const char* DATA
[] = {
2335 // Unquoted special characters in the suffix are illegal
2340 for (int32_t i
=0; DATA
[i
]; ++i
) {
2341 const char* pat
=DATA
[i
];
2342 UBool valid
= (*pat
) == '+';
2344 UErrorCode ec
= U_ZERO_ERROR
;
2345 DecimalFormat
fmt(pat
, ec
); // locale doesn't matter here
2346 if (U_SUCCESS(ec
) == valid
) {
2347 logln("Ok: pattern \"%s\": %s",
2348 pat
, u_errorName(ec
));
2350 errcheckln(ec
, "FAIL: pattern \"%s\" should have %s; got %s",
2351 pat
, (valid
?"succeeded":"failed"),
2357 //----------------------------------------------------------------------
2359 static const char* KEYWORDS
[] = {
2360 /*0*/ "ref=", // <reference pattern to parse numbers>
2361 /*1*/ "loc=", // <locale for formats>
2362 /*2*/ "f:", // <pattern or '-'> <number> <exp. string>
2363 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
2364 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
2365 /*5*/ "p:", // <pattern or '-'> <string> <exp. number>
2366 /*6*/ "perr:", // <pattern or '-'> <invalid string>
2367 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
2368 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2373 * Return an integer representing the next token from this
2374 * iterator. The integer will be an index into the given list, or
2375 * -1 if there are no more tokens, or -2 if the token is not on
2378 static int32_t keywordIndex(const UnicodeString
& tok
) {
2379 for (int32_t i
=0; KEYWORDS
[i
]!=0; ++i
) {
2380 if (tok
==KEYWORDS
[i
]) {
2388 * Parse a CurrencyAmount using the given NumberFormat, with
2389 * the 'delim' character separating the number and the currency.
2391 static void parseCurrencyAmount(const UnicodeString
& str
,
2392 const NumberFormat
& fmt
,
2394 Formattable
& result
,
2396 UnicodeString num
, cur
;
2397 int32_t i
= str
.indexOf(delim
);
2398 str
.extractBetween(0, i
, num
);
2399 str
.extractBetween(i
+1, INT32_MAX
, cur
);
2401 fmt
.parse(num
, n
, ec
);
2402 result
.adoptObject(new CurrencyAmount(n
, cur
.getTerminatedBuffer(), ec
));
2405 void NumberFormatTest::TestCases() {
2406 UErrorCode ec
= U_ZERO_ERROR
;
2407 TextFile
reader("NumberFormatTestCases.txt", "UTF8", ec
);
2408 if (U_FAILURE(ec
)) {
2409 dataerrln("Couldn't open NumberFormatTestCases.txt");
2412 TokenIterator
tokens(&reader
);
2414 Locale
loc("en", "US", "");
2415 DecimalFormat
*ref
= 0, *fmt
= 0;
2416 MeasureFormat
*mfmt
= 0;
2417 UnicodeString pat
, tok
, mloc
, str
, out
, where
, currAmt
;
2422 if (!tokens
.next(tok
, ec
)) {
2425 where
= UnicodeString("(") + tokens
.getLineNumber() + ") ";
2426 int32_t cmd
= keywordIndex(tok
);
2429 // ref= <reference pattern>
2430 if (!tokens
.next(tok
, ec
)) goto error
;
2432 ref
= new DecimalFormat(tok
,
2433 new DecimalFormatSymbols(Locale::getUS(), ec
), ec
);
2434 if (U_FAILURE(ec
)) {
2435 dataerrln("Error constructing DecimalFormat");
2441 if (!tokens
.next(tok
, ec
)) goto error
;
2442 loc
= Locale::createFromName(CharString().appendInvariantChars(tok
, ec
).data());
2448 if (!tokens
.next(tok
, ec
)) goto error
;
2452 fmt
= new DecimalFormat(pat
, new DecimalFormatSymbols(loc
, ec
), ec
);
2453 if (U_FAILURE(ec
)) {
2454 errln("FAIL: " + where
+ "Pattern \"" + pat
+ "\": " + u_errorName(ec
));
2456 if (!tokens
.next(tok
, ec
)) goto error
;
2457 if (!tokens
.next(tok
, ec
)) goto error
;
2459 if (!tokens
.next(tok
, ec
)) goto error
;
2464 if (cmd
== 2 || cmd
== 3 || cmd
== 4) {
2465 // f: <pattern or '-'> <number> <exp. string>
2466 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
2467 // rt: <pattern or '-'> <number> <string>
2469 if (!tokens
.next(num
, ec
)) goto error
;
2470 if (!tokens
.next(str
, ec
)) goto error
;
2471 ref
->parse(num
, n
, ec
);
2472 assertSuccess("parse", ec
);
2473 assertEquals(where
+ "\"" + pat
+ "\".format(" + num
+ ")",
2474 str
, fmt
->format(n
, out
.remove(), ec
));
2475 assertSuccess("format", ec
);
2476 if (cmd
== 3) { // fp:
2477 if (!tokens
.next(num
, ec
)) goto error
;
2478 ref
->parse(num
, n
, ec
);
2479 assertSuccess("parse", ec
);
2481 if (cmd
!= 2) { // != f:
2483 fmt
->parse(str
, m
, ec
);
2484 assertSuccess("parse", ec
);
2485 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
2489 // p: <pattern or '-'> <string to parse> <exp. number>
2491 UnicodeString expstr
;
2492 if (!tokens
.next(str
, ec
)) goto error
;
2493 if (!tokens
.next(expstr
, ec
)) goto error
;
2495 ref
->parse(expstr
, exp
, ec
);
2496 assertSuccess("parse", ec
);
2497 fmt
->parse(str
, n
, ec
);
2498 assertSuccess("parse", ec
);
2499 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
2504 if (!tokens
.next(tok
, ec
)) goto error
;
2508 mfmt
= MeasureFormat::createCurrencyFormat(
2509 Locale::createFromName(
2510 CharString().appendInvariantChars(mloc
, ec
).data()), ec
);
2511 if (U_FAILURE(ec
)) {
2512 errln("FAIL: " + where
+ "Loc \"" + mloc
+ "\": " + u_errorName(ec
));
2514 if (!tokens
.next(tok
, ec
)) goto error
;
2515 if (!tokens
.next(tok
, ec
)) goto error
;
2516 if (!tokens
.next(tok
, ec
)) goto error
;
2519 } else if (mfmt
== NULL
) {
2520 errln("FAIL: " + where
+ "Loc \"" + mloc
+ "\": skip case using previous locale, no valid MeasureFormat");
2521 if (!tokens
.next(tok
, ec
)) goto error
;
2522 if (!tokens
.next(tok
, ec
)) goto error
;
2523 if (!tokens
.next(tok
, ec
)) goto error
;
2526 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2527 if (!tokens
.next(currAmt
, ec
)) goto error
;
2528 if (!tokens
.next(str
, ec
)) goto error
;
2529 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
2530 if (assertSuccess("parseCurrencyAmount", ec
)) {
2531 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").format(" + currAmt
+ ")",
2532 str
, mfmt
->format(n
, out
.remove(), ec
));
2533 assertSuccess("format", ec
);
2535 if (!tokens
.next(currAmt
, ec
)) goto error
;
2536 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
2537 if (assertSuccess("parseCurrencyAmount", ec
)) {
2540 mfmt
->parseObject(str
, m
, ec
);
2541 if (assertSuccess("parseCurrency", ec
)) {
2542 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").parse(\"" + str
+ "\")",
2545 errln("FAIL: source " + str
);
2550 // perr: <pattern or '-'> <invalid string>
2551 errln("FAIL: Under construction");
2554 // pat: <pattern> <exp. toPattern, or '-' or 'err'>
2555 UnicodeString testpat
;
2556 UnicodeString exppat
;
2557 if (!tokens
.next(testpat
, ec
)) goto error
;
2558 if (!tokens
.next(exppat
, ec
)) goto error
;
2559 UBool err
= exppat
== "err";
2560 UBool existingPat
= FALSE
;
2561 if (testpat
== "-") {
2563 errln("FAIL: " + where
+ "Invalid command \"pat: - err\"");
2569 if (exppat
== "-") exppat
= testpat
;
2570 DecimalFormat
* f
= 0;
2571 UErrorCode ec2
= U_ZERO_ERROR
;
2575 f
= new DecimalFormat(testpat
, ec2
);
2577 if (U_SUCCESS(ec2
)) {
2579 errln("FAIL: " + where
+ "Invalid pattern \"" + testpat
+
2583 assertEquals(where
+ "\"" + testpat
+ "\".toPattern()",
2584 exppat
, f
->toPattern(pat2
));
2588 logln("Ok: " + where
+ "Invalid pattern \"" + testpat
+
2589 "\" failed: " + u_errorName(ec2
));
2591 errln("FAIL: " + where
+ "Valid pattern \"" + testpat
+
2592 "\" failed: " + u_errorName(ec2
));
2595 if (!existingPat
) delete f
;
2598 errln("FAIL: " + where
+ "Unknown command \"" + tok
+ "\"");
2605 if (U_SUCCESS(ec
)) {
2606 errln("FAIL: Unexpected EOF");
2608 errcheckln(ec
, "FAIL: " + where
+ "Unexpected " + u_errorName(ec
));
2618 //----------------------------------------------------------------------
2620 //----------------------------------------------------------------------
2622 UBool
NumberFormatTest::equalValue(const Formattable
& a
, const Formattable
& b
) {
2623 if (a
.getType() == b
.getType()) {
2627 if (a
.getType() == Formattable::kLong
) {
2628 if (b
.getType() == Formattable::kInt64
) {
2629 return a
.getLong() == b
.getLong();
2630 } else if (b
.getType() == Formattable::kDouble
) {
2631 return (double) a
.getLong() == b
.getDouble(); // TODO check use of double instead of long
2633 } else if (a
.getType() == Formattable::kDouble
) {
2634 if (b
.getType() == Formattable::kLong
) {
2635 return a
.getDouble() == (double) b
.getLong();
2636 } else if (b
.getType() == Formattable::kInt64
) {
2637 return a
.getDouble() == (double)b
.getInt64();
2639 } else if (a
.getType() == Formattable::kInt64
) {
2640 if (b
.getType() == Formattable::kLong
) {
2641 return a
.getInt64() == (int64_t)b
.getLong();
2642 } else if (b
.getType() == Formattable::kDouble
) {
2643 return a
.getInt64() == (int64_t)b
.getDouble();
2649 void NumberFormatTest::expect3(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
2650 // Don't round-trip format test, since we explicitly do it
2651 expect_rbnf(fmt
, n
, str
, FALSE
);
2652 expect_rbnf(fmt
, str
, n
);
2655 void NumberFormatTest::expect2(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
2656 // Don't round-trip format test, since we explicitly do it
2657 expect(fmt
, n
, str
, FALSE
);
2658 expect(fmt
, str
, n
);
2661 void NumberFormatTest::expect2(NumberFormat
* fmt
, const Formattable
& n
,
2662 const UnicodeString
& exp
,
2663 UErrorCode status
) {
2664 if (fmt
== NULL
|| U_FAILURE(status
)) {
2665 dataerrln("FAIL: NumberFormat constructor");
2667 expect2(*fmt
, n
, exp
);
2672 void NumberFormatTest::expect(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
2673 UErrorCode status
= U_ZERO_ERROR
;
2675 fmt
.parse(str
, num
, status
);
2676 if (U_FAILURE(status
)) {
2677 dataerrln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\" - " + u_errorName(status
));
2681 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
2682 if (equalValue(num
, n
)) {
2683 logln(UnicodeString("Ok \"") + str
+ "\" x " +
2687 dataerrln(UnicodeString("FAIL \"") + str
+ "\" x " +
2689 toString(num
) + ", expected " + toString(n
));
2693 void NumberFormatTest::expect_rbnf(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
2694 UErrorCode status
= U_ZERO_ERROR
;
2696 fmt
.parse(str
, num
, status
);
2697 if (U_FAILURE(status
)) {
2698 errln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\"");
2701 if (equalValue(num
, n
)) {
2702 logln(UnicodeString("Ok \"") + str
+ " = " +
2705 errln(UnicodeString("FAIL \"") + str
+ " = " +
2706 toString(num
) + ", expected " + toString(n
));
2710 void NumberFormatTest::expect_rbnf(NumberFormat
& fmt
, const Formattable
& n
,
2711 const UnicodeString
& exp
, UBool rt
) {
2714 UErrorCode status
= U_ZERO_ERROR
;
2715 fmt
.format(n
, saw
, pos
, status
);
2716 CHECK(status
, "NumberFormat::format");
2718 logln(UnicodeString("Ok ") + toString(n
) +
2720 escape(saw
) + "\"");
2721 // We should be able to round-trip the formatted string =>
2722 // number => string (but not the other way around: number
2723 // => string => number2, might have number2 != number):
2726 fmt
.parse(exp
, n2
, status
);
2727 if (U_FAILURE(status
)) {
2728 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\"");
2732 fmt
.format(n2
, saw2
, pos
, status
);
2733 CHECK(status
, "NumberFormat::format");
2735 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
2736 " => \"" + saw2
+ "\"");
2740 errln(UnicodeString("FAIL ") + toString(n
) +
2742 escape(saw
) + "\", expected \"" + exp
+ "\"");
2746 void NumberFormatTest::expect(NumberFormat
& fmt
, const Formattable
& n
,
2747 const UnicodeString
& exp
, UBool rt
) {
2750 UErrorCode status
= U_ZERO_ERROR
;
2751 fmt
.format(n
, saw
, pos
, status
);
2752 CHECK(status
, "NumberFormat::format");
2754 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
2756 logln(UnicodeString("Ok ") + toString(n
) + " x " +
2757 escape(pat
) + " = \"" +
2758 escape(saw
) + "\"");
2759 // We should be able to round-trip the formatted string =>
2760 // number => string (but not the other way around: number
2761 // => string => number2, might have number2 != number):
2764 fmt
.parse(exp
, n2
, status
);
2765 if (U_FAILURE(status
)) {
2766 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\" - " + u_errorName(status
));
2770 fmt
.format(n2
, saw2
, pos
, status
);
2771 CHECK(status
, "NumberFormat::format");
2773 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
2774 " => \"" + saw2
+ "\"");
2778 dataerrln(UnicodeString("FAIL ") + toString(n
) + " x " +
2779 escape(pat
) + " = \"" +
2780 escape(saw
) + "\", expected \"" + exp
+ "\"");
2784 void NumberFormatTest::expect(NumberFormat
* fmt
, const Formattable
& n
,
2785 const UnicodeString
& exp
, UBool rt
,
2786 UErrorCode status
) {
2787 if (fmt
== NULL
|| U_FAILURE(status
)) {
2788 dataerrln("FAIL: NumberFormat constructor");
2790 expect(*fmt
, n
, exp
, rt
);
2795 void NumberFormatTest::expectCurrency(NumberFormat
& nf
, const Locale
& locale
,
2796 double value
, const UnicodeString
& string
) {
2797 UErrorCode ec
= U_ZERO_ERROR
;
2798 DecimalFormat
& fmt
= * (DecimalFormat
*) &nf
;
2799 const UChar DEFAULT_CURR
[] = {45/*-*/,0};
2801 u_strcpy(curr
, DEFAULT_CURR
);
2802 if (*locale
.getLanguage() != 0) {
2803 ucurr_forLocale(locale
.getName(), curr
, 4, &ec
);
2804 assertSuccess("ucurr_forLocale", ec
);
2805 fmt
.setCurrency(curr
, ec
);
2806 assertSuccess("DecimalFormat::setCurrency", ec
);
2807 fmt
.setCurrency(curr
); //Deprecated variant, for coverage only
2810 fmt
.format(value
, s
);
2811 s
.findAndReplace((UChar32
)0x00A0, (UChar32
)0x0020);
2813 // Default display of the number yields "1234.5599999999999"
2814 // instead of "1234.56". Use a formatter to fix this.
2816 NumberFormat::createInstance(Locale::getUS(), ec
);
2818 if (U_FAILURE(ec
)) {
2819 // Oops; bad formatter. Use default op+= display.
2820 v
= (UnicodeString
)"" + value
;
2822 f
->setMaximumFractionDigits(4);
2823 f
->setGroupingUsed(FALSE
);
2824 f
->format(value
, v
);
2829 logln((UnicodeString
)"Ok: " + v
+ " x " + curr
+ " => " + prettify(s
));
2831 errln((UnicodeString
)"FAIL: " + v
+ " x " + curr
+ " => " + prettify(s
) +
2832 ", expected " + prettify(string
));
2836 void NumberFormatTest::expectPat(DecimalFormat
& fmt
, const UnicodeString
& exp
) {
2840 logln(UnicodeString("Ok \"") + pat
+ "\"");
2842 errln(UnicodeString("FAIL \"") + pat
+ "\", expected \"" + exp
+ "\"");
2846 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2848 expectPad(fmt
, pat
, pos
, 0, (UnicodeString
)"");
2850 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2851 int32_t pos
, int32_t width
, UChar pad
) {
2852 expectPad(fmt
, pat
, pos
, width
, UnicodeString(pad
));
2854 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2855 int32_t pos
, int32_t width
, const UnicodeString
& pad
) {
2856 int32_t apos
= 0, awidth
= 0;
2857 UnicodeString apadStr
;
2858 UErrorCode status
= U_ZERO_ERROR
;
2859 fmt
.applyPattern(pat
, status
);
2860 if (U_SUCCESS(status
)) {
2861 apos
= fmt
.getPadPosition();
2862 awidth
= fmt
.getFormatWidth();
2863 apadStr
=fmt
.getPadCharacterString();
2869 if (apos
== pos
&& awidth
== width
&& apadStr
== pad
) {
2870 UnicodeString infoStr
;
2871 if (pos
== ILLEGAL
) {
2872 infoStr
= UnicodeString(" width=", "") + awidth
+ UnicodeString(" pad=", "") + apadStr
;
2874 logln(UnicodeString("Ok \"") + pat
+ "\" pos=" + apos
+ infoStr
);
2876 errln(UnicodeString("FAIL \"") + pat
+ "\" pos=" + apos
+
2877 " width=" + awidth
+ " pad=" + apadStr
+
2878 ", expected " + pos
+ " " + width
+ " " + pad
);
2882 // This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale - FIXME
2883 void NumberFormatTest::TestCompatibleCurrencies() {
2885 static const UChar JPY[] = {0x4A, 0x50, 0x59, 0};
2886 static const UChar CNY[] = {0x43, 0x4E, 0x59, 0};
2887 UErrorCode status = U_ZERO_ERROR;
2888 LocalPointer<NumberFormat> fmt(
2889 NumberFormat::createCurrencyInstance(Locale::getUS(), status));
2890 if (U_FAILURE(status)) {
2891 errln("Could not create number format instance.");
2894 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
2895 expectParseCurrency(*fmt, JPY, 1235, "\\u00A51,235");
2896 logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__);
2897 expectParseCurrency(*fmt, JPY, 1235, "\\uFFE51,235");
2898 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
2899 expectParseCurrency(*fmt, CNY, 1235, "CN\\u00A51,235");
2901 LocalPointer<NumberFormat> fmtTW(
2902 NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
2904 logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__);
2905 expectParseCurrency(*fmtTW, CNY, 1235, "\\u00A51,235");
2906 logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__);
2907 expectParseCurrency(*fmtTW, CNY, 1235, "\\uFFE51,235");
2909 LocalPointer<NumberFormat> fmtJP(
2910 NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
2912 logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__);
2913 expectParseCurrency(*fmtJP, JPY, 1235, "\\u00A51,235");
2914 logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
2915 expectParseCurrency(*fmtJP, JPY, 1235, "\\uFFE51,235");
2921 void NumberFormatTest::expectParseCurrency(const NumberFormat
&fmt
, const UChar
* currency
, double amount
, const char *text
) {
2923 UnicodeString utext
= ctou(text
);
2924 LocalPointer
<CurrencyAmount
> currencyAmount(fmt
.parseCurrency(utext
, ppos
));
2925 if (!ppos
.getIndex()) {
2926 errln(UnicodeString("Parse of ") + utext
+ " should have succeeded.");
2929 UErrorCode status
= U_ZERO_ERROR
;
2932 sprintf(theInfo
, "For locale %s, string \"%s\", currency ",
2933 fmt
.getLocale(ULOC_ACTUAL_LOCALE
, status
).getBaseName(),
2935 u_austrcpy(theInfo
+uprv_strlen(theInfo
), currency
);
2937 char theOperation
[100];
2939 uprv_strcpy(theOperation
, theInfo
);
2940 uprv_strcat(theOperation
, ", check amount:");
2941 assertTrue(theOperation
, amount
== currencyAmount
->getNumber().getDouble(status
));
2943 uprv_strcpy(theOperation
, theInfo
);
2944 uprv_strcat(theOperation
, ", check currency:");
2945 assertEquals(theOperation
, currency
, currencyAmount
->getISOCurrency());
2949 void NumberFormatTest::TestJB3832(){
2950 const char* localeID
= "pt_PT@currency=PTE";
2951 Locale
loc(localeID
);
2952 UErrorCode status
= U_ZERO_ERROR
;
2953 UnicodeString
expected(CharsToUnicodeString("1,150$50\\u00A0\\u200B")); // per cldrbug 7670
2955 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(loc
, status
);
2956 if(U_FAILURE(status
)){
2957 dataerrln("Could not create currency formatter for locale %s - %s", localeID
, u_errorName(status
));
2960 currencyFmt
->format(1150.50, s
);
2962 errln(UnicodeString("FAIL: Expected: ")+expected
2963 + UnicodeString(" Got: ") + s
2964 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
2966 if (U_FAILURE(status
)){
2967 errln("FAIL: Status %s", u_errorName(status
));
2972 void NumberFormatTest::TestHost()
2974 #if U_PLATFORM_USES_ONLY_WIN32_API
2975 Win32NumberTest::testLocales(this);
2977 Locale
loc("en_US@compat=host");
2978 for (UNumberFormatStyle k
= UNUM_DECIMAL
;
2979 k
< UNUM_FORMAT_STYLE_COUNT
; k
= (UNumberFormatStyle
)(k
+1)) {
2980 UErrorCode status
= U_ZERO_ERROR
;
2981 LocalPointer
<NumberFormat
> full(NumberFormat::createInstance(loc
, k
, status
));
2982 if (!NumberFormat::isStyleSupported(k
)) {
2983 if (status
!= U_UNSUPPORTED_ERROR
) {
2984 errln("FAIL: expected style %d to be unsupported - %s",
2985 k
, u_errorName(status
));
2989 if (full
.isNull() || U_FAILURE(status
)) {
2990 dataerrln("FAIL: Can't create number instance of style %d for host - %s",
2991 k
, u_errorName(status
));
2994 UnicodeString result1
;
2995 Formattable
number(10.00);
2996 full
->format(number
, result1
, status
);
2997 if (U_FAILURE(status
)) {
2998 errln("FAIL: Can't format for host");
3001 Formattable formattable
;
3002 full
->parse(result1
, formattable
, status
);
3003 if (U_FAILURE(status
)) {
3004 errln("FAIL: Can't parse for host");
3010 void NumberFormatTest::TestHostClone()
3013 Verify that a cloned formatter gives the same results
3014 and is useable after the original has been deleted.
3016 // This is mainly important on Windows.
3017 UErrorCode status
= U_ZERO_ERROR
;
3018 Locale
loc("en_US@compat=host");
3019 UDate now
= Calendar::getNow();
3020 NumberFormat
*full
= NumberFormat::createInstance(loc
, status
);
3021 if (full
== NULL
|| U_FAILURE(status
)) {
3022 dataerrln("FAIL: Can't create NumberFormat date instance - %s", u_errorName(status
));
3025 UnicodeString result1
;
3026 full
->format(now
, result1
, status
);
3027 Format
*fullClone
= full
->clone();
3031 UnicodeString result2
;
3032 fullClone
->format(now
, result2
, status
);
3033 if (U_FAILURE(status
)) {
3034 errln("FAIL: format failure.");
3036 if (result1
!= result2
) {
3037 errln("FAIL: Clone returned different result from non-clone.");
3042 void NumberFormatTest::TestCurrencyFormat()
3044 // This test is here to increase code coverage.
3045 UErrorCode status
= U_ZERO_ERROR
;
3046 MeasureFormat
*cloneObj
;
3048 Formattable toFormat
, result
;
3049 static const UChar ISO_CODE
[4] = {0x0047, 0x0042, 0x0050, 0};
3051 Locale saveDefaultLocale
= Locale::getDefault();
3052 Locale::setDefault( Locale::getUK(), status
);
3053 if (U_FAILURE(status
)) {
3054 errln("couldn't set default Locale!");
3058 MeasureFormat
*measureObj
= MeasureFormat::createCurrencyFormat(status
);
3059 if (U_FAILURE(status
)){
3060 dataerrln("FAIL: MeasureFormat::createCurrencyFormat status %s", u_errorName(status
));
3063 Locale::setDefault( saveDefaultLocale
, status
);
3064 if (U_FAILURE(status
)){
3065 dataerrln("FAIL: Locale::setDefault status %s", u_errorName(status
));
3068 cloneObj
= (MeasureFormat
*)measureObj
->clone();
3069 if (cloneObj
== NULL
) {
3070 errln("Clone doesn't work");
3073 toFormat
.adoptObject(new CurrencyAmount(1234.56, ISO_CODE
, status
));
3074 measureObj
->format(toFormat
, str
, status
);
3075 measureObj
->parseObject(str
, result
, status
);
3076 if (U_FAILURE(status
)){
3077 errln("FAIL: Status %s", u_errorName(status
));
3079 if (result
!= toFormat
) {
3080 errln("measureObj does not round trip. Formatted string was \"" + str
+ "\" Got: " + toString(result
) + " Expected: " + toString(toFormat
));
3082 status
= U_ZERO_ERROR
;
3084 cloneObj
->format(toFormat
, str
, status
);
3085 cloneObj
->parseObject(str
, result
, status
);
3086 if (U_FAILURE(status
)){
3087 errln("FAIL: Status %s", u_errorName(status
));
3089 if (result
!= toFormat
) {
3090 errln("Clone does not round trip. Formatted string was \"" + str
+ "\" Got: " + toString(result
) + " Expected: " + toString(toFormat
));
3092 if (*measureObj
!= *cloneObj
) {
3093 errln("Cloned object is not equal to the original object");
3098 status
= U_USELESS_COLLATOR_ERROR
;
3099 if (MeasureFormat::createCurrencyFormat(status
) != NULL
) {
3100 errln("createCurrencyFormat should have returned NULL.");
3104 /* Port of ICU4J rounding test. */
3105 void NumberFormatTest::TestRounding() {
3106 UErrorCode status
= U_ZERO_ERROR
;
3107 DecimalFormat
*df
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status
);
3109 if (U_FAILURE(status
)) {
3110 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status
));
3114 int roundingIncrements
[]={1, 2, 5, 20, 50, 100};
3115 int testValues
[]={0, 300};
3117 for (int j
=0; j
<2; j
++) {
3118 for (int mode
=DecimalFormat::kRoundUp
;mode
<DecimalFormat::kRoundHalfEven
;mode
++) {
3119 df
->setRoundingMode((DecimalFormat::ERoundingMode
)mode
);
3120 for (int increment
=0; increment
<6; increment
++) {
3121 double base
=testValues
[j
];
3122 double rInc
=roundingIncrements
[increment
];
3123 checkRounding(df
, base
, 20, rInc
);
3124 rInc
=1.000000000/rInc
;
3125 checkRounding(df
, base
, 20, rInc
);
3132 void NumberFormatTest::TestRoundingPattern() {
3133 UErrorCode status
= U_ZERO_ERROR
;
3135 UnicodeString pattern
;
3137 UnicodeString expected
;
3139 { (UnicodeString
)"##0.65", 1.234, (UnicodeString
)"1.30" },
3140 { (UnicodeString
)"#50", 1230, (UnicodeString
)"1250" }
3142 int32_t numOfTests
= UPRV_LENGTHOF(tests
);
3143 UnicodeString result
;
3145 DecimalFormat
*df
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status
);
3146 if (U_FAILURE(status
)) {
3147 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status
));
3151 for (int32_t i
= 0; i
< numOfTests
; i
++) {
3154 df
->applyPattern(tests
[i
].pattern
, status
);
3155 if (U_FAILURE(status
)) {
3156 errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status
));
3159 df
->format(tests
[i
].testCase
, result
);
3161 if (result
!= tests
[i
].expected
) {
3162 errln("String Pattern Rounding Test Failed: Pattern: \"" + tests
[i
].pattern
+ "\" Number: " + tests
[i
].testCase
+ " - Got: " + result
+ " Expected: " + tests
[i
].expected
);
3169 void NumberFormatTest::checkRounding(DecimalFormat
* df
, double base
, int iterations
, double increment
) {
3170 df
->setRoundingIncrement(increment
);
3171 double lastParsed
=INT32_MIN
; //Intger.MIN_VALUE
3172 for (int i
=-iterations
; i
<=iterations
;i
++) {
3173 double iValue
=base
+(increment
*(i
*0.1));
3174 double smallIncrement
=0.00000001;
3176 smallIncrement
*=iValue
;
3178 //we not only test the value, but some values in a small range around it
3179 lastParsed
=checkRound(df
, iValue
-smallIncrement
, lastParsed
);
3180 lastParsed
=checkRound(df
, iValue
, lastParsed
);
3181 lastParsed
=checkRound(df
, iValue
+smallIncrement
, lastParsed
);
3185 double NumberFormatTest::checkRound(DecimalFormat
* df
, double iValue
, double lastParsed
) {
3186 UErrorCode status
=U_ZERO_ERROR
;
3187 UnicodeString formattedDecimal
;
3190 df
->format(iValue
, formattedDecimal
, status
);
3192 if (U_FAILURE(status
)) {
3193 errln("Error formatting number.");
3196 df
->parse(formattedDecimal
, result
, status
);
3198 if (U_FAILURE(status
)) {
3199 errln("Error parsing number.");
3202 parsed
=result
.getDouble();
3204 if (lastParsed
>parsed
) {
3205 errln("Rounding wrong direction! %d > %d", lastParsed
, parsed
);
3211 void NumberFormatTest::TestNonpositiveMultiplier() {
3212 UErrorCode status
= U_ZERO_ERROR
;
3213 DecimalFormatSymbols
US(Locale::getUS(), status
);
3214 CHECK(status
, "DecimalFormatSymbols constructor");
3215 DecimalFormat
df(UnicodeString("0"), US
, status
);
3216 CHECK(status
, "DecimalFormat(0)");
3218 // test zero multiplier
3220 int32_t mult
= df
.getMultiplier();
3221 df
.setMultiplier(0);
3222 if (df
.getMultiplier() != mult
) {
3223 errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
3226 // test negative multiplier
3228 df
.setMultiplier(-1);
3229 if (df
.getMultiplier() != -1) {
3230 errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
3234 expect(df
, "1122.123", -1122.123);
3235 expect(df
, "-1122.123", 1122.123);
3236 expect(df
, "1.2", -1.2);
3237 expect(df
, "-1.2", 1.2);
3239 // Note: the tests with the final parameter of FALSE will not round trip.
3240 // The initial numeric value will format correctly, after the multiplier.
3241 // Parsing the formatted text will be out-of-range for an int64, however.
3242 // The expect() function could be modified to detect this and fall back
3243 // to looking at the decimal parsed value, but it doesn't.
3244 expect(df
, U_INT64_MIN
, "9223372036854775808", FALSE
);
3245 expect(df
, U_INT64_MIN
+1, "9223372036854775807");
3246 expect(df
, (int64_t)-123, "123");
3247 expect(df
, (int64_t)123, "-123");
3248 expect(df
, U_INT64_MAX
-1, "-9223372036854775806");
3249 expect(df
, U_INT64_MAX
, "-9223372036854775807");
3251 df
.setMultiplier(-2);
3252 expect(df
, -(U_INT64_MIN
/2)-1, "-9223372036854775806");
3253 expect(df
, -(U_INT64_MIN
/2), "-9223372036854775808");
3254 expect(df
, -(U_INT64_MIN
/2)+1, "-9223372036854775810", FALSE
);
3256 df
.setMultiplier(-7);
3257 expect(df
, -(U_INT64_MAX
/7)-1, "9223372036854775814", FALSE
);
3258 expect(df
, -(U_INT64_MAX
/7), "9223372036854775807");
3259 expect(df
, -(U_INT64_MAX
/7)+1, "9223372036854775800");
3261 // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
3262 // (right now the big numbers get turned into doubles and lose tons of accuracy)
3263 //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
3264 //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
3265 //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
3266 //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
3268 // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
3269 //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3270 //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3271 //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3272 //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3276 const char * stringToParse
;
3280 } TestSpaceParsingItem
;
3283 NumberFormatTest::TestSpaceParsing() {
3285 // the string to be parsed, parsed position, parsed error index
3286 const TestSpaceParsingItem DATA
[] = {
3287 // TOTO: Update the following TODOs, some may be handled now
3288 {"$124", 4, -1, FALSE
},
3289 {"$124 $124", 4, -1, FALSE
},
3290 {"$124 ", 4, -1, FALSE
},
3291 //{"$ 124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
3292 //{"$\\u00A0124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
3293 {"$ 124 ", 0, 1, FALSE
}, // errorIndex used to be 0, now 1 (better)
3294 {"$\\u00A0124 ", 5, -1, FALSE
}, // errorIndex used to be 0, now 1 (better) *Apple change from open source*
3295 {" $ 124 ", 0, 0, FALSE
}, // TODO: need to handle space correctly
3296 {"124$", 0, 3, FALSE
}, // TODO: need to handle space correctly
3297 // {"124 $", 5, -1, FALSE}, // TODO: OK or not, need currency spacing rule
3298 {"124 $", 0, 3, FALSE
},
3299 {"$124", 4, -1, TRUE
},
3300 {"$124 $124", 4, -1, TRUE
},
3301 {"$124 ", 4, -1, TRUE
},
3302 {"$ 124 ", 5, -1, TRUE
},
3303 {"$\\u00A0124 ", 5, -1, TRUE
},
3304 {" $ 124 ", 6, -1, TRUE
},
3305 //{"124$", 4, -1, TRUE}, // TODO: need to handle trailing currency correctly
3306 {"124$", 3, -1, TRUE
},
3307 //{"124 $", 5, -1, TRUE}, // TODO: OK or not, need currency spacing rule
3308 {"124 $", 4, -1, TRUE
},
3310 UErrorCode status
= U_ZERO_ERROR
;
3311 Locale
locale("en_US");
3312 NumberFormat
* foo
= NumberFormat::createCurrencyInstance(locale
, status
);
3314 if (U_FAILURE(status
)) {
3318 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(DATA
); ++i
) {
3319 ParsePosition
parsePosition(0);
3320 UnicodeString stringToBeParsed
= ctou(DATA
[i
].stringToParse
);
3321 int parsedPosition
= DATA
[i
].parsedPos
;
3322 int errorIndex
= DATA
[i
].errorIndex
;
3323 foo
->setLenient(DATA
[i
].lenient
);
3325 foo
->parse(stringToBeParsed
, result
, parsePosition
);
3326 logln("Parsing: " + stringToBeParsed
);
3327 if (parsePosition
.getIndex() != parsedPosition
||
3328 parsePosition
.getErrorIndex() != errorIndex
) {
3329 errln("FAILED parse " + stringToBeParsed
+ "; lenient: " + DATA
[i
].lenient
+ "; wrong position, expected: (" + parsedPosition
+ ", " + errorIndex
+ "); got (" + parsePosition
.getIndex() + ", " + parsePosition
.getErrorIndex() + ")");
3331 if (parsePosition
.getErrorIndex() == -1 &&
3332 result
.getType() == Formattable::kLong
&&
3333 result
.getLong() != 124) {
3334 errln("FAILED parse " + stringToBeParsed
+ "; wrong number, expect: 124, got " + result
.getLong());
3341 * Test using various numbering systems and numbering system keyword.
3344 const char *localeName
;
3347 const char *expectedResult
;
3348 } TestNumberingSystemItem
;
3350 void NumberFormatTest::TestNumberingSystems() {
3352 const TestNumberingSystemItem DATA
[] = {
3353 { "en_US@numbers=thai", 1234.567, FALSE
, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
3354 { "en_US@numbers=hebr", 5678.0, TRUE
, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
3355 { "en_US@numbers=arabext", 1234.567, FALSE
, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
3356 { "ar_EG", 1234.567, FALSE
, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
3357 { "th_TH@numbers=traditional", 1234.567, FALSE
, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
3358 { "ar_MA", 1234.567, FALSE
, "1.234,567" },
3359 { "en_US@numbers=hanidec", 1234.567, FALSE
, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3360 { "ta_IN@numbers=native", 1234.567, FALSE
, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
3361 { "ta_IN@numbers=traditional", 1235.0, TRUE
, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
3362 { "ta_IN@numbers=finance", 1234.567, FALSE
, "1,234.567" }, // fall back to default per TR35
3363 { "zh_TW@numbers=native", 1234.567, FALSE
, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3364 { "zh_TW@numbers=traditional", 1234.567, TRUE
, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
3365 { "zh_TW@numbers=finance", 1234.567, TRUE
, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
3366 { NULL
, 0, FALSE
, NULL
}
3371 const TestNumberingSystemItem
*item
;
3372 for (item
= DATA
; item
->localeName
!= NULL
; item
++) {
3374 Locale loc
= Locale::createFromName(item
->localeName
);
3376 NumberFormat
*origFmt
= NumberFormat::createInstance(loc
,ec
);
3377 if (U_FAILURE(ec
)) {
3378 dataerrln("FAIL: getInstance(%s) - %s", item
->localeName
, u_errorName(ec
));
3381 // Clone to test ticket #10682
3382 NumberFormat
*fmt
= (NumberFormat
*) origFmt
->clone();
3387 expect3(*fmt
,item
->value
,CharsToUnicodeString(item
->expectedResult
));
3389 expect2(*fmt
,item
->value
,CharsToUnicodeString(item
->expectedResult
));
3395 // Test bogus keyword value
3397 Locale loc4
= Locale::createFromName("en_US@numbers=foobar");
3398 NumberFormat
* fmt4
= NumberFormat::createInstance(loc4
, ec
);
3399 if ( ec
!= U_UNSUPPORTED_ERROR
) {
3400 errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
3405 NumberingSystem
*ns
= NumberingSystem::createInstance(ec
);
3406 if (U_FAILURE(ec
)) {
3407 dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec
));
3411 ns
->getDynamicClassID();
3412 ns
->getStaticClassID();
3414 errln("FAIL: getInstance() returned NULL.");
3417 NumberingSystem
*ns1
= new NumberingSystem(*ns
);
3419 errln("FAIL: NumberSystem copy constructor returned NULL.");
3429 NumberFormatTest::TestMultiCurrencySign() {
3430 const char* DATA
[][6] = {
3431 // the fields in the following test are:
3433 // currency pattern (with negative pattern),
3434 // currency number to be formatted,
3435 // currency format using currency symbol name, such as "$" for USD,
3436 // currency format using currency ISO name, such as "USD",
3437 // currency format using plural name, such as "US dollars".
3439 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
3440 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
3441 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollars1.00"},
3443 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\u00A51,234.56", "CNY1,234.56", "\\u4EBA\\u6C11\\u5E011,234.56"},
3444 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\u00A51,234.56)", "(CNY1,234.56)", "(\\u4EBA\\u6C11\\u5E011,234.56)"},
3445 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\u00A51.00", "CNY1.00", "\\u4EBA\\u6C11\\u5E011.00"}
3448 const UChar doubleCurrencySign
[] = {0xA4, 0xA4, 0};
3449 UnicodeString
doubleCurrencyStr(doubleCurrencySign
);
3450 const UChar tripleCurrencySign
[] = {0xA4, 0xA4, 0xA4, 0};
3451 UnicodeString
tripleCurrencyStr(tripleCurrencySign
);
3453 for (uint32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
3454 const char* locale
= DATA
[i
][0];
3455 UnicodeString pat
= ctou(DATA
[i
][1]);
3456 double numberToBeFormat
= atof(DATA
[i
][2]);
3457 UErrorCode status
= U_ZERO_ERROR
;
3458 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale(locale
), status
);
3459 if (U_FAILURE(status
)) {
3463 for (int j
=1; j
<=3; ++j
) {
3464 // j represents the number of currency sign in the pattern.
3466 pat
= pat
.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr
);
3467 } else if (j
== 3) {
3468 pat
= pat
.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr
);
3471 DecimalFormat
* fmt
= new DecimalFormat(pat
, new DecimalFormatSymbols(*sym
), status
);
3472 if (U_FAILURE(status
)) {
3473 errln("FAILED init DecimalFormat ");
3478 ((NumberFormat
*) fmt
)->format(numberToBeFormat
, s
);
3479 // DATA[i][3] is the currency format result using a
3480 // single currency sign.
3481 // DATA[i][4] is the currency format result using
3482 // double currency sign.
3483 // DATA[i][5] is the currency format result using
3484 // triple currency sign.
3485 // DATA[i][j+2] is the currency format result using
3486 // 'j' number of currency sign.
3487 UnicodeString currencyFormatResult
= ctou(DATA
[i
][2+j
]);
3488 if (s
.compare(currencyFormatResult
)) {
3489 errln("FAIL format: Expected " + currencyFormatResult
+ "; Got " + s
);
3491 // mix style parsing
3492 for (int k
=3; k
<=5; ++k
) {
3493 // DATA[i][3] is the currency format result using a
3494 // single currency sign.
3495 // DATA[i][4] is the currency format result using
3496 // double currency sign.
3497 // DATA[i][5] is the currency format result using
3498 // triple currency sign.
3499 UnicodeString oneCurrencyFormat
= ctou(DATA
[i
][k
]);
3500 UErrorCode status
= U_ZERO_ERROR
;
3501 Formattable parseRes
;
3502 fmt
->parse(oneCurrencyFormat
, parseRes
, status
);
3503 if (U_FAILURE(status
) ||
3504 (parseRes
.getType() == Formattable::kDouble
&&
3505 parseRes
.getDouble() != numberToBeFormat
) ||
3506 (parseRes
.getType() == Formattable::kLong
&&
3507 parseRes
.getLong() != numberToBeFormat
)) {
3508 errln("FAILED parse " + oneCurrencyFormat
+ "; (i, j, k): " +
3509 i
+ ", " + j
+ ", " + k
);
3520 NumberFormatTest::TestCurrencyFormatForMixParsing() {
3521 UErrorCode status
= U_ZERO_ERROR
;
3522 MeasureFormat
* curFmt
= MeasureFormat::createCurrencyFormat(Locale("en_US"), status
);
3523 if (U_FAILURE(status
)) {
3527 const char* formats
[] = {
3528 "$1,234.56", // string to be parsed
3530 "US dollars1,234.56",
3531 // "1,234.56 US dollars" // Fails in 62 because currency format is not compatible with pattern.
3533 const CurrencyAmount
* curramt
= NULL
;
3534 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(formats
); ++i
) {
3535 UnicodeString stringToBeParsed
= ctou(formats
[i
]);
3536 logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed
);
3538 UErrorCode status
= U_ZERO_ERROR
;
3539 curFmt
->parseObject(stringToBeParsed
, result
, status
);
3540 if (U_FAILURE(status
)) {
3541 errln("FAIL: measure format parsing: '%s' ec: %s", formats
[i
], u_errorName(status
));
3542 } else if (result
.getType() != Formattable::kObject
||
3543 (curramt
= dynamic_cast<const CurrencyAmount
*>(result
.getObject())) == NULL
||
3544 curramt
->getNumber().getDouble() != 1234.56 ||
3545 UnicodeString(curramt
->getISOCurrency()).compare(ISO_CURRENCY_USD
)
3547 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
3548 if (curramt
->getNumber().getDouble() != 1234.56) {
3549 errln((UnicodeString
)"wong number, expect: 1234.56" + ", got: " + curramt
->getNumber().getDouble());
3551 if (curramt
->getISOCurrency() != ISO_CURRENCY_USD
) {
3552 errln((UnicodeString
)"wong currency, expect: USD" + ", got: " + curramt
->getISOCurrency());
3560 /** Starting in ICU 62, strict mode is actually strict with currency formats. */
3561 void NumberFormatTest::TestMismatchedCurrencyFormatFail() {
3562 IcuTestErrorCode
status(*this, "TestMismatchedCurrencyFormatFail");
3563 LocalPointer
<DecimalFormat
> df(
3564 dynamic_cast<DecimalFormat
*>(DecimalFormat::createCurrencyInstance("en", status
)), status
);
3565 if (!assertSuccess("createCurrencyInstance() failed.", status
, true, __FILE__
, __LINE__
)) {return;}
3566 UnicodeString pattern
;
3567 assertEquals("Test assumes that currency sign is at the beginning",
3569 df
->toPattern(pattern
));
3570 // Should round-trip on the correct currency format:
3571 expect2(*df
, 1.23, u
"XXX\u00A01.23");
3572 df
->setCurrency(u
"EUR", status
);
3573 expect2(*df
, 1.23, u
"\u20AC1.23");
3574 // Should parse with currency in the wrong place in lenient mode
3575 df
->setLenient(TRUE
);
3576 expect(*df
, u
"1.23\u20AC", 1.23);
3577 expectParseCurrency(*df
, u
"EUR", 1.23, "1.23\\u20AC");
3578 // Should NOT parse with currency in the wrong place in STRICT mode
3579 df
->setLenient(FALSE
);
3582 ErrorCode failStatus
;
3583 df
->parse(u
"1.23\u20AC", result
, failStatus
);
3584 assertEquals("Should fail to parse", U_INVALID_FORMAT_ERROR
, failStatus
);
3588 df
->parseCurrency(u
"1.23\u20AC", ppos
);
3589 assertEquals("Should fail to parse currency", 0, ppos
.getIndex());
3595 NumberFormatTest::TestDecimalFormatCurrencyParse() {
3597 UErrorCode status
= U_ZERO_ERROR
;
3598 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale("en_US"), status
);
3599 if (U_FAILURE(status
)) {
3604 UChar currency
= 0x00A4;
3605 // "\xA4#,##0.00;-\xA4#,##0.00"
3606 pat
.append(currency
).append(currency
).append(currency
).append("#,##0.00;-").append(currency
).append(currency
).append(currency
).append("#,##0.00");
3607 DecimalFormat
* fmt
= new DecimalFormat(pat
, sym
, status
);
3608 if (U_FAILURE(status
)) {
3610 errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3613 const char* DATA
[][2] = {
3615 // string to be parsed, the parsed result (number)
3618 {"1.00 US dollar", "1"},
3619 {"$1,234.56", "1234.56"},
3620 {"USD1,234.56", "1234.56"},
3621 {"1,234.56 US dollar", "1234.56"},
3623 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3624 fmt
->setLenient(TRUE
);
3625 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(DATA
); ++i
) {
3626 UnicodeString stringToBeParsed
= ctou(DATA
[i
][0]);
3627 double parsedResult
= atof(DATA
[i
][1]);
3628 UErrorCode status
= U_ZERO_ERROR
;
3630 fmt
->parse(stringToBeParsed
, result
, status
);
3631 logln((UnicodeString
)"Input: " + stringToBeParsed
+ "; output: " + result
.getDouble(status
));
3632 if (U_FAILURE(status
) ||
3633 (result
.getType() == Formattable::kDouble
&&
3634 result
.getDouble() != parsedResult
) ||
3635 (result
.getType() == Formattable::kLong
&&
3636 result
.getLong() != parsedResult
)) {
3637 errln((UnicodeString
)"FAIL parse: Expected " + parsedResult
);
3645 NumberFormatTest::TestCurrencyIsoPluralFormat() {
3646 static const char* DATA
[][6] = {
3649 // currency amount to be formatted,
3650 // currency ISO code to be formatted,
3651 // format result using CURRENCYSTYLE,
3652 // format result using ISOCURRENCYSTYLE,
3653 // format result using PLURALCURRENCYSTYLE,
3655 {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollars"},
3656 {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},
3657 {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD1,234.56", "-1,234.56 US dollars"},
3658 {"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00\\u7F8E\\u5143"},
3659 {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56\\u7F8E\\u5143"},
3660 {"zh_CN", "1", "CNY", "\\u00A51.00", "CNY1.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3661 {"zh_CN", "1234.56", "CNY", "\\u00A51,234.56", "CNY1,234.56", "1,234.56\\u4EBA\\u6C11\\u5E01"},
3662 {"ru_RU", "1", "RUB", "1,00\\u00A0\\u20BD", "1,00\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3663 {"ru_RU", "2", "RUB", "2,00\\u00A0\\u20BD", "2,00\\u00A0RUB", "2,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3664 {"ru_RU", "5", "RUB", "5,00\\u00A0\\u20BD", "5,00\\u00A0RUB", "5,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3665 // test locale without currency information
3666 {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3667 // test choice format
3668 {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"},
3670 static const UNumberFormatStyle currencyStyles
[] = {
3673 UNUM_CURRENCY_PLURAL
3676 for (int32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
3677 const char* localeString
= DATA
[i
][0];
3678 double numberToBeFormat
= atof(DATA
[i
][1]);
3679 const char* currencyISOCode
= DATA
[i
][2];
3680 logln(UnicodeString(u
"Locale: ") + localeString
+ "; amount: " + numberToBeFormat
);
3681 Locale
locale(localeString
);
3682 for (int32_t kIndex
= 0; kIndex
< UPRV_LENGTHOF(currencyStyles
); ++kIndex
) {
3683 UNumberFormatStyle k
= currencyStyles
[kIndex
];
3684 logln(UnicodeString(u
"UNumberFormatStyle: ") + k
);
3685 UErrorCode status
= U_ZERO_ERROR
;
3686 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, k
, status
);
3687 if (U_FAILURE(status
)) {
3689 dataerrln((UnicodeString
)"can not create instance, locale:" + localeString
+ ", style: " + k
+ " - " + u_errorName(status
));
3692 UChar currencyCode
[4];
3693 u_charsToUChars(currencyISOCode
, currencyCode
, 4);
3694 numFmt
->setCurrency(currencyCode
, status
);
3695 if (U_FAILURE(status
)) {
3697 errln((UnicodeString
)"can not set currency:" + currencyISOCode
);
3701 UnicodeString strBuf
;
3702 numFmt
->format(numberToBeFormat
, strBuf
);
3703 int resultDataIndex
= 3 + kIndex
;
3704 // DATA[i][resultDataIndex] is the currency format result
3705 // using 'k' currency style.
3706 UnicodeString formatResult
= ctou(DATA
[i
][resultDataIndex
]);
3707 if (strBuf
.compare(formatResult
)) {
3708 errln("FAIL: Expected " + formatResult
+ " actual: " + strBuf
);
3710 // test parsing, and test parsing for all currency formats.
3711 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3712 numFmt
->setLenient(TRUE
);
3713 for (int j
= 3; j
< 6; ++j
) {
3714 // DATA[i][3] is the currency format result using
3715 // CURRENCYSTYLE formatter.
3716 // DATA[i][4] is the currency format result using
3717 // ISOCURRENCYSTYLE formatter.
3718 // DATA[i][5] is the currency format result using
3719 // PLURALCURRENCYSTYLE formatter.
3720 UnicodeString oneCurrencyFormatResult
= ctou(DATA
[i
][j
]);
3721 UErrorCode status
= U_ZERO_ERROR
;
3722 Formattable parseResult
;
3723 numFmt
->parse(oneCurrencyFormatResult
, parseResult
, status
);
3724 if (U_FAILURE(status
) ||
3725 (parseResult
.getType() == Formattable::kDouble
&&
3726 parseResult
.getDouble() != numberToBeFormat
) ||
3727 (parseResult
.getType() == Formattable::kLong
&&
3728 parseResult
.getLong() != numberToBeFormat
)) {
3729 errln((UnicodeString
)"FAIL: getCurrencyFormat of locale " +
3730 localeString
+ " failed roundtripping the number");
3731 if (parseResult
.getType() == Formattable::kDouble
) {
3732 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual: " +parseResult
.getDouble());
3734 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual: " +parseResult
.getLong());
3744 NumberFormatTest::TestCurrencyParsing() {
3745 static const char* DATA
[][6] = {
3748 // currency amount to be formatted,
3749 // currency ISO code to be formatted,
3750 // format result using CURRENCYSTYLE,
3751 // format result using ISOCURRENCYSTYLE,
3752 // format result using PLURALCURRENCYSTYLE,
3753 {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
3754 {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
3755 {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
3756 {"ar_EG", "1", "USD", "\\u0661\\u066b\\u0660\\u0660\\u00a0US$", "\\u0661\\u066b\\u0660\\u0660\\u00a0USD", "\\u0661\\u066b\\u0660\\u0660 \\u062f\\u0648\\u0644\\u0627\\u0631 \\u0623\\u0645\\u0631\\u064a\\u0643\\u064a"},
3757 {"fa_CA", "1", "USD", "\\u200e$\\u06f1\\u066b\\u06f0\\u06f0", "\\u200eUSD\\u06f1\\u066b\\u06f0\\u06f0", "\\u06f1\\u066b\\u06f0\\u06f0 \\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627"},
3758 {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
3759 {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 ameri\\u010Dkih dolara"},
3760 {"id_ID", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 Dolar Amerika Serikat"},
3761 {"it_IT", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 dollari statunitensi"},
3762 {"ko_KR", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
3763 {"ja_JP", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00\\u7c73\\u30c9\\u30eb"},
3764 {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY\\u00A001.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3765 {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3766 {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3767 {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1 \\u65E5\\u5713"},
3768 {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY\\u00A01.00", "1\\u5186"},
3769 // ICU 62 requires #parseCurrency() to recognize variants when parsing
3770 // {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
3771 {"ru_RU", "1", "RUB", "1,00\\u00A0\\u00A0\\u20BD", "1,00\\u00A0\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}
3773 static const UNumberFormatStyle currencyStyles
[] = {
3776 UNUM_CURRENCY_PLURAL
3778 static const char* currencyStyleNames
[] = {
3780 "UNUM_CURRENCY_ISO",
3781 "UNUM_CURRENCY_PLURAL"
3784 #ifdef NUMFMTST_CACHE_DEBUG
3787 printf("loop: %d\n", deadloop
++);
3789 for (uint32_t i
=0; i
< UPRV_LENGTHOF(DATA
); ++i
) { /* i = test case # - should be i=0*/
3790 for (int32_t kIndex
= 2; kIndex
< UPRV_LENGTHOF(currencyStyles
); ++kIndex
) {
3791 UNumberFormatStyle k
= currencyStyles
[kIndex
]; /* k = style */
3792 const char* localeString
= DATA
[i
][0];
3793 double numberToBeFormat
= atof(DATA
[i
][1]);
3794 const char* currencyISOCode
= DATA
[i
][2];
3795 Locale
locale(localeString
);
3796 UErrorCode status
= U_ZERO_ERROR
;
3797 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, k
, status
);
3798 logln("#%d NumberFormat(%s, %s) Currency=%s\n",
3799 i
, localeString
, currencyStyleNames
[kIndex
],
3802 if (U_FAILURE(status
)) {
3804 dataerrln((UnicodeString
)"can not create instance, locale:" + localeString
+ ", style: " + k
+ " - " + u_errorName(status
));
3807 UChar currencyCode
[4];
3808 u_charsToUChars(currencyISOCode
, currencyCode
, 4);
3809 numFmt
->setCurrency(currencyCode
, status
);
3810 if (U_FAILURE(status
)) {
3812 errln((UnicodeString
)"can not set currency:" + currencyISOCode
);
3816 UnicodeString strBuf
;
3817 numFmt
->format(numberToBeFormat
, strBuf
);
3818 int resultDataIndex
= 3 + kIndex
;
3819 // DATA[i][resultDataIndex] is the currency format result
3820 // using 'k' currency style.
3821 UnicodeString formatResult
= ctou(DATA
[i
][resultDataIndex
]);
3822 if (strBuf
.compare(formatResult
)) {
3823 errln("FAIL: Expected " + formatResult
+ " actual: " + strBuf
);
3825 // test parsing, and test parsing for all currency formats.
3826 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3827 numFmt
->setLenient(TRUE
);
3828 for (int j
= 3; j
< 6; ++j
) {
3829 // DATA[i][3] is the currency format result using
3830 // CURRENCYSTYLE formatter.
3831 // DATA[i][4] is the currency format result using
3832 // ISOCURRENCYSTYLE formatter.
3833 // DATA[i][5] is the currency format result using
3834 // PLURALCURRENCYSTYLE formatter.
3835 UnicodeString oneCurrencyFormatResult
= ctou(DATA
[i
][j
]);
3836 UErrorCode status
= U_ZERO_ERROR
;
3837 Formattable parseResult
;
3838 logln("parse(%s)", DATA
[i
][j
]);
3839 numFmt
->parse(oneCurrencyFormatResult
, parseResult
, status
);
3840 if (U_FAILURE(status
) ||
3841 (parseResult
.getType() == Formattable::kDouble
&&
3842 parseResult
.getDouble() != numberToBeFormat
) ||
3843 (parseResult
.getType() == Formattable::kLong
&&
3844 parseResult
.getLong() != numberToBeFormat
)) {
3845 errln((UnicodeString
)"FAIL: NumberFormat(" + localeString
+", " + currencyStyleNames
[kIndex
] +
3846 "), Currency="+currencyISOCode
+", parse("+DATA
[i
][j
]+") returned error " + (UnicodeString
)u_errorName(status
)+". Testcase: data[" + i
+ "][" + currencyStyleNames
[j
-3] +"="+j
+"]");
3847 if (parseResult
.getType() == Formattable::kDouble
) {
3848 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual (double): " +parseResult
.getDouble());
3850 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual (long): " +parseResult
.getLong());
3852 errln((UnicodeString
)" round-trip would be: " + strBuf
);
3858 #ifdef NUMFMTST_CACHE_DEBUG
3865 NumberFormatTest::TestParseCurrencyInUCurr() {
3866 const char* DATA
[] = {
3867 "1.00 US DOLLAR", // case in-sensitive
3904 "Afghan Afghani (1927\\u20132002)1.00",
3905 "Afghan afghani (1927\\u20132002)1.00",
3906 "Afghan Afghani1.00",
3907 "Afghan Afghanis1.00",
3910 "Albanian lek\\u00eb1.00",
3911 "Algerian Dinar1.00",
3912 "Algerian dinar1.00",
3913 "Algerian dinars1.00",
3914 "Andorran Peseta1.00",
3915 "Andorran peseta1.00",
3916 "Andorran pesetas1.00",
3917 "Angolan Kwanza (1977\\u20131991)1.00",
3918 "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
3919 "Angolan Kwanza1.00",
3920 "Angolan New Kwanza (1990\\u20132000)1.00",
3921 "Angolan kwanza (1977\\u20131991)1.00",
3922 "Angolan readjusted kwanza (1995\\u20131999)1.00",
3923 "Angolan kwanza1.00",
3924 "Angolan kwanzas (1977\\u20131991)1.00",
3925 "Angolan readjusted kwanzas (1995\\u20131999)1.00",
3926 "Angolan kwanzas1.00",
3927 "Angolan new kwanza (1990\\u20132000)1.00",
3928 "Angolan new kwanzas (1990\\u20132000)1.00",
3929 "Argentine Austral1.00",
3930 "Argentine Peso (1983\\u20131985)1.00",
3931 "Argentine Peso1.00",
3932 "Argentine austral1.00",
3933 "Argentine australs1.00",
3934 "Argentine peso (1983\\u20131985)1.00",
3935 "Argentine peso1.00",
3936 "Argentine pesos (1983\\u20131985)1.00",
3937 "Argentine pesos1.00",
3938 "Armenian Dram1.00",
3939 "Armenian dram1.00",
3940 "Armenian drams1.00",
3941 "Aruban Florin1.00",
3942 "Aruban florin1.00",
3943 "Australian Dollar1.00",
3944 "Australian dollar1.00",
3945 "Australian dollars1.00",
3946 "Austrian Schilling1.00",
3947 "Austrian schilling1.00",
3948 "Austrian schillings1.00",
3949 "Azerbaijani Manat (1993\\u20132006)1.00",
3950 "Azerbaijani Manat1.00",
3951 "Azerbaijani manat (1993\\u20132006)1.00",
3952 "Azerbaijani manat1.00",
3953 "Azerbaijani manats (1993\\u20132006)1.00",
3954 "Azerbaijani manats1.00",
3998 "Bahamian Dollar1.00",
3999 "Bahamian dollar1.00",
4000 "Bahamian dollars1.00",
4001 "Bahraini Dinar1.00",
4002 "Bahraini dinar1.00",
4003 "Bahraini dinars1.00",
4004 "Bangladeshi Taka1.00",
4005 "Bangladeshi taka1.00",
4006 "Bangladeshi takas1.00",
4007 "Barbadian Dollar1.00",
4008 "Barbadian dollar1.00",
4009 "Barbadian dollars1.00",
4010 "Belarusian Ruble (1994\\u20131999)1.00",
4011 "Belarusian Ruble1.00",
4012 "Belarusian ruble (1994\\u20131999)1.00",
4013 "Belarusian rubles (1994\\u20131999)1.00",
4014 "Belarusian ruble1.00",
4015 "Belarusian rubles1.00",
4016 "Belgian Franc (convertible)1.00",
4017 "Belgian Franc (financial)1.00",
4018 "Belgian Franc1.00",
4019 "Belgian franc (convertible)1.00",
4020 "Belgian franc (financial)1.00",
4021 "Belgian franc1.00",
4022 "Belgian francs (convertible)1.00",
4023 "Belgian francs (financial)1.00",
4024 "Belgian francs1.00",
4025 "Belize Dollar1.00",
4026 "Belize dollar1.00",
4027 "Belize dollars1.00",
4028 "Bermudan Dollar1.00",
4029 "Bermudan dollar1.00",
4030 "Bermudan dollars1.00",
4031 "Bhutanese Ngultrum1.00",
4032 "Bhutanese ngultrum1.00",
4033 "Bhutanese ngultrums1.00",
4034 "Bolivian Mvdol1.00",
4035 "Bolivian Peso1.00",
4036 "Bolivian mvdol1.00",
4037 "Bolivian mvdols1.00",
4038 "Bolivian peso1.00",
4039 "Bolivian pesos1.00",
4040 "Bolivian Boliviano1.00",
4041 "Bolivian Boliviano1.00",
4042 "Bolivian Bolivianos1.00",
4043 "Bosnia-Herzegovina Convertible Mark1.00",
4044 "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
4045 "Bosnia-Herzegovina convertible mark1.00",
4046 "Bosnia-Herzegovina convertible marks1.00",
4047 "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
4048 "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
4049 "Botswanan Pula1.00",
4050 "Botswanan pula1.00",
4051 "Botswanan pulas1.00",
4052 "Brazilian New Cruzado (1989\\u20131990)1.00",
4053 "Brazilian Cruzado (1986\\u20131989)1.00",
4054 "Brazilian Cruzeiro (1990\\u20131993)1.00",
4055 "Brazilian New Cruzeiro (1967\\u20131986)1.00",
4056 "Brazilian Cruzeiro (1993\\u20131994)1.00",
4057 "Brazilian Real1.00",
4058 "Brazilian new cruzado (1989\\u20131990)1.00",
4059 "Brazilian new cruzados (1989\\u20131990)1.00",
4060 "Brazilian cruzado (1986\\u20131989)1.00",
4061 "Brazilian cruzados (1986\\u20131989)1.00",
4062 "Brazilian cruzeiro (1990\\u20131993)1.00",
4063 "Brazilian new cruzeiro (1967\\u20131986)1.00",
4064 "Brazilian cruzeiro (1993\\u20131994)1.00",
4065 "Brazilian cruzeiros (1990\\u20131993)1.00",
4066 "Brazilian new cruzeiros (1967\\u20131986)1.00",
4067 "Brazilian cruzeiros (1993\\u20131994)1.00",
4068 "Brazilian real1.00",
4069 "Brazilian reals1.00",
4070 "British Pound1.00",
4071 "British pound1.00",
4072 "British pounds1.00",
4073 "Brunei Dollar1.00",
4074 "Brunei dollar1.00",
4075 "Brunei dollars1.00",
4076 "Bulgarian Hard Lev1.00",
4077 "Bulgarian Lev1.00",
4078 "Bulgarian Leva1.00",
4079 "Bulgarian hard lev1.00",
4080 "Bulgarian hard leva1.00",
4081 "Bulgarian lev1.00",
4084 "Burmese kyats1.00",
4085 "Burundian Franc1.00",
4086 "Burundian franc1.00",
4087 "Burundian francs1.00",
4092 "West African CFA Franc1.00",
4093 "Central African CFA Franc1.00",
4094 "West African CFA franc1.00",
4095 "Central African CFA franc1.00",
4096 "West African CFA francs1.00",
4097 "Central African CFA francs1.00",
4124 "Cambodian Riel1.00",
4125 "Cambodian riel1.00",
4126 "Cambodian riels1.00",
4127 "Canadian Dollar1.00",
4128 "Canadian dollar1.00",
4129 "Canadian dollars1.00",
4130 "Cape Verdean Escudo1.00",
4131 "Cape Verdean escudo1.00",
4132 "Cape Verdean escudos1.00",
4133 "Cayman Islands Dollar1.00",
4134 "Cayman Islands dollar1.00",
4135 "Cayman Islands dollars1.00",
4137 "Chilean Unit of Account (UF)1.00",
4139 "Chilean pesos1.00",
4140 "Chilean unit of account (UF)1.00",
4141 "Chilean units of account (UF)1.00",
4144 "Colombian Peso1.00",
4145 "Colombian peso1.00",
4146 "Colombian pesos1.00",
4147 "Comorian Franc1.00",
4148 "Comorian franc1.00",
4149 "Comorian francs1.00",
4150 "Congolese Franc1.00",
4151 "Congolese franc1.00",
4152 "Congolese francs1.00",
4153 "Costa Rican Col\\u00f3n1.00",
4154 "Costa Rican col\\u00f3n1.00",
4155 "Costa Rican col\\u00f3ns1.00",
4156 "Croatian Dinar1.00",
4157 "Croatian Kuna1.00",
4158 "Croatian dinar1.00",
4159 "Croatian dinars1.00",
4160 "Croatian kuna1.00",
4161 "Croatian kunas1.00",
4165 "Cypriot Pound1.00",
4166 "Cypriot pound1.00",
4167 "Cypriot pounds1.00",
4170 "Czech korunas1.00",
4171 "Czechoslovak Hard Koruna1.00",
4172 "Czechoslovak hard koruna1.00",
4173 "Czechoslovak hard korunas1.00",
4184 "Danish kroner1.00",
4188 "Djiboutian Franc1.00",
4189 "Djiboutian franc1.00",
4190 "Djiboutian francs1.00",
4191 "Dominican Peso1.00",
4192 "Dominican peso1.00",
4193 "Dominican pesos1.00",
4212 "East Caribbean Dollar1.00",
4213 "East Caribbean dollar1.00",
4214 "East Caribbean dollars1.00",
4215 "East German Mark1.00",
4216 "East German mark1.00",
4217 "East German marks1.00",
4218 "Ecuadorian Sucre1.00",
4219 "Ecuadorian Unit of Constant Value1.00",
4220 "Ecuadorian sucre1.00",
4221 "Ecuadorian sucres1.00",
4222 "Ecuadorian unit of constant value1.00",
4223 "Ecuadorian units of constant value1.00",
4224 "Egyptian Pound1.00",
4225 "Egyptian pound1.00",
4226 "Egyptian pounds1.00",
4227 "Salvadoran Col\\u00f3n1.00",
4228 "Salvadoran col\\u00f3n1.00",
4229 "Salvadoran colones1.00",
4230 "Equatorial Guinean Ekwele1.00",
4231 "Equatorial Guinean ekwele1.00",
4232 "Eritrean Nakfa1.00",
4233 "Eritrean nakfa1.00",
4234 "Eritrean nakfas1.00",
4235 "Estonian Kroon1.00",
4236 "Estonian kroon1.00",
4237 "Estonian kroons1.00",
4238 "Ethiopian Birr1.00",
4239 "Ethiopian birr1.00",
4240 "Ethiopian birrs1.00",
4242 "European Composite Unit1.00",
4243 "European Currency Unit1.00",
4244 "European Monetary Unit1.00",
4245 "European Unit of Account (XBC)1.00",
4246 "European Unit of Account (XBD)1.00",
4247 "European composite unit1.00",
4248 "European composite units1.00",
4249 "European currency unit1.00",
4250 "European currency units1.00",
4251 "European monetary unit1.00",
4252 "European monetary units1.00",
4253 "European unit of account (XBC)1.00",
4254 "European unit of account (XBD)1.00",
4255 "European units of account (XBC)1.00",
4256 "European units of account (XBD)1.00",
4264 "Falkland Islands Pound1.00",
4265 "Falkland Islands pound1.00",
4266 "Falkland Islands pounds1.00",
4267 "Fijian Dollar1.00",
4268 "Fijian dollar1.00",
4269 "Fijian dollars1.00",
4270 "Finnish Markka1.00",
4271 "Finnish markka1.00",
4272 "Finnish markkas1.00",
4275 "French Gold Franc1.00",
4276 "French UIC-Franc1.00",
4277 "French UIC-franc1.00",
4278 "French UIC-francs1.00",
4280 "French francs1.00",
4281 "French gold franc1.00",
4282 "French gold francs1.00",
4307 "Gambian Dalasi1.00",
4308 "Gambian dalasi1.00",
4309 "Gambian dalasis1.00",
4310 "Georgian Kupon Larit1.00",
4311 "Georgian Lari1.00",
4312 "Georgian kupon larit1.00",
4313 "Georgian kupon larits1.00",
4314 "Georgian lari1.00",
4315 "Georgian laris1.00",
4316 "Ghanaian Cedi (1979\\u20132007)1.00",
4317 "Ghanaian Cedi1.00",
4318 "Ghanaian cedi (1979\\u20132007)1.00",
4319 "Ghanaian cedi1.00",
4320 "Ghanaian cedis (1979\\u20132007)1.00",
4321 "Ghanaian cedis1.00",
4322 "Gibraltar Pound1.00",
4323 "Gibraltar pound1.00",
4324 "Gibraltar pounds1.00",
4327 "Greek Drachma1.00",
4328 "Greek drachma1.00",
4329 "Greek drachmas1.00",
4330 "Guatemalan Quetzal1.00",
4331 "Guatemalan quetzal1.00",
4332 "Guatemalan quetzals1.00",
4333 "Guinean Franc1.00",
4335 "Guinean franc1.00",
4336 "Guinean francs1.00",
4338 "Guinean sylis1.00",
4339 "Guinea-Bissau Peso1.00",
4340 "Guinea-Bissau peso1.00",
4341 "Guinea-Bissau pesos1.00",
4342 "Guyanaese Dollar1.00",
4343 "Guyanaese dollar1.00",
4344 "Guyanaese dollars1.00",
4355 "Haitian Gourde1.00",
4356 "Haitian gourde1.00",
4357 "Haitian gourdes1.00",
4358 "Honduran Lempira1.00",
4359 "Honduran lempira1.00",
4360 "Honduran lempiras1.00",
4361 "Hong Kong Dollar1.00",
4362 "Hong Kong dollar1.00",
4363 "Hong Kong dollars1.00",
4364 "Hungarian Forint1.00",
4365 "Hungarian forint1.00",
4366 "Hungarian forints1.00",
4378 "Icelandic Kr\\u00f3na1.00",
4379 "Icelandic kr\\u00f3na1.00",
4380 "Icelandic kr\\u00f3nur1.00",
4383 "Indian rupees1.00",
4384 "Indonesian Rupiah1.00",
4385 "Indonesian rupiah1.00",
4386 "Indonesian rupiahs1.00",
4389 "Iranian rials1.00",
4396 "Israeli Pound1.00",
4397 "Israeli new shekel1.00",
4398 "Israeli pound1.00",
4399 "Israeli pounds1.00",
4402 "Italian liras1.00",
4406 "Jamaican Dollar1.00",
4407 "Jamaican dollar1.00",
4408 "Jamaican dollars1.00",
4411 "Jordanian Dinar1.00",
4412 "Jordanian dinar1.00",
4413 "Jordanian dinars1.00",
4425 "Kazakhstani Tenge1.00",
4426 "Kazakhstani tenge1.00",
4427 "Kazakhstani tenges1.00",
4428 "Kenyan Shilling1.00",
4429 "Kenyan shilling1.00",
4430 "Kenyan shillings1.00",
4431 "Kuwaiti Dinar1.00",
4432 "Kuwaiti dinar1.00",
4433 "Kuwaiti dinars1.00",
4434 "Kyrgystani Som1.00",
4435 "Kyrgystani som1.00",
4436 "Kyrgystani soms1.00",
4464 "Latvian Ruble1.00",
4467 "Latvian ruble1.00",
4468 "Latvian rubles1.00",
4469 "Lebanese Pound1.00",
4470 "Lebanese pound1.00",
4471 "Lebanese pounds1.00",
4474 "Lesotho lotis1.00",
4475 "Liberian Dollar1.00",
4476 "Liberian dollar1.00",
4477 "Liberian dollars1.00",
4480 "Libyan dinars1.00",
4481 "Lithuanian Litas1.00",
4482 "Lithuanian Talonas1.00",
4483 "Lithuanian litas1.00",
4484 "Lithuanian litai1.00",
4485 "Lithuanian talonas1.00",
4486 "Lithuanian talonases1.00",
4487 "Luxembourgian Convertible Franc1.00",
4488 "Luxembourg Financial Franc1.00",
4489 "Luxembourgian Franc1.00",
4490 "Luxembourgian convertible franc1.00",
4491 "Luxembourgian convertible francs1.00",
4492 "Luxembourg financial franc1.00",
4493 "Luxembourg financial francs1.00",
4494 "Luxembourgian franc1.00",
4495 "Luxembourgian francs1.00",
4534 "Macanese Pataca1.00",
4535 "Macanese pataca1.00",
4536 "Macanese patacas1.00",
4537 "Macedonian Denar1.00",
4538 "Macedonian denar1.00",
4539 "Macedonian denari1.00",
4540 "Malagasy Ariaries1.00",
4541 "Malagasy Ariary1.00",
4542 "Malagasy Ariary1.00",
4543 "Malagasy Franc1.00",
4544 "Malagasy franc1.00",
4545 "Malagasy francs1.00",
4546 "Malawian Kwacha1.00",
4547 "Malawian Kwacha1.00",
4548 "Malawian Kwachas1.00",
4549 "Malaysian Ringgit1.00",
4550 "Malaysian ringgit1.00",
4551 "Malaysian ringgits1.00",
4552 "Maldivian Rufiyaa1.00",
4553 "Maldivian rufiyaa1.00",
4554 "Maldivian rufiyaas1.00",
4557 "Malian francs1.00",
4559 "Maltese Pound1.00",
4562 "Maltese pound1.00",
4563 "Maltese pounds1.00",
4564 "Mauritanian Ouguiya1.00",
4565 "Mauritanian ouguiya1.00",
4566 "Mauritanian ouguiyas1.00",
4567 "Mauritian Rupee1.00",
4568 "Mauritian rupee1.00",
4569 "Mauritian rupees1.00",
4571 "Mexican Silver Peso (1861\\u20131992)1.00",
4572 "Mexican Investment Unit1.00",
4574 "Mexican pesos1.00",
4575 "Mexican silver peso (1861\\u20131992)1.00",
4576 "Mexican silver pesos (1861\\u20131992)1.00",
4577 "Mexican investment unit1.00",
4578 "Mexican investment units1.00",
4582 "Mongolian Tugrik1.00",
4583 "Mongolian tugrik1.00",
4584 "Mongolian tugriks1.00",
4585 "Moroccan Dirham1.00",
4586 "Moroccan Franc1.00",
4587 "Moroccan dirham1.00",
4588 "Moroccan dirhams1.00",
4589 "Moroccan franc1.00",
4590 "Moroccan francs1.00",
4591 "Mozambican Escudo1.00",
4592 "Mozambican Metical1.00",
4593 "Mozambican escudo1.00",
4594 "Mozambican escudos1.00",
4595 "Mozambican metical1.00",
4596 "Mozambican meticals1.00",
4599 "Myanmar kyats1.00",
4612 "Namibian Dollar1.00",
4613 "Namibian dollar1.00",
4614 "Namibian dollars1.00",
4615 "Nepalese Rupee1.00",
4616 "Nepalese rupee1.00",
4617 "Nepalese rupees1.00",
4618 "Netherlands Antillean Guilder1.00",
4619 "Netherlands Antillean guilder1.00",
4620 "Netherlands Antillean guilders1.00",
4621 "Dutch Guilder1.00",
4622 "Dutch guilder1.00",
4623 "Dutch guilders1.00",
4624 "Israeli New Shekel1.00",
4625 "Israeli New Shekels1.00",
4626 "New Zealand Dollar1.00",
4627 "New Zealand dollar1.00",
4628 "New Zealand dollars1.00",
4629 "Nicaraguan C\\u00f3rdoba1.00",
4630 "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00",
4631 "Nicaraguan c\\u00f3rdoba1.00",
4632 "Nicaraguan c\\u00f3rdobas1.00",
4633 "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00",
4634 "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00",
4635 "Nigerian Naira1.00",
4636 "Nigerian naira1.00",
4637 "Nigerian nairas1.00",
4638 "North Korean Won1.00",
4639 "North Korean won1.00",
4640 "North Korean won1.00",
4641 "Norwegian Krone1.00",
4642 "Norwegian krone1.00",
4643 "Norwegian kroner1.00",
4645 "Mozambican Metical (1980\\u20132006)1.00",
4646 "Mozambican metical (1980\\u20132006)1.00",
4647 "Mozambican meticals (1980\\u20132006)1.00",
4648 "Romanian Lei (1952\\u20132006)1.00",
4649 "Romanian Leu (1952\\u20132006)1.00",
4650 "Romanian leu (1952\\u20132006)1.00",
4651 "Serbian Dinar (2002\\u20132006)1.00",
4652 "Serbian dinar (2002\\u20132006)1.00",
4653 "Serbian dinars (2002\\u20132006)1.00",
4654 "Sudanese Dinar (1992\\u20132007)1.00",
4655 "Sudanese Pound (1957\\u20131998)1.00",
4656 "Sudanese dinar (1992\\u20132007)1.00",
4657 "Sudanese dinars (1992\\u20132007)1.00",
4658 "Sudanese pound (1957\\u20131998)1.00",
4659 "Sudanese pounds (1957\\u20131998)1.00",
4660 "Turkish Lira (1922\\u20132005)1.00",
4661 "Turkish Lira (1922\\u20132005)1.00",
4683 "Pakistani Rupee1.00",
4684 "Pakistani rupee1.00",
4685 "Pakistani rupees1.00",
4688 "Panamanian Balboa1.00",
4689 "Panamanian balboa1.00",
4690 "Panamanian balboas1.00",
4691 "Papua New Guinean Kina1.00",
4692 "Papua New Guinean kina1.00",
4693 "Papua New Guinean kina1.00",
4694 "Paraguayan Guarani1.00",
4695 "Paraguayan guarani1.00",
4696 "Paraguayan guaranis1.00",
4697 "Peruvian Inti1.00",
4699 "Peruvian Sol (1863\\u20131965)1.00",
4700 "Peruvian inti1.00",
4701 "Peruvian intis1.00",
4703 "Peruvian soles1.00",
4704 "Peruvian sol (1863\\u20131965)1.00",
4705 "Peruvian soles (1863\\u20131965)1.00",
4706 "Philippine Piso1.00",
4707 "Philippine piso1.00",
4708 "Philippine pisos1.00",
4711 "Polish Zloty (1950\\u20131995)1.00",
4713 "Polish zlotys1.00",
4714 "Polish zloty (PLZ)1.00",
4716 "Polish zlotys (PLZ)1.00",
4717 "Portuguese Escudo1.00",
4718 "Portuguese Guinea Escudo1.00",
4719 "Portuguese Guinea escudo1.00",
4720 "Portuguese Guinea escudos1.00",
4721 "Portuguese escudo1.00",
4722 "Portuguese escudos1.00",
4744 "Rhodesian Dollar1.00",
4745 "Rhodesian dollar1.00",
4746 "Rhodesian dollars1.00",
4750 "Russian Ruble (1991\\u20131998)1.00",
4751 "Russian Ruble1.00",
4752 "Russian ruble (1991\\u20131998)1.00",
4753 "Russian ruble1.00",
4754 "Russian rubles (1991\\u20131998)1.00",
4755 "Russian rubles1.00",
4756 "Rwandan Franc1.00",
4757 "Rwandan franc1.00",
4758 "Rwandan francs1.00",
4788 "St. Helena Pound1.00",
4789 "St. Helena pound1.00",
4790 "St. Helena pounds1.00",
4791 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra1.00",
4792 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra1.00",
4793 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras1.00",
4797 "Serbian Dinar1.00",
4798 "Serbian dinar1.00",
4799 "Serbian dinars1.00",
4800 "Seychellois Rupee1.00",
4801 "Seychellois rupee1.00",
4802 "Seychellois rupees1.00",
4803 "Sierra Leonean Leone1.00",
4804 "Sierra Leonean leone1.00",
4805 "Sierra Leonean leones1.00",
4808 "Singapore Dollar1.00",
4809 "Singapore dollar1.00",
4810 "Singapore dollars1.00",
4811 "Slovak Koruna1.00",
4812 "Slovak koruna1.00",
4813 "Slovak korunas1.00",
4814 "Slovenian Tolar1.00",
4815 "Slovenian tolar1.00",
4816 "Slovenian tolars1.00",
4817 "Solomon Islands Dollar1.00",
4818 "Solomon Islands dollar1.00",
4819 "Solomon Islands dollars1.00",
4820 "Somali Shilling1.00",
4821 "Somali shilling1.00",
4822 "Somali shillings1.00",
4823 "South African Rand (financial)1.00",
4824 "South African Rand1.00",
4825 "South African rand (financial)1.00",
4826 "South African rand1.00",
4827 "South African rands (financial)1.00",
4828 "South African rand1.00",
4829 "South Korean Won1.00",
4830 "South Korean won1.00",
4831 "South Korean won1.00",
4832 "Soviet Rouble1.00",
4833 "Soviet rouble1.00",
4834 "Soviet roubles1.00",
4835 "Spanish Peseta (A account)1.00",
4836 "Spanish Peseta (convertible account)1.00",
4837 "Spanish Peseta1.00",
4838 "Spanish peseta (A account)1.00",
4839 "Spanish peseta (convertible account)1.00",
4840 "Spanish peseta1.00",
4841 "Spanish pesetas (A account)1.00",
4842 "Spanish pesetas (convertible account)1.00",
4843 "Spanish pesetas1.00",
4844 "Special Drawing Rights1.00",
4845 "Sri Lankan Rupee1.00",
4846 "Sri Lankan rupee1.00",
4847 "Sri Lankan rupees1.00",
4848 "Sudanese Pound1.00",
4849 "Sudanese pound1.00",
4850 "Sudanese pounds1.00",
4851 "Surinamese Dollar1.00",
4852 "Surinamese dollar1.00",
4853 "Surinamese dollars1.00",
4854 "Surinamese Guilder1.00",
4855 "Surinamese guilder1.00",
4856 "Surinamese guilders1.00",
4857 "Swazi Lilangeni1.00",
4858 "Swazi lilangeni1.00",
4859 "Swazi emalangeni1.00",
4860 "Swedish Krona1.00",
4861 "Swedish krona1.00",
4862 "Swedish kronor1.00",
4868 "Syrian pounds1.00",
4887 "New Taiwan Dollar1.00",
4888 "New Taiwan dollar1.00",
4889 "New Taiwan dollars1.00",
4890 "Tajikistani Ruble1.00",
4891 "Tajikistani Somoni1.00",
4892 "Tajikistani ruble1.00",
4893 "Tajikistani rubles1.00",
4894 "Tajikistani somoni1.00",
4895 "Tajikistani somonis1.00",
4896 "Tanzanian Shilling1.00",
4897 "Tanzanian shilling1.00",
4898 "Tanzanian shillings1.00",
4899 "Testing Currency Code1.00",
4900 "Testing Currency Code1.00",
4904 "Timorese Escudo1.00",
4905 "Timorese escudo1.00",
4906 "Timorese escudos1.00",
4907 "Tongan Pa\\u02bbanga1.00",
4908 "Tongan pa\\u02bbanga1.00",
4909 "Tongan pa\\u02bbanga1.00",
4910 "Trinidad & Tobago Dollar1.00",
4911 "Trinidad & Tobago dollar1.00",
4912 "Trinidad & Tobago dollars1.00",
4913 "Tunisian Dinar1.00",
4914 "Tunisian dinar1.00",
4915 "Tunisian dinars1.00",
4919 "Turkmenistani Manat1.00",
4920 "Turkmenistani manat1.00",
4921 "Turkmenistani manat1.00",
4930 "US Dollar (Next day)1.00",
4931 "US Dollar (Same day)1.00",
4933 "US dollar (next day)1.00",
4934 "US dollar (same day)1.00",
4936 "US dollars (next day)1.00",
4937 "US dollars (same day)1.00",
4951 "Ugandan Shilling (1966\\u20131987)1.00",
4952 "Ugandan Shilling1.00",
4953 "Ugandan shilling (1966\\u20131987)1.00",
4954 "Ugandan shilling1.00",
4955 "Ugandan shillings (1966\\u20131987)1.00",
4956 "Ugandan shillings1.00",
4957 "Ukrainian Hryvnia1.00",
4958 "Ukrainian Karbovanets1.00",
4959 "Ukrainian hryvnia1.00",
4960 "Ukrainian hryvnias1.00",
4961 "Ukrainian karbovanets1.00",
4962 "Ukrainian karbovantsiv1.00",
4963 "Colombian Real Value Unit1.00",
4964 "United Arab Emirates Dirham1.00",
4965 "Unknown Currency1.00",
4966 "Uruguayan Peso (1975\\u20131993)1.00",
4967 "Uruguayan Peso1.00",
4968 "Uruguayan Peso (Indexed Units)1.00",
4969 "Uruguayan peso (1975\\u20131993)1.00",
4970 "Uruguayan peso (indexed units)1.00",
4971 "Uruguayan peso1.00",
4972 "Uruguayan pesos (1975\\u20131993)1.00",
4973 "Uruguayan pesos (indexed units)1.00",
4974 "Uruguayan pesos1.00",
4975 "Uzbekistani Som1.00",
4976 "Uzbekistani som1.00",
4977 "Uzbekistani som1.00",
4984 "Vanuatu vatus1.00",
4985 "Venezuelan Bol\\u00edvar1.00",
4986 "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00",
4987 "Venezuelan bol\\u00edvar1.00",
4988 "Venezuelan bol\\u00edvars1.00",
4989 "Venezuelan bol\\u00edvar (1871\\u20132008)1.00",
4990 "Venezuelan bol\\u00edvars (1871\\u20132008)1.00",
4991 "Vietnamese Dong1.00",
4992 "Vietnamese dong1.00",
4993 "Vietnamese dong1.00",
5053 "Yemeni dinars1.00",
5056 "Yugoslavian Convertible Dinar (1990\\u20131992)1.00",
5057 "Yugoslavian Hard Dinar (1966\\u20131990)1.00",
5058 "Yugoslavian New Dinar (1994\\u20132002)1.00",
5059 "Yugoslavian convertible dinar (1990\\u20131992)1.00",
5060 "Yugoslavian convertible dinars (1990\\u20131992)1.00",
5061 "Yugoslavian hard dinar (1966\\u20131990)1.00",
5062 "Yugoslavian hard dinars (1966\\u20131990)1.00",
5063 "Yugoslavian new dinar (1994\\u20132002)1.00",
5064 "Yugoslavian new dinars (1994\\u20132002)1.00",
5075 "Zairean New Zaire (1993\\u20131998)1.00",
5076 "Zairean Zaire (1971\\u20131993)1.00",
5077 "Zairean new zaire (1993\\u20131998)1.00",
5078 "Zairean new zaires (1993\\u20131998)1.00",
5079 "Zairean zaire (1971\\u20131993)1.00",
5080 "Zairean zaires (1971\\u20131993)1.00",
5081 "Zambian Kwacha1.00",
5082 "Zambian kwacha1.00",
5083 "Zambian kwachas1.00",
5084 "Zimbabwean Dollar (1980\\u20132008)1.00",
5085 "Zimbabwean dollar (1980\\u20132008)1.00",
5086 "Zimbabwean dollars (1980\\u20132008)1.00",
5089 "Turkish lira (1922\\u20132005)1.00",
5090 "special drawing rights1.00",
5091 "Colombian real value unit1.00",
5092 "Colombian real value units1.00",
5093 "unknown currency1.00",
5101 // Following has extra text, should be parsed correctly too
5104 "1.00 US dollar random",
5105 "1.00 US dollars random",
5106 "1.00 Afghan Afghani random",
5107 "1.00 Afghan Afghani random",
5108 "1.00 Afghan Afghanis (1927\\u20131992) random",
5109 "1.00 Afghan Afghanis random",
5110 "1.00 Albanian Lek random",
5111 "1.00 Albanian lek random",
5112 "1.00 Albanian lek\\u00eb random",
5113 "1.00 Algerian Dinar random",
5114 "1.00 Algerian dinar random",
5115 "1.00 Algerian dinars random",
5116 "1.00 Andorran Peseta random",
5117 "1.00 Andorran peseta random",
5118 "1.00 Andorran pesetas random",
5119 "1.00 Angolan Kwanza (1977\\u20131990) random",
5120 "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random",
5121 "1.00 Angolan Kwanza random",
5122 "1.00 Angolan New Kwanza (1990\\u20132000) random",
5123 "1.00 Angolan kwanza (1977\\u20131991) random",
5124 "1.00 Angolan readjusted kwanza (1995\\u20131999) random",
5125 "1.00 Angolan kwanza random",
5126 "1.00 Angolan kwanzas (1977\\u20131991) random",
5127 "1.00 Angolan readjusted kwanzas (1995\\u20131999) random",
5128 "1.00 Angolan kwanzas random",
5129 "1.00 Angolan new kwanza (1990\\u20132000) random",
5130 "1.00 Angolan new kwanzas (1990\\u20132000) random",
5131 "1.00 Argentine Austral random",
5132 "1.00 Argentine Peso (1983\\u20131985) random",
5133 "1.00 Argentine Peso random",
5134 "1.00 Argentine austral random",
5135 "1.00 Argentine australs random",
5136 "1.00 Argentine peso (1983\\u20131985) random",
5137 "1.00 Argentine peso random",
5138 "1.00 Argentine pesos (1983\\u20131985) random",
5139 "1.00 Argentine pesos random",
5140 "1.00 Armenian Dram random",
5141 "1.00 Armenian dram random",
5142 "1.00 Armenian drams random",
5143 "1.00 Aruban Florin random",
5144 "1.00 Aruban florin random",
5145 "1.00 Australian Dollar random",
5146 "1.00 Australian dollar random",
5147 "1.00 Australian dollars random",
5148 "1.00 Austrian Schilling random",
5149 "1.00 Austrian schilling random",
5150 "1.00 Austrian schillings random",
5151 "1.00 Azerbaijani Manat (1993\\u20132006) random",
5152 "1.00 Azerbaijani Manat random",
5153 "1.00 Azerbaijani manat (1993\\u20132006) random",
5154 "1.00 Azerbaijani manat random",
5155 "1.00 Azerbaijani manats (1993\\u20132006) random",
5156 "1.00 Azerbaijani manats random",
5157 "1.00 Bahamian Dollar random",
5158 "1.00 Bahamian dollar random",
5159 "1.00 Bahamian dollars random",
5160 "1.00 Bahraini Dinar random",
5161 "1.00 Bahraini dinar random",
5162 "1.00 Bahraini dinars random",
5163 "1.00 Bangladeshi Taka random",
5164 "1.00 Bangladeshi taka random",
5165 "1.00 Bangladeshi takas random",
5166 "1.00 Barbadian Dollar random",
5167 "1.00 Barbadian dollar random",
5168 "1.00 Barbadian dollars random",
5169 "1.00 Belarusian Ruble (1994\\u20131999) random",
5170 "1.00 Belarusian Ruble random",
5171 "1.00 Belarusian ruble (1994\\u20131999) random",
5172 "1.00 Belarusian rubles (1994\\u20131999) random",
5173 "1.00 Belarusian ruble random",
5174 "1.00 Belarusian rubles random",
5175 "1.00 Belgian Franc (convertible) random",
5176 "1.00 Belgian Franc (financial) random",
5177 "1.00 Belgian Franc random",
5178 "1.00 Belgian franc (convertible) random",
5179 "1.00 Belgian franc (financial) random",
5180 "1.00 Belgian franc random",
5181 "1.00 Belgian francs (convertible) random",
5182 "1.00 Belgian francs (financial) random",
5183 "1.00 Belgian francs random",
5184 "1.00 Belize Dollar random",
5185 "1.00 Belize dollar random",
5186 "1.00 Belize dollars random",
5187 "1.00 Bermudan Dollar random",
5188 "1.00 Bermudan dollar random",
5189 "1.00 Bermudan dollars random",
5190 "1.00 Bhutanese Ngultrum random",
5191 "1.00 Bhutanese ngultrum random",
5192 "1.00 Bhutanese ngultrums random",
5193 "1.00 Bolivian Mvdol random",
5194 "1.00 Bolivian Peso random",
5195 "1.00 Bolivian mvdol random",
5196 "1.00 Bolivian mvdols random",
5197 "1.00 Bolivian peso random",
5198 "1.00 Bolivian pesos random",
5199 "1.00 Bolivian Boliviano random",
5200 "1.00 Bolivian Boliviano random",
5201 "1.00 Bolivian Bolivianos random",
5202 "1.00 Bosnia-Herzegovina Convertible Mark random",
5203 "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random",
5204 "1.00 Bosnia-Herzegovina convertible mark random",
5205 "1.00 Bosnia-Herzegovina convertible marks random",
5206 "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random",
5207 "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random",
5208 "1.00 Botswanan Pula random",
5209 "1.00 Botswanan pula random",
5210 "1.00 Botswanan pulas random",
5211 "1.00 Brazilian New Cruzado (1989\\u20131990) random",
5212 "1.00 Brazilian Cruzado (1986\\u20131989) random",
5213 "1.00 Brazilian Cruzeiro (1990\\u20131993) random",
5214 "1.00 Brazilian New Cruzeiro (1967\\u20131986) random",
5215 "1.00 Brazilian Cruzeiro (1993\\u20131994) random",
5216 "1.00 Brazilian Real random",
5217 "1.00 Brazilian new cruzado (1989\\u20131990) random",
5218 "1.00 Brazilian new cruzados (1989\\u20131990) random",
5219 "1.00 Brazilian cruzado (1986\\u20131989) random",
5220 "1.00 Brazilian cruzados (1986\\u20131989) random",
5221 "1.00 Brazilian cruzeiro (1990\\u20131993) random",
5222 "1.00 Brazilian new cruzeiro (1967\\u20131986) random",
5223 "1.00 Brazilian cruzeiro (1993\\u20131994) random",
5224 "1.00 Brazilian cruzeiros (1990\\u20131993) random",
5225 "1.00 Brazilian new cruzeiros (1967\\u20131986) random",
5226 "1.00 Brazilian cruzeiros (1993\\u20131994) random",
5227 "1.00 Brazilian real random",
5228 "1.00 Brazilian reals random",
5229 "1.00 British Pound random",
5230 "1.00 British pound random",
5231 "1.00 British pounds random",
5232 "1.00 Brunei Dollar random",
5233 "1.00 Brunei dollar random",
5234 "1.00 Brunei dollars random",
5235 "1.00 Bulgarian Hard Lev random",
5236 "1.00 Bulgarian Lev random",
5237 "1.00 Bulgarian Leva random",
5238 "1.00 Bulgarian hard lev random",
5239 "1.00 Bulgarian hard leva random",
5240 "1.00 Bulgarian lev random",
5241 "1.00 Burmese Kyat random",
5242 "1.00 Burmese kyat random",
5243 "1.00 Burmese kyats random",
5244 "1.00 Burundian Franc random",
5245 "1.00 Burundian franc random",
5246 "1.00 Burundian francs random",
5247 "1.00 Cambodian Riel random",
5248 "1.00 Cambodian riel random",
5249 "1.00 Cambodian riels random",
5250 "1.00 Canadian Dollar random",
5251 "1.00 Canadian dollar random",
5252 "1.00 Canadian dollars random",
5253 "1.00 Cape Verdean Escudo random",
5254 "1.00 Cape Verdean escudo random",
5255 "1.00 Cape Verdean escudos random",
5256 "1.00 Cayman Islands Dollar random",
5257 "1.00 Cayman Islands dollar random",
5258 "1.00 Cayman Islands dollars random",
5259 "1.00 Chilean Peso random",
5260 "1.00 Chilean Unit of Account (UF) random",
5261 "1.00 Chilean peso random",
5262 "1.00 Chilean pesos random",
5263 "1.00 Chilean unit of account (UF) random",
5264 "1.00 Chilean units of account (UF) random",
5265 "1.00 Chinese Yuan random",
5266 "1.00 Chinese yuan random",
5267 "1.00 Colombian Peso random",
5268 "1.00 Colombian peso random",
5269 "1.00 Colombian pesos random",
5270 "1.00 Comorian Franc random",
5271 "1.00 Comorian franc random",
5272 "1.00 Comorian francs random",
5273 "1.00 Congolese Franc Congolais random",
5274 "1.00 Congolese franc Congolais random",
5275 "1.00 Congolese francs Congolais random",
5276 "1.00 Costa Rican Col\\u00f3n random",
5277 "1.00 Costa Rican col\\u00f3n random",
5278 "1.00 Costa Rican col\\u00f3ns random",
5279 "1.00 Croatian Dinar random",
5280 "1.00 Croatian Kuna random",
5281 "1.00 Croatian dinar random",
5282 "1.00 Croatian dinars random",
5283 "1.00 Croatian kuna random",
5284 "1.00 Croatian kunas random",
5285 "1.00 Cuban Peso random",
5286 "1.00 Cuban peso random",
5287 "1.00 Cuban pesos random",
5288 "1.00 Cypriot Pound random",
5289 "1.00 Cypriot pound random",
5290 "1.00 Cypriot pounds random",
5291 "1.00 Czech Koruna random",
5292 "1.00 Czech koruna random",
5293 "1.00 Czech korunas random",
5294 "1.00 Czechoslovak Hard Koruna random",
5295 "1.00 Czechoslovak hard koruna random",
5296 "1.00 Czechoslovak hard korunas random",
5297 "1.00 Danish Krone random",
5298 "1.00 Danish krone random",
5299 "1.00 Danish kroner random",
5300 "1.00 German Mark random",
5301 "1.00 German mark random",
5302 "1.00 German marks random",
5303 "1.00 Djiboutian Franc random",
5304 "1.00 Djiboutian franc random",
5305 "1.00 Djiboutian francs random",
5306 "1.00 Dominican Peso random",
5307 "1.00 Dominican peso random",
5308 "1.00 Dominican pesos random",
5309 "1.00 East Caribbean Dollar random",
5310 "1.00 East Caribbean dollar random",
5311 "1.00 East Caribbean dollars random",
5312 "1.00 East German Mark random",
5313 "1.00 East German mark random",
5314 "1.00 East German marks random",
5315 "1.00 Ecuadorian Sucre random",
5316 "1.00 Ecuadorian Unit of Constant Value random",
5317 "1.00 Ecuadorian sucre random",
5318 "1.00 Ecuadorian sucres random",
5319 "1.00 Ecuadorian unit of constant value random",
5320 "1.00 Ecuadorian units of constant value random",
5321 "1.00 Egyptian Pound random",
5322 "1.00 Egyptian pound random",
5323 "1.00 Egyptian pounds random",
5324 "1.00 Salvadoran Col\\u00f3n random",
5325 "1.00 Salvadoran col\\u00f3n random",
5326 "1.00 Salvadoran colones random",
5327 "1.00 Equatorial Guinean Ekwele random",
5328 "1.00 Equatorial Guinean ekwele random",
5329 "1.00 Eritrean Nakfa random",
5330 "1.00 Eritrean nakfa random",
5331 "1.00 Eritrean nakfas random",
5332 "1.00 Estonian Kroon random",
5333 "1.00 Estonian kroon random",
5334 "1.00 Estonian kroons random",
5335 "1.00 Ethiopian Birr random",
5336 "1.00 Ethiopian birr random",
5337 "1.00 Ethiopian birrs random",
5338 "1.00 European Composite Unit random",
5339 "1.00 European Currency Unit random",
5340 "1.00 European Monetary Unit random",
5341 "1.00 European Unit of Account (XBC) random",
5342 "1.00 European Unit of Account (XBD) random",
5343 "1.00 European composite unit random",
5344 "1.00 European composite units random",
5345 "1.00 European currency unit random",
5346 "1.00 European currency units random",
5347 "1.00 European monetary unit random",
5348 "1.00 European monetary units random",
5349 "1.00 European unit of account (XBC) random",
5350 "1.00 European unit of account (XBD) random",
5351 "1.00 European units of account (XBC) random",
5352 "1.00 European units of account (XBD) random",
5353 "1.00 Falkland Islands Pound random",
5354 "1.00 Falkland Islands pound random",
5355 "1.00 Falkland Islands pounds random",
5356 "1.00 Fijian Dollar random",
5357 "1.00 Fijian dollar random",
5358 "1.00 Fijian dollars random",
5359 "1.00 Finnish Markka random",
5360 "1.00 Finnish markka random",
5361 "1.00 Finnish markkas random",
5362 "1.00 French Franc random",
5363 "1.00 French Gold Franc random",
5364 "1.00 French UIC-Franc random",
5365 "1.00 French UIC-franc random",
5366 "1.00 French UIC-francs random",
5367 "1.00 French franc random",
5368 "1.00 French francs random",
5369 "1.00 French gold franc random",
5370 "1.00 French gold francs random",
5371 "1.00 Gambian Dalasi random",
5372 "1.00 Gambian dalasi random",
5373 "1.00 Gambian dalasis random",
5374 "1.00 Georgian Kupon Larit random",
5375 "1.00 Georgian Lari random",
5376 "1.00 Georgian kupon larit random",
5377 "1.00 Georgian kupon larits random",
5378 "1.00 Georgian lari random",
5379 "1.00 Georgian laris random",
5380 "1.00 Ghanaian Cedi (1979\\u20132007) random",
5381 "1.00 Ghanaian Cedi random",
5382 "1.00 Ghanaian cedi (1979\\u20132007) random",
5383 "1.00 Ghanaian cedi random",
5384 "1.00 Ghanaian cedis (1979\\u20132007) random",
5385 "1.00 Ghanaian cedis random",
5386 "1.00 Gibraltar Pound random",
5387 "1.00 Gibraltar pound random",
5388 "1.00 Gibraltar pounds random",
5391 "1.00 Greek Drachma random",
5392 "1.00 Greek drachma random",
5393 "1.00 Greek drachmas random",
5394 "1.00 Guatemalan Quetzal random",
5395 "1.00 Guatemalan quetzal random",
5396 "1.00 Guatemalan quetzals random",
5397 "1.00 Guinean Franc random",
5398 "1.00 Guinean Syli random",
5399 "1.00 Guinean franc random",
5400 "1.00 Guinean francs random",
5401 "1.00 Guinean syli random",
5402 "1.00 Guinean sylis random",
5403 "1.00 Guinea-Bissau Peso random",
5404 "1.00 Guinea-Bissau peso random",
5405 "1.00 Guinea-Bissau pesos random",
5406 "1.00 Guyanaese Dollar random",
5407 "1.00 Guyanaese dollar random",
5408 "1.00 Guyanaese dollars random",
5409 "1.00 Haitian Gourde random",
5410 "1.00 Haitian gourde random",
5411 "1.00 Haitian gourdes random",
5412 "1.00 Honduran Lempira random",
5413 "1.00 Honduran lempira random",
5414 "1.00 Honduran lempiras random",
5415 "1.00 Hong Kong Dollar random",
5416 "1.00 Hong Kong dollar random",
5417 "1.00 Hong Kong dollars random",
5418 "1.00 Hungarian Forint random",
5419 "1.00 Hungarian forint random",
5420 "1.00 Hungarian forints random",
5421 "1.00 Icelandic Kr\\u00f3na random",
5422 "1.00 Icelandic kr\\u00f3na random",
5423 "1.00 Icelandic kr\\u00f3nur random",
5424 "1.00 Indian Rupee random",
5425 "1.00 Indian rupee random",
5426 "1.00 Indian rupees random",
5427 "1.00 Indonesian Rupiah random",
5428 "1.00 Indonesian rupiah random",
5429 "1.00 Indonesian rupiahs random",
5430 "1.00 Iranian Rial random",
5431 "1.00 Iranian rial random",
5432 "1.00 Iranian rials random",
5433 "1.00 Iraqi Dinar random",
5434 "1.00 Iraqi dinar random",
5435 "1.00 Iraqi dinars random",
5436 "1.00 Irish Pound random",
5437 "1.00 Irish pound random",
5438 "1.00 Irish pounds random",
5439 "1.00 Israeli Pound random",
5440 "1.00 Israeli new shekel random",
5441 "1.00 Israeli pound random",
5442 "1.00 Israeli pounds random",
5443 "1.00 Italian Lira random",
5444 "1.00 Italian lira random",
5445 "1.00 Italian liras random",
5446 "1.00 Jamaican Dollar random",
5447 "1.00 Jamaican dollar random",
5448 "1.00 Jamaican dollars random",
5449 "1.00 Japanese Yen random",
5450 "1.00 Japanese yen random",
5451 "1.00 Jordanian Dinar random",
5452 "1.00 Jordanian dinar random",
5453 "1.00 Jordanian dinars random",
5454 "1.00 Kazakhstani Tenge random",
5455 "1.00 Kazakhstani tenge random",
5456 "1.00 Kazakhstani tenges random",
5457 "1.00 Kenyan Shilling random",
5458 "1.00 Kenyan shilling random",
5459 "1.00 Kenyan shillings random",
5460 "1.00 Kuwaiti Dinar random",
5461 "1.00 Kuwaiti dinar random",
5462 "1.00 Kuwaiti dinars random",
5463 "1.00 Kyrgystani Som random",
5464 "1.00 Kyrgystani som random",
5465 "1.00 Kyrgystani soms random",
5466 "1.00 Laotian Kip random",
5467 "1.00 Laotian kip random",
5468 "1.00 Laotian kips random",
5469 "1.00 Latvian Lats random",
5470 "1.00 Latvian Ruble random",
5471 "1.00 Latvian lats random",
5472 "1.00 Latvian lati random",
5473 "1.00 Latvian ruble random",
5474 "1.00 Latvian rubles random",
5475 "1.00 Lebanese Pound random",
5476 "1.00 Lebanese pound random",
5477 "1.00 Lebanese pounds random",
5478 "1.00 Lesotho Loti random",
5479 "1.00 Lesotho loti random",
5480 "1.00 Lesotho lotis random",
5481 "1.00 Liberian Dollar random",
5482 "1.00 Liberian dollar random",
5483 "1.00 Liberian dollars random",
5484 "1.00 Libyan Dinar random",
5485 "1.00 Libyan dinar random",
5486 "1.00 Libyan dinars random",
5487 "1.00 Lithuanian Litas random",
5488 "1.00 Lithuanian Talonas random",
5489 "1.00 Lithuanian litas random",
5490 "1.00 Lithuanian litai random",
5491 "1.00 Lithuanian talonas random",
5492 "1.00 Lithuanian talonases random",
5493 "1.00 Luxembourgian Convertible Franc random",
5494 "1.00 Luxembourg Financial Franc random",
5495 "1.00 Luxembourgian Franc random",
5496 "1.00 Luxembourgian convertible franc random",
5497 "1.00 Luxembourgian convertible francs random",
5498 "1.00 Luxembourg financial franc random",
5499 "1.00 Luxembourg financial francs random",
5500 "1.00 Luxembourgian franc random",
5501 "1.00 Luxembourgian francs random",
5502 "1.00 Macanese Pataca random",
5503 "1.00 Macanese pataca random",
5504 "1.00 Macanese patacas random",
5505 "1.00 Macedonian Denar random",
5506 "1.00 Macedonian denar random",
5507 "1.00 Macedonian denari random",
5508 "1.00 Malagasy Ariaries random",
5509 "1.00 Malagasy Ariary random",
5510 "1.00 Malagasy Ariary random",
5511 "1.00 Malagasy Franc random",
5512 "1.00 Malagasy franc random",
5513 "1.00 Malagasy francs random",
5514 "1.00 Malawian Kwacha random",
5515 "1.00 Malawian Kwacha random",
5516 "1.00 Malawian Kwachas random",
5517 "1.00 Malaysian Ringgit random",
5518 "1.00 Malaysian ringgit random",
5519 "1.00 Malaysian ringgits random",
5520 "1.00 Maldivian Rufiyaa random",
5521 "1.00 Maldivian rufiyaa random",
5522 "1.00 Maldivian rufiyaas random",
5523 "1.00 Malian Franc random",
5524 "1.00 Malian franc random",
5525 "1.00 Malian francs random",
5526 "1.00 Maltese Lira random",
5527 "1.00 Maltese Pound random",
5528 "1.00 Maltese lira random",
5529 "1.00 Maltese liras random",
5530 "1.00 Maltese pound random",
5531 "1.00 Maltese pounds random",
5532 "1.00 Mauritanian Ouguiya random",
5533 "1.00 Mauritanian ouguiya random",
5534 "1.00 Mauritanian ouguiyas random",
5535 "1.00 Mauritian Rupee random",
5536 "1.00 Mauritian rupee random",
5537 "1.00 Mauritian rupees random",
5538 "1.00 Mexican Peso random",
5539 "1.00 Mexican Silver Peso (1861\\u20131992) random",
5540 "1.00 Mexican Investment Unit random",
5541 "1.00 Mexican peso random",
5542 "1.00 Mexican pesos random",
5543 "1.00 Mexican silver peso (1861\\u20131992) random",
5544 "1.00 Mexican silver pesos (1861\\u20131992) random",
5545 "1.00 Mexican investment unit random",
5546 "1.00 Mexican investment units random",
5547 "1.00 Moldovan Leu random",
5548 "1.00 Moldovan leu random",
5549 "1.00 Moldovan lei random",
5550 "1.00 Mongolian Tugrik random",
5551 "1.00 Mongolian tugrik random",
5552 "1.00 Mongolian tugriks random",
5553 "1.00 Moroccan Dirham random",
5554 "1.00 Moroccan Franc random",
5555 "1.00 Moroccan dirham random",
5556 "1.00 Moroccan dirhams random",
5557 "1.00 Moroccan franc random",
5558 "1.00 Moroccan francs random",
5559 "1.00 Mozambican Escudo random",
5560 "1.00 Mozambican Metical random",
5561 "1.00 Mozambican escudo random",
5562 "1.00 Mozambican escudos random",
5563 "1.00 Mozambican metical random",
5564 "1.00 Mozambican meticals random",
5565 "1.00 Myanmar Kyat random",
5566 "1.00 Myanmar kyat random",
5567 "1.00 Myanmar kyats random",
5568 "1.00 Namibian Dollar random",
5569 "1.00 Namibian dollar random",
5570 "1.00 Namibian dollars random",
5571 "1.00 Nepalese Rupee random",
5572 "1.00 Nepalese rupee random",
5573 "1.00 Nepalese rupees random",
5574 "1.00 Netherlands Antillean Guilder random",
5575 "1.00 Netherlands Antillean guilder random",
5576 "1.00 Netherlands Antillean guilders random",
5577 "1.00 Dutch Guilder random",
5578 "1.00 Dutch guilder random",
5579 "1.00 Dutch guilders random",
5580 "1.00 Israeli New Shekel random",
5581 "1.00 Israeli new shekels random",
5582 "1.00 New Zealand Dollar random",
5583 "1.00 New Zealand dollar random",
5584 "1.00 New Zealand dollars random",
5585 "1.00 Nicaraguan C\\u00f3rdoba random",
5586 "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random",
5587 "1.00 Nicaraguan c\\u00f3rdoba random",
5588 "1.00 Nicaraguan c\\u00f3rdoba random",
5589 "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random",
5590 "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random",
5591 "1.00 Nigerian Naira random",
5592 "1.00 Nigerian naira random",
5593 "1.00 Nigerian nairas random",
5594 "1.00 North Korean Won random",
5595 "1.00 North Korean won random",
5596 "1.00 North Korean won random",
5597 "1.00 Norwegian Krone random",
5598 "1.00 Norwegian krone random",
5599 "1.00 Norwegian kroner random",
5600 "1.00 Mozambican Metical (1980\\u20132006) random",
5601 "1.00 Mozambican metical (1980\\u20132006) random",
5602 "1.00 Mozambican meticals (1980\\u20132006) random",
5603 "1.00 Romanian Lei (1952\\u20132006) random",
5604 "1.00 Romanian Leu (1952\\u20132006) random",
5605 "1.00 Romanian leu (1952\\u20132006) random",
5606 "1.00 Serbian Dinar (2002\\u20132006) random",
5607 "1.00 Serbian dinar (2002\\u20132006) random",
5608 "1.00 Serbian dinars (2002\\u20132006) random",
5609 "1.00 Sudanese Dinar (1992\\u20132007) random",
5610 "1.00 Sudanese Pound (1957\\u20131998) random",
5611 "1.00 Sudanese dinar (1992\\u20132007) random",
5612 "1.00 Sudanese dinars (1992\\u20132007) random",
5613 "1.00 Sudanese pound (1957\\u20131998) random",
5614 "1.00 Sudanese pounds (1957\\u20131998) random",
5615 "1.00 Turkish Lira (1922\\u20132005) random",
5616 "1.00 Turkish Lira (1922\\u20132005) random",
5617 "1.00 Omani Rial random",
5618 "1.00 Omani rial random",
5619 "1.00 Omani rials random",
5620 "1.00 Pakistani Rupee random",
5621 "1.00 Pakistani rupee random",
5622 "1.00 Pakistani rupees random",
5623 "1.00 Palladium random",
5624 "1.00 Palladium random",
5625 "1.00 Panamanian Balboa random",
5626 "1.00 Panamanian balboa random",
5627 "1.00 Panamanian balboas random",
5628 "1.00 Papua New Guinean Kina random",
5629 "1.00 Papua New Guinean kina random",
5630 "1.00 Papua New Guinean kina random",
5631 "1.00 Paraguayan Guarani random",
5632 "1.00 Paraguayan guarani random",
5633 "1.00 Paraguayan guaranis random",
5634 "1.00 Peruvian Inti random",
5635 "1.00 Peruvian Sol random",
5636 "1.00 Peruvian Sol (1863\\u20131965) random",
5637 "1.00 Peruvian inti random",
5638 "1.00 Peruvian intis random",
5639 "1.00 Peruvian sol random",
5640 "1.00 Peruvian soles random",
5641 "1.00 Peruvian sol (1863\\u20131965) random",
5642 "1.00 Peruvian soles (1863\\u20131965) random",
5643 "1.00 Philippine Piso random",
5644 "1.00 Philippine piso random",
5645 "1.00 Philippine pisos random",
5646 "1.00 Platinum random",
5647 "1.00 Platinum random",
5648 "1.00 Polish Zloty (1950\\u20131995) random",
5649 "1.00 Polish Zloty random",
5650 "1.00 Polish zlotys random",
5651 "1.00 Polish zloty (PLZ) random",
5652 "1.00 Polish zloty random",
5653 "1.00 Polish zlotys (PLZ) random",
5654 "1.00 Portuguese Escudo random",
5655 "1.00 Portuguese Guinea Escudo random",
5656 "1.00 Portuguese Guinea escudo random",
5657 "1.00 Portuguese Guinea escudos random",
5658 "1.00 Portuguese escudo random",
5659 "1.00 Portuguese escudos random",
5660 "1.00 Qatari Rial random",
5661 "1.00 Qatari rial random",
5662 "1.00 Qatari rials random",
5663 "1.00 RINET Funds random",
5664 "1.00 RINET Funds random",
5665 "1.00 Rhodesian Dollar random",
5666 "1.00 Rhodesian dollar random",
5667 "1.00 Rhodesian dollars random",
5668 "1.00 Romanian Leu random",
5669 "1.00 Romanian lei random",
5670 "1.00 Romanian leu random",
5671 "1.00 Russian Ruble (1991\\u20131998) random",
5672 "1.00 Russian Ruble random",
5673 "1.00 Russian ruble (1991\\u20131998) random",
5674 "1.00 Russian ruble random",
5675 "1.00 Russian rubles (1991\\u20131998) random",
5676 "1.00 Russian rubles random",
5677 "1.00 Rwandan Franc random",
5678 "1.00 Rwandan franc random",
5679 "1.00 Rwandan francs random",
5680 "1.00 St. Helena Pound random",
5681 "1.00 St. Helena pound random",
5682 "1.00 St. Helena pounds random",
5683 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra random",
5684 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra random",
5685 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras random",
5686 "1.00 Saudi Riyal random",
5687 "1.00 Saudi riyal random",
5688 "1.00 Saudi riyals random",
5689 "1.00 Serbian Dinar random",
5690 "1.00 Serbian dinar random",
5691 "1.00 Serbian dinars random",
5692 "1.00 Seychellois Rupee random",
5693 "1.00 Seychellois rupee random",
5694 "1.00 Seychellois rupees random",
5695 "1.00 Sierra Leonean Leone random",
5696 "1.00 Sierra Leonean leone random",
5697 "1.00 Sierra Leonean leones random",
5698 "1.00 Singapore Dollar random",
5699 "1.00 Singapore dollar random",
5700 "1.00 Singapore dollars random",
5701 "1.00 Slovak Koruna random",
5702 "1.00 Slovak koruna random",
5703 "1.00 Slovak korunas random",
5704 "1.00 Slovenian Tolar random",
5705 "1.00 Slovenian tolar random",
5706 "1.00 Slovenian tolars random",
5707 "1.00 Solomon Islands Dollar random",
5708 "1.00 Solomon Islands dollar random",
5709 "1.00 Solomon Islands dollars random",
5710 "1.00 Somali Shilling random",
5711 "1.00 Somali shilling random",
5712 "1.00 Somali shillings random",
5713 "1.00 South African Rand (financial) random",
5714 "1.00 South African Rand random",
5715 "1.00 South African rand (financial) random",
5716 "1.00 South African rand random",
5717 "1.00 South African rands (financial) random",
5718 "1.00 South African rand random",
5719 "1.00 South Korean Won random",
5720 "1.00 South Korean won random",
5721 "1.00 South Korean won random",
5722 "1.00 Soviet Rouble random",
5723 "1.00 Soviet rouble random",
5724 "1.00 Soviet roubles random",
5725 "1.00 Spanish Peseta (A account) random",
5726 "1.00 Spanish Peseta (convertible account) random",
5727 "1.00 Spanish Peseta random",
5728 "1.00 Spanish peseta (A account) random",
5729 "1.00 Spanish peseta (convertible account) random",
5730 "1.00 Spanish peseta random",
5731 "1.00 Spanish pesetas (A account) random",
5732 "1.00 Spanish pesetas (convertible account) random",
5733 "1.00 Spanish pesetas random",
5734 "1.00 Special Drawing Rights random",
5735 "1.00 Sri Lankan Rupee random",
5736 "1.00 Sri Lankan rupee random",
5737 "1.00 Sri Lankan rupees random",
5738 "1.00 Sudanese Pound random",
5739 "1.00 Sudanese pound random",
5740 "1.00 Sudanese pounds random",
5741 "1.00 Surinamese Dollar random",
5742 "1.00 Surinamese dollar random",
5743 "1.00 Surinamese dollars random",
5744 "1.00 Surinamese Guilder random",
5745 "1.00 Surinamese guilder random",
5746 "1.00 Surinamese guilders random",
5747 "1.00 Swazi Lilangeni random",
5748 "1.00 Swazi lilangeni random",
5749 "1.00 Swazi emalangeni random",
5750 "1.00 Swedish Krona random",
5751 "1.00 Swedish krona random",
5752 "1.00 Swedish kronor random",
5753 "1.00 Swiss Franc random",
5754 "1.00 Swiss franc random",
5755 "1.00 Swiss francs random",
5756 "1.00 Syrian Pound random",
5757 "1.00 Syrian pound random",
5758 "1.00 Syrian pounds random",
5759 "1.00 New Taiwan Dollar random",
5760 "1.00 New Taiwan dollar random",
5761 "1.00 New Taiwan dollars random",
5762 "1.00 Tajikistani Ruble random",
5763 "1.00 Tajikistani Somoni random",
5764 "1.00 Tajikistani ruble random",
5765 "1.00 Tajikistani rubles random",
5766 "1.00 Tajikistani somoni random",
5767 "1.00 Tajikistani somonis random",
5768 "1.00 Tanzanian Shilling random",
5769 "1.00 Tanzanian shilling random",
5770 "1.00 Tanzanian shillings random",
5771 "1.00 Testing Currency Code random",
5772 "1.00 Testing Currency Code random",
5773 "1.00 Thai Baht random",
5774 "1.00 Thai baht random",
5775 "1.00 Thai baht random",
5776 "1.00 Timorese Escudo random",
5777 "1.00 Timorese escudo random",
5778 "1.00 Timorese escudos random",
5779 "1.00 Trinidad & Tobago Dollar random",
5780 "1.00 Trinidad & Tobago dollar random",
5781 "1.00 Trinidad & Tobago dollars random",
5782 "1.00 Tunisian Dinar random",
5783 "1.00 Tunisian dinar random",
5784 "1.00 Tunisian dinars random",
5785 "1.00 Turkish Lira random",
5786 "1.00 Turkish Lira random",
5787 "1.00 Turkish lira random",
5788 "1.00 Turkmenistani Manat random",
5789 "1.00 Turkmenistani manat random",
5790 "1.00 Turkmenistani manat random",
5791 "1.00 US Dollar (Next day) random",
5792 "1.00 US Dollar (Same day) random",
5793 "1.00 US Dollar random",
5794 "1.00 US dollar (next day) random",
5795 "1.00 US dollar (same day) random",
5796 "1.00 US dollar random",
5797 "1.00 US dollars (next day) random",
5798 "1.00 US dollars (same day) random",
5799 "1.00 US dollars random",
5800 "1.00 Ugandan Shilling (1966\\u20131987) random",
5801 "1.00 Ugandan Shilling random",
5802 "1.00 Ugandan shilling (1966\\u20131987) random",
5803 "1.00 Ugandan shilling random",
5804 "1.00 Ugandan shillings (1966\\u20131987) random",
5805 "1.00 Ugandan shillings random",
5806 "1.00 Ukrainian Hryvnia random",
5807 "1.00 Ukrainian Karbovanets random",
5808 "1.00 Ukrainian hryvnia random",
5809 "1.00 Ukrainian hryvnias random",
5810 "1.00 Ukrainian karbovanets random",
5811 "1.00 Ukrainian karbovantsiv random",
5812 "1.00 Colombian Real Value Unit random",
5813 "1.00 United Arab Emirates Dirham random",
5814 "1.00 Unknown Currency random",
5815 "1.00 Uruguayan Peso (1975\\u20131993) random",
5816 "1.00 Uruguayan Peso random",
5817 "1.00 Uruguayan Peso (Indexed Units) random",
5818 "1.00 Uruguayan peso (1975\\u20131993) random",
5819 "1.00 Uruguayan peso (indexed units) random",
5820 "1.00 Uruguayan peso random",
5821 "1.00 Uruguayan pesos (1975\\u20131993) random",
5822 "1.00 Uruguayan pesos (indexed units) random",
5823 "1.00 Uzbekistani Som random",
5824 "1.00 Uzbekistani som random",
5825 "1.00 Uzbekistani som random",
5826 "1.00 Vanuatu Vatu random",
5827 "1.00 Vanuatu vatu random",
5828 "1.00 Vanuatu vatus random",
5829 "1.00 Venezuelan Bol\\u00edvar random",
5830 "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random",
5831 "1.00 Venezuelan bol\\u00edvar random",
5832 "1.00 Venezuelan bol\\u00edvars random",
5833 "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random",
5834 "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random",
5835 "1.00 Vietnamese Dong random",
5836 "1.00 Vietnamese dong random",
5837 "1.00 Vietnamese dong random",
5838 "1.00 WIR Euro random",
5839 "1.00 WIR Franc random",
5840 "1.00 WIR euro random",
5841 "1.00 WIR euros random",
5842 "1.00 WIR franc random",
5843 "1.00 WIR francs random",
5844 "1.00 Samoan Tala random",
5845 "1.00 Samoan tala random",
5846 "1.00 Samoan tala random",
5847 "1.00 Yemeni Dinar random",
5848 "1.00 Yemeni Rial random",
5849 "1.00 Yemeni dinar random",
5850 "1.00 Yemeni dinars random",
5851 "1.00 Yemeni rial random",
5852 "1.00 Yemeni rials random",
5853 "1.00 Yugoslavian Convertible Dinar (1990\\u20131992) random",
5854 "1.00 Yugoslavian Hard Dinar (1966\\u20131990) random",
5855 "1.00 Yugoslavian New Dinar (1994\\u20132002) random",
5856 "1.00 Yugoslavian convertible dinar (1990\\u20131992) random",
5857 "1.00 Yugoslavian convertible dinars (1990\\u20131992) random",
5858 "1.00 Yugoslavian hard dinar (1966\\u20131990) random",
5859 "1.00 Yugoslavian hard dinars (1966\\u20131990) random",
5860 "1.00 Yugoslavian new dinar (1994\\u20132002) random",
5861 "1.00 Yugoslavian new dinars (1994\\u20132002) random",
5862 "1.00 Zairean New Zaire (1993\\u20131998) random",
5863 "1.00 Zairean Zaire (1971\\u20131993) random",
5864 "1.00 Zairean new zaire (1993\\u20131998) random",
5865 "1.00 Zairean new zaires (1993\\u20131998) random",
5866 "1.00 Zairean zaire (1971\\u20131993) random",
5867 "1.00 Zairean zaires (1971\\u20131993) random",
5868 "1.00 Zambian Kwacha random",
5869 "1.00 Zambian kwacha random",
5870 "1.00 Zambian kwachas random",
5871 "1.00 Zimbabwean Dollar (1980\\u20132008) random",
5872 "1.00 Zimbabwean dollar (1980\\u20132008) random",
5873 "1.00 Zimbabwean dollars (1980\\u20132008) random",
5875 "1.00 euros random",
5876 "1.00 Turkish lira (1922\\u20132005) random",
5877 "1.00 special drawing rights random",
5878 "1.00 Colombian real value unit random",
5879 "1.00 Colombian real value units random",
5880 "1.00 unknown currency random",
5883 const char* WRONG_DATA
[] = {
5884 // Following are missing one last char in the currency name
5885 "usd1.00", // case sensitive
5886 "1.00 Nicaraguan Cordob",
5887 "1.00 Namibian Dolla",
5888 "1.00 Namibian dolla",
5889 "1.00 Nepalese Rupe",
5890 "1.00 Nepalese rupe",
5891 "1.00 Netherlands Antillean Guilde",
5892 "1.00 Netherlands Antillean guilde",
5893 "1.00 Dutch Guilde",
5894 "1.00 Dutch guilde",
5895 "1.00 Israeli New Sheqe",
5896 "1.00 New Zealand Dolla",
5897 "1.00 New Zealand dolla",
5898 "1.00 Nicaraguan cordob",
5899 "1.00 Nigerian Nair",
5900 "1.00 Nigerian nair",
5901 "1.00 North Korean Wo",
5902 "1.00 North Korean wo",
5903 "1.00 Norwegian Kron",
5904 "1.00 Norwegian kron",
5920 "Afghan Afghan1.00",
5921 "Afghan Afghani (1927\\u201320021.00",
5924 "Algerian Dina1.00",
5925 "Andorran Peset1.00",
5926 "Angolan Kwanz1.00",
5927 "Angolan Kwanza (1977\\u201319901.00",
5928 "Angolan Readjusted Kwanza (1995\\u201319991.00",
5929 "Angolan New Kwanza (1990\\u201320001.00",
5930 "Argentine Austra1.00",
5931 "Argentine Pes1.00",
5932 "Argentine Peso (1983\\u201319851.00",
5935 "Australian Dolla1.00",
5936 "Austrian Schillin1.00",
5937 "Azerbaijani Mana1.00",
5938 "Azerbaijani Manat (1993\\u201320061.00",
5956 "Bahamian Dolla1.00",
5957 "Bahraini Dina1.00",
5958 "Bangladeshi Tak1.00",
5959 "Barbadian Dolla1.00",
5961 "Belarusian Ruble (1994\\u201319991.00",
5962 "Belarusian Rubl1.00",
5964 "Belgian Franc (convertible1.00",
5965 "Belgian Franc (financial1.00",
5967 "Bermudan Dolla1.00",
5968 "Bhutanese Ngultru1.00",
5969 "Bolivian Mvdo1.00",
5971 "Bolivian Bolivian1.00",
5972 "Bosnia-Herzegovina Convertible Mar1.00",
5973 "Bosnia-Herzegovina Dina1.00",
5974 "Botswanan Pul1.00",
5975 "Brazilian Cruzad1.00",
5976 "Brazilian Cruzado Nov1.00",
5977 "Brazilian Cruzeir1.00",
5978 "Brazilian Cruzeiro (1990\\u201319931.00",
5979 "Brazilian New Cruzeiro (1967\\u201319861.00",
5980 "Brazilian Rea1.00",
5981 "British Pound Sterlin1.00",
5983 "Bulgarian Hard Le1.00",
5986 "Burundian Fran1.00",
6001 "Cambodian Rie1.00",
6002 "Canadian Dolla1.00",
6003 "Cape Verdean Escud1.00",
6004 "Cayman Islands Dolla1.00",
6006 "Chilean Unit of Accoun1.00",
6008 "Colombian Pes1.00",
6010 "Congolese Fran1.00",
6011 "Costa Rican Col\\u00f31.00",
6012 "Croatian Dina1.00",
6016 "Czech Republic Korun1.00",
6017 "Czechoslovak Hard Korun1.00",
6027 "Djiboutian Fran1.00",
6029 "Dominican Pes1.00",
6038 "East Caribbean Dolla1.00",
6039 "East German Ostmar1.00",
6040 "Ecuadorian Sucr1.00",
6041 "Ecuadorian Unit of Constant Valu1.00",
6042 "Egyptian Poun1.00",
6044 "Salvadoran Col\\u00f31.00",
6045 "Equatorial Guinean Ekwel1.00",
6046 "Eritrean Nakf1.00",
6048 "Estonian Kroo1.00",
6049 "Ethiopian Bir1.00",
6051 "European Composite Uni1.00",
6052 "European Currency Uni1.00",
6053 "European Monetary Uni1.00",
6054 "European Unit of Account (XBC1.00",
6055 "European Unit of Account (XBD1.00",
6062 "Falkland Islands Poun1.00",
6065 "Finnish Markk1.00",
6068 "French Gold Fran1.00",
6069 "French UIC-Fran1.00",
6082 "Gambian Dalas1.00",
6083 "Georgian Kupon Lari1.00",
6086 "Ghanaian Cedi (1979\\u201320071.00",
6087 "Gibraltar Poun1.00",
6090 "Guatemalan Quetza1.00",
6093 "Guinea-Bissau Pes1.00",
6094 "Guyanaese Dolla1.00",
6100 "Haitian Gourd1.00",
6101 "Honduran Lempir1.00",
6102 "Hong Kong Dolla1.00",
6103 "Hungarian Forin1.00",
6112 "Icelandic Kron1.00",
6114 "Indonesian Rupia1.00",
6124 "Jamaican Dolla1.00",
6126 "Jordanian Dina1.00",
6137 "Kazakhstani Teng1.00",
6138 "Kenyan Shillin1.00",
6140 "Kyrgystani So1.00",
6152 "Lebanese Poun1.00",
6154 "Liberian Dolla1.00",
6156 "Lithuanian Lit1.00",
6157 "Lithuanian Talona1.00",
6158 "Luxembourgian Convertible Fran1.00",
6159 "Luxembourg Financial Fran1.00",
6160 "Luxembourgian Fran1.00",
6178 "Macanese Patac1.00",
6179 "Macedonian Dena1.00",
6180 "Malagasy Ariar1.00",
6181 "Malagasy Fran1.00",
6182 "Malawian Kwach1.00",
6183 "Malaysian Ringgi1.00",
6184 "Maldivian Rufiya1.00",
6189 "Mauritanian Ouguiy1.00",
6190 "Mauritian Rupe1.00",
6192 "Mexican Silver Peso (1861\\u201319921.00",
6193 "Mexican Investment Uni1.00",
6195 "Mongolian Tugri1.00",
6196 "Moroccan Dirha1.00",
6197 "Moroccan Fran1.00",
6198 "Mozambican Escud1.00",
6199 "Mozambican Metica1.00",
6211 "Namibian Dolla1.00",
6212 "Nepalese Rupe1.00",
6213 "Netherlands Antillean Guilde1.00",
6215 "Israeli New Sheqe1.00",
6216 "New Zealand Dolla1.00",
6217 "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00",
6218 "Nicaraguan C\\u00f3rdob1.00",
6219 "Nigerian Nair1.00",
6220 "North Korean Wo1.00",
6221 "Norwegian Kron1.00",
6224 "Old Mozambican Metica1.00",
6225 "Romanian Leu (1952\\u201320061.00",
6226 "Serbian Dinar (2002\\u201320061.00",
6227 "Sudanese Dinar (1992\\u201320071.00",
6228 "Sudanese Pound (1957\\u201319981.00",
6229 "Turkish Lira (1922\\u201320051.00",
6239 "Pakistani Rupe1.00",
6241 "Panamanian Balbo1.00",
6242 "Papua New Guinean Kin1.00",
6243 "Paraguayan Guaran1.00",
6245 "Peruvian Sol (1863\\u201319651.00",
6246 "Peruvian Sol Nuev1.00",
6247 "Philippine Pes1.00",
6250 "Polish Zloty (1950\\u201319951.00",
6251 "Portuguese Escud1.00",
6252 "Portuguese Guinea Escud1.00",
6263 "Rhodesian Dolla1.00",
6266 "Russian Ruble (1991\\u201319981.00",
6286 "St. Helena Poun1.00",
6287 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobr1.00",
6290 "Seychellois Rupe1.00",
6292 "Sierra Leonean Leon1.00",
6294 "Singapore Dolla1.00",
6296 "Slovenian Tola1.00",
6297 "Solomon Islands Dolla1.00",
6298 "Somali Shillin1.00",
6299 "South African Ran1.00",
6300 "South African Rand (financial1.00",
6301 "South Korean Wo1.00",
6303 "Spanish Peset1.00",
6304 "Spanish Peseta (A account1.00",
6305 "Spanish Peseta (convertible account1.00",
6306 "Special Drawing Right1.00",
6307 "Sri Lankan Rupe1.00",
6308 "Sudanese Poun1.00",
6309 "Surinamese Dolla1.00",
6310 "Surinamese Guilde1.00",
6311 "Swazi Lilangen1.00",
6326 "New Taiwan Dolla1.00",
6327 "Tajikistani Rubl1.00",
6328 "Tajikistani Somon1.00",
6329 "Tanzanian Shillin1.00",
6330 "Testing Currency Cod1.00",
6332 "Timorese Escud1.00",
6333 "Tongan Pa\\u20bbang1.00",
6334 "Trinidad & Tobago Dolla1.00",
6335 "Tunisian Dina1.00",
6337 "Turkmenistani Mana1.00",
6343 "US Dollar (Next day1.00",
6344 "US Dollar (Same day1.00",
6348 "Ugandan Shillin1.00",
6349 "Ugandan Shilling (1966\\u201319871.00",
6350 "Ukrainian Hryvni1.00",
6351 "Ukrainian Karbovanet1.00",
6352 "Colombian Real Value Uni1.00",
6353 "United Arab Emirates Dirha1.00",
6354 "Unknown Currenc1.00",
6356 "Uruguay Peso (1975\\u201319931.00",
6357 "Uruguay Peso Uruguay1.00",
6358 "Uruguay Peso (Indexed Units1.00",
6359 "Uzbekistani So1.00",
6365 "Venezuelan Bol\\u00edva1.00",
6366 "Venezuelan Bol\\u00edvar Fuert1.00",
6367 "Vietnamese Don1.00",
6368 "West African CFA Fran1.00",
6369 "Central African CFA Fran1.00",
6390 "Yugoslavian Convertible Dina1.00",
6391 "Yugoslavian Hard Dinar (1966\\u201319901.00",
6392 "Yugoslavian New Dina1.00",
6398 "Zairean New Zaire (1993\\u201319981.00",
6400 "Zambian Kwach1.00",
6401 "Zimbabwean Dollar (1980\\u201320081.00",
6409 Locale
locale("en_US");
6410 for (uint32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
6411 UnicodeString formatted
= ctou(DATA
[i
]);
6412 UErrorCode status
= U_ZERO_ERROR
;
6413 LocalPointer
<NumberFormat
> numFmt(NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
), status
);
6414 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
6417 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
6418 numFmt
->setLenient(TRUE
);
6419 ParsePosition parsePos
;
6420 LocalPointer
<CurrencyAmount
> currAmt(numFmt
->parseCurrency(formatted
, parsePos
));
6421 if (parsePos
.getIndex() > 0) {
6422 double doubleVal
= currAmt
->getNumber().getDouble(status
);
6423 if ( doubleVal
!= 1.0 ) {
6424 errln("Parsed as currency value other than 1.0: " + formatted
+ " -> " + doubleVal
);
6427 errln("Failed to parse as currency: " + formatted
);
6431 for (uint32_t i
=0; i
<UPRV_LENGTHOF(WRONG_DATA
); ++i
) {
6432 UnicodeString formatted
= ctou(WRONG_DATA
[i
]);
6433 UErrorCode status
= U_ZERO_ERROR
;
6434 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
);
6435 if (numFmt
!= NULL
&& U_SUCCESS(status
)) {
6436 ParsePosition parsePos
;
6437 LocalPointer
<CurrencyAmount
> currAmt(numFmt
->parseCurrency(formatted
, parsePos
));
6438 if (parsePos
.getIndex() > 0) {
6439 double doubleVal
= currAmt
->getNumber().getDouble(status
);
6440 errln("Parsed as currency, should not have: " + formatted
+ " -> " + doubleVal
);
6443 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status
));
6451 const char* attrString(int32_t);
6455 // std::cout << s.toUTF8String(ss)
6456 void NumberFormatTest::expectPositions(FieldPositionIterator
& iter
, int32_t *values
, int32_t tupleCount
,
6457 const UnicodeString
& str
) {
6461 if (tupleCount
> 10) {
6462 assertTrue("internal error, tupleCount too large", FALSE
);
6464 for (int i
= 0; i
< tupleCount
; ++i
) {
6470 while (iter
.next(fp
)) {
6472 int32_t id
= fp
.getField();
6473 int32_t start
= fp
.getBeginIndex();
6474 int32_t limit
= fp
.getEndIndex();
6476 // is there a logln using printf?
6478 sprintf(buf
, "%24s %3d %3d %3d", attrString(id
), id
, start
, limit
);
6481 for (int i
= 0; i
< tupleCount
; ++i
) {
6485 if (values
[i
*3] == id
&&
6486 values
[i
*3+1] == start
&&
6487 values
[i
*3+2] == limit
) {
6488 found
[i
] = ok
= TRUE
;
6493 assertTrue((UnicodeString
)"found [" + id
+ "," + start
+ "," + limit
+ "]", ok
);
6496 // check that all were found
6498 for (int i
= 0; i
< tupleCount
; ++i
) {
6501 assertTrue((UnicodeString
) "missing [" + values
[i
*3] + "," + values
[i
*3+1] + "," + values
[i
*3+2] + "]", found
[i
]);
6504 assertTrue("no expected values were missing", ok
);
6507 void NumberFormatTest::expectPosition(FieldPosition
& pos
, int32_t id
, int32_t start
, int32_t limit
,
6508 const UnicodeString
& str
) {
6510 assertTrue((UnicodeString
)"id " + id
+ " == " + pos
.getField(), id
== pos
.getField());
6511 assertTrue((UnicodeString
)"begin " + start
+ " == " + pos
.getBeginIndex(), start
== pos
.getBeginIndex());
6512 assertTrue((UnicodeString
)"end " + limit
+ " == " + pos
.getEndIndex(), limit
== pos
.getEndIndex());
6515 void NumberFormatTest::TestFieldPositionIterator() {
6517 UErrorCode status
= U_ZERO_ERROR
;
6518 FieldPositionIterator iter1
;
6519 FieldPositionIterator iter2
;
6522 DecimalFormat
*decFmt
= (DecimalFormat
*) NumberFormat::createInstance(status
);
6523 if (failure(status
, "NumberFormat::createInstance", TRUE
)) return;
6525 double num
= 1234.56;
6529 assertTrue((UnicodeString
)"self==", iter1
== iter1
);
6530 assertTrue((UnicodeString
)"iter1==iter2", iter1
== iter2
);
6532 decFmt
->format(num
, str1
, &iter1
, status
);
6533 assertTrue((UnicodeString
)"iter1 != iter2", iter1
!= iter2
);
6534 decFmt
->format(num
, str2
, &iter2
, status
);
6535 assertTrue((UnicodeString
)"iter1 == iter2 (2)", iter1
== iter2
);
6537 assertTrue((UnicodeString
)"iter1 != iter2 (2)", iter1
!= iter2
);
6539 assertTrue((UnicodeString
)"iter1 == iter2 (3)", iter1
== iter2
);
6541 // should format ok with no iterator
6543 decFmt
->format(num
, str2
, NULL
, status
);
6544 assertEquals("null fpiter", str1
, str2
);
6549 void NumberFormatTest::TestFormatAttributes() {
6550 Locale
locale("en_US");
6551 UErrorCode status
= U_ZERO_ERROR
;
6552 DecimalFormat
*decFmt
= (DecimalFormat
*) NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
);
6553 if (failure(status
, "NumberFormat::createInstance", TRUE
)) return;
6554 double val
= 12345.67;
6557 int32_t expected
[] = {
6558 UNUM_CURRENCY_FIELD
, 0, 1,
6559 UNUM_GROUPING_SEPARATOR_FIELD
, 3, 4,
6560 UNUM_INTEGER_FIELD
, 1, 7,
6561 UNUM_DECIMAL_SEPARATOR_FIELD
, 7, 8,
6562 UNUM_FRACTION_FIELD
, 8, 10,
6564 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
6566 FieldPositionIterator posIter
;
6567 UnicodeString result
;
6568 decFmt
->format(val
, result
, &posIter
, status
);
6569 expectPositions(posIter
, expected
, tupleCount
, result
);
6572 FieldPosition
fp(UNUM_INTEGER_FIELD
);
6573 UnicodeString result
;
6574 decFmt
->format(val
, result
, fp
);
6575 expectPosition(fp
, UNUM_INTEGER_FIELD
, 1, 7, result
);
6578 FieldPosition
fp(UNUM_FRACTION_FIELD
);
6579 UnicodeString result
;
6580 decFmt
->format(val
, result
, fp
);
6581 expectPosition(fp
, UNUM_FRACTION_FIELD
, 8, 10, result
);
6585 decFmt
= (DecimalFormat
*) NumberFormat::createInstance(locale
, UNUM_SCIENTIFIC
, status
);
6588 int32_t expected
[] = {
6589 UNUM_SIGN_FIELD
, 0, 1,
6590 UNUM_INTEGER_FIELD
, 1, 2,
6591 UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3,
6592 UNUM_FRACTION_FIELD
, 3, 5,
6593 UNUM_EXPONENT_SYMBOL_FIELD
, 5, 6,
6594 UNUM_EXPONENT_SIGN_FIELD
, 6, 7,
6595 UNUM_EXPONENT_FIELD
, 7, 8
6597 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
6599 FieldPositionIterator posIter
;
6600 UnicodeString result
;
6601 decFmt
->format(val
, result
, &posIter
, status
);
6602 expectPositions(posIter
, expected
, tupleCount
, result
);
6605 FieldPosition
fp(UNUM_INTEGER_FIELD
);
6606 UnicodeString result
;
6607 decFmt
->format(val
, result
, fp
);
6608 expectPosition(fp
, UNUM_INTEGER_FIELD
, 1, 2, result
);
6611 FieldPosition
fp(UNUM_FRACTION_FIELD
);
6612 UnicodeString result
;
6613 decFmt
->format(val
, result
, fp
);
6614 expectPosition(fp
, UNUM_FRACTION_FIELD
, 3, 5, result
);
6621 const char* attrString(int32_t attrId
) {
6623 case UNUM_INTEGER_FIELD
: return "integer";
6624 case UNUM_FRACTION_FIELD
: return "fraction";
6625 case UNUM_DECIMAL_SEPARATOR_FIELD
: return "decimal separator";
6626 case UNUM_EXPONENT_SYMBOL_FIELD
: return "exponent symbol";
6627 case UNUM_EXPONENT_SIGN_FIELD
: return "exponent sign";
6628 case UNUM_EXPONENT_FIELD
: return "exponent";
6629 case UNUM_GROUPING_SEPARATOR_FIELD
: return "grouping separator";
6630 case UNUM_CURRENCY_FIELD
: return "currency";
6631 case UNUM_PERCENT_FIELD
: return "percent";
6632 case UNUM_PERMILL_FIELD
: return "permille";
6633 case UNUM_SIGN_FIELD
: return "sign";
6639 // Test formatting & parsing of big decimals.
6640 // API test, not a comprehensive test.
6641 // See DecimalFormatTest/DataDrivenTests
6643 #define ASSERT_SUCCESS(status) { \
6644 assertSuccess(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (status)); \
6646 #define ASSERT_EQUALS(expected, actual) { \
6647 assertEquals(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (expected), (actual)); \
6650 void NumberFormatTest::TestDecimal() {
6652 UErrorCode status
= U_ZERO_ERROR
;
6653 Formattable
f("12.345678999987654321E666", status
);
6654 ASSERT_SUCCESS(status
);
6655 StringPiece s
= f
.getDecimalNumber(status
);
6656 ASSERT_SUCCESS(status
);
6657 ASSERT_EQUALS("1.2345678999987654321E+667", s
.data());
6658 //printf("%s\n", s.data());
6662 UErrorCode status
= U_ZERO_ERROR
;
6663 Formattable
f1("this is not a number", status
);
6664 ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR
, status
);
6668 UErrorCode status
= U_ZERO_ERROR
;
6670 f
.setDecimalNumber("123.45", status
);
6671 ASSERT_SUCCESS(status
);
6672 ASSERT_EQUALS( Formattable::kDouble
, f
.getType());
6673 ASSERT_EQUALS(123.45, f
.getDouble());
6674 ASSERT_EQUALS(123.45, f
.getDouble(status
));
6675 ASSERT_SUCCESS(status
);
6676 ASSERT_EQUALS("123.45", f
.getDecimalNumber(status
).data());
6677 ASSERT_SUCCESS(status
);
6679 f
.setDecimalNumber("4.5678E7", status
);
6682 ASSERT_EQUALS(45678000, n
);
6684 status
= U_ZERO_ERROR
;
6685 f
.setDecimalNumber("-123", status
);
6686 ASSERT_SUCCESS(status
);
6687 ASSERT_EQUALS( Formattable::kLong
, f
.getType());
6688 ASSERT_EQUALS(-123, f
.getLong());
6689 ASSERT_EQUALS(-123, f
.getLong(status
));
6690 ASSERT_SUCCESS(status
);
6691 ASSERT_EQUALS("-123", f
.getDecimalNumber(status
).data());
6692 ASSERT_SUCCESS(status
);
6694 status
= U_ZERO_ERROR
;
6695 f
.setDecimalNumber("1234567890123", status
); // Number too big for 32 bits
6696 ASSERT_SUCCESS(status
);
6697 ASSERT_EQUALS( Formattable::kInt64
, f
.getType());
6698 ASSERT_EQUALS(1234567890123LL, f
.getInt64());
6699 ASSERT_EQUALS(1234567890123LL, f
.getInt64(status
));
6700 ASSERT_SUCCESS(status
);
6701 ASSERT_EQUALS("1234567890123", f
.getDecimalNumber(status
).data());
6702 ASSERT_SUCCESS(status
);
6706 UErrorCode status
= U_ZERO_ERROR
;
6707 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6708 if (U_FAILURE(status
) || fmtr
== NULL
) {
6709 dataerrln("Unable to create NumberFormat");
6711 UnicodeString formattedResult
;
6712 StringPiece
num("244444444444444444444444444444444444446.4");
6713 fmtr
->format(num
, formattedResult
, NULL
, status
);
6714 ASSERT_SUCCESS(status
);
6715 ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult
);
6716 //std::string ss; std::cout << formattedResult.toUTF8String(ss);
6722 // Check formatting a DigitList. DigitList is internal, but this is
6723 // a critical interface that must work.
6724 UErrorCode status
= U_ZERO_ERROR
;
6725 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6726 if (U_FAILURE(status
) || fmtr
== NULL
) {
6727 dataerrln("Unable to create NumberFormat");
6729 UnicodeString formattedResult
;
6731 StringPiece
num("123.4566666666666666666666666666666666621E+40");
6732 dl
.set(num
, status
);
6733 ASSERT_SUCCESS(status
);
6734 fmtr
->format(dl
, formattedResult
, NULL
, status
);
6735 ASSERT_SUCCESS(status
);
6736 ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult
);
6738 status
= U_ZERO_ERROR
;
6740 dl
.set(num
, status
);
6741 FieldPosition
pos(NumberFormat::FRACTION_FIELD
);
6742 ASSERT_SUCCESS(status
);
6743 formattedResult
.remove();
6744 fmtr
->format(dl
, formattedResult
, pos
, status
);
6745 ASSERT_SUCCESS(status
);
6746 ASSERT_EQUALS("666.666", formattedResult
);
6747 ASSERT_EQUALS(4, pos
.getBeginIndex());
6748 ASSERT_EQUALS(7, pos
.getEndIndex());
6754 // Check a parse with a formatter with a multiplier.
6755 UErrorCode status
= U_ZERO_ERROR
;
6756 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT
, status
);
6757 if (U_FAILURE(status
) || fmtr
== NULL
) {
6758 dataerrln("Unable to create NumberFormat");
6760 UnicodeString input
= "1.84%";
6762 fmtr
->parse(input
, result
, status
);
6763 ASSERT_SUCCESS(status
);
6764 ASSERT_EQUALS("0.0184", result
.getDecimalNumber(status
).data());
6765 //std::cout << result.getDecimalNumber(status).data();
6770 #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6772 * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6776 // Check that a parse returns a decimal number with full accuracy
6777 UErrorCode status
= U_ZERO_ERROR
;
6778 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6779 if (U_FAILURE(status
) || fmtr
== NULL
) {
6780 dataerrln("Unable to create NumberFormat");
6782 UnicodeString input
= "1.002200044400088880000070000";
6784 fmtr
->parse(input
, result
, status
);
6785 ASSERT_SUCCESS(status
);
6786 ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result
.getDecimalNumber(status
).data()));
6787 ASSERT_EQUALS(1.00220004440008888, result
.getDouble());
6788 //std::cout << result.getDecimalNumber(status).data();
6796 void NumberFormatTest::TestCurrencyFractionDigits() {
6797 UErrorCode status
= U_ZERO_ERROR
;
6798 UnicodeString text1
, text2
;
6799 double value
= 99.12345;
6801 // Create currenct instance
6802 NumberFormat
* fmt
= NumberFormat::createCurrencyInstance("ja_JP", status
);
6803 if (U_FAILURE(status
) || fmt
== NULL
) {
6804 dataerrln("Unable to create NumberFormat");
6806 fmt
->format(value
, text1
);
6808 // Reset the same currency and format the test value again
6809 fmt
->setCurrency(fmt
->getCurrency(), status
);
6810 ASSERT_SUCCESS(status
);
6811 fmt
->format(value
, text2
);
6813 if (text1
!= text2
) {
6814 errln((UnicodeString
)"NumberFormat::format() should return the same result - text1="
6815 + text1
+ " text2=" + text2
);
6821 void NumberFormatTest::TestExponentParse() {
6823 UErrorCode status
= U_ZERO_ERROR
;
6825 ParsePosition
parsePos(0);
6827 // set the exponent symbol
6828 status
= U_ZERO_ERROR
;
6829 DecimalFormatSymbols
symbols(Locale::getDefault(), status
);
6830 if(U_FAILURE(status
)) {
6831 dataerrln((UnicodeString
)"ERROR: Could not create DecimalFormatSymbols (Default)");
6835 // create format instance
6836 status
= U_ZERO_ERROR
;
6837 DecimalFormat
fmt(u
"#####", symbols
, status
);
6838 if(U_FAILURE(status
)) {
6839 errln((UnicodeString
)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
6843 fmt
.parse("5.06e-27", result
, parsePos
);
6844 if(result
.getType() != Formattable::kDouble
&&
6845 result
.getDouble() != 5.06E-27 &&
6846 parsePos
.getIndex() != 8
6849 errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i",
6850 result
.getDouble(), parsePos
.getIndex());
6854 void NumberFormatTest::TestExplicitParents() {
6856 /* Test that number formats are properly inherited from es_419 */
6857 /* These could be subject to change if the CLDR data changes */
6858 static const char* parentLocaleTests
[][2]= {
6859 /* locale ID */ /* expected */
6860 {"es_CO", "1.250,75" },
6861 {"es_ES", "1.250,75" },
6862 {"es_GQ", "1.250,75" },
6863 {"es_MX", "1,250.75" },
6864 {"es_US", "1,250.75" },
6865 {"es_VE", "1.250,75" },
6870 for(int i
=0; i
< UPRV_LENGTHOF(parentLocaleTests
); i
++){
6871 UErrorCode status
= U_ZERO_ERROR
;
6872 const char *localeID
= parentLocaleTests
[i
][0];
6873 UnicodeString
expected(parentLocaleTests
[i
][1], -1, US_INV
);
6874 expected
= expected
.unescape();
6876 uloc_canonicalize(localeID
, loc
, 256, &status
);
6877 NumberFormat
*fmt
= NumberFormat::createInstance(Locale(loc
), status
);
6878 if(U_FAILURE(status
)){
6879 dataerrln("Could not create number formatter for locale %s - %s",localeID
, u_errorName(status
));
6883 fmt
->format(1250.75, s
);
6885 errln(UnicodeString("FAIL: Expected: ")+expected
6886 + UnicodeString(" Got: ") + s
6887 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
6889 if (U_FAILURE(status
)){
6890 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
6898 * Test available numbering systems API.
6900 void NumberFormatTest::TestAvailableNumberingSystems() {
6901 UErrorCode status
= U_ZERO_ERROR
;
6902 StringEnumeration
*availableNumberingSystems
= NumberingSystem::getAvailableNames(status
);
6903 CHECK_DATA(status
, "NumberingSystem::getAvailableNames()")
6905 int32_t nsCount
= availableNumberingSystems
->count(status
);
6906 if ( nsCount
< 74 ) {
6907 errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 74, got %d",nsCount
);
6910 /* A relatively simple test of the API. We call getAvailableNames() and cycle through */
6911 /* each name returned, attempting to create a numbering system based on that name and */
6912 /* verifying that the name returned from the resulting numbering system is the same */
6913 /* one that we initially thought. */
6916 for ( int32_t i
= 0 ; i
< nsCount
; i
++ ) {
6917 const char *nsname
= availableNumberingSystems
->next(&len
,status
);
6918 NumberingSystem
* ns
= NumberingSystem::createInstanceByName(nsname
,status
);
6919 logln("OK for ns = %s",nsname
);
6920 if ( uprv_strcmp(nsname
,ns
->getName()) ) {
6921 errln("FAIL: Numbering system name didn't match for name = %s\n",nsname
);
6927 delete availableNumberingSystems
;
6931 NumberFormatTest::Test9087(void)
6933 U_STRING_DECL(pattern
,"#",1);
6934 U_STRING_INIT(pattern
,"#",1);
6936 U_STRING_DECL(infstr
,"INF",3);
6937 U_STRING_INIT(infstr
,"INF",3);
6939 U_STRING_DECL(nanstr
,"NAN",3);
6940 U_STRING_INIT(nanstr
,"NAN",3);
6942 UChar outputbuf
[50] = {0};
6943 UErrorCode status
= U_ZERO_ERROR
;
6944 UNumberFormat
* fmt
= unum_open(UNUM_PATTERN_DECIMAL
,pattern
,1,NULL
,NULL
,&status
);
6945 if ( U_FAILURE(status
) ) {
6946 dataerrln("FAIL: error in unum_open() - %s", u_errorName(status
));
6950 unum_setSymbol(fmt
,UNUM_INFINITY_SYMBOL
,infstr
,3,&status
);
6951 unum_setSymbol(fmt
,UNUM_NAN_SYMBOL
,nanstr
,3,&status
);
6952 if ( U_FAILURE(status
) ) {
6953 errln("FAIL: error setting symbols");
6956 double inf
= uprv_getInfinity();
6958 unum_setAttribute(fmt
,UNUM_ROUNDING_MODE
,UNUM_ROUND_HALFEVEN
);
6959 unum_setDoubleAttribute(fmt
,UNUM_ROUNDING_INCREMENT
,0);
6961 UFieldPosition position
= { 0, 0, 0};
6962 unum_formatDouble(fmt
,inf
,outputbuf
,50,&position
,&status
);
6964 if ( u_strcmp(infstr
, outputbuf
)) {
6965 errln((UnicodeString
)"FAIL: unexpected result for infinity - expected " + infstr
+ " got " + outputbuf
);
6971 void NumberFormatTest::TestFormatFastpaths() {
6972 // get some additional case
6974 UErrorCode status
=U_ZERO_ERROR
;
6975 DecimalFormat
df(UnicodeString(u
"0000"),status
);
6976 if (U_FAILURE(status
)) {
6977 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
6979 int64_t long_number
= 1;
6980 UnicodeString expect
= "0001";
6981 UnicodeString result
;
6983 df
.format(long_number
, result
, pos
);
6984 if(U_FAILURE(status
)||expect
!=result
) {
6985 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s",
6986 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
6988 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),""));
6993 UErrorCode status
=U_ZERO_ERROR
;
6994 DecimalFormat
df(UnicodeString(u
"0000000000000000000"),status
);
6995 if (U_FAILURE(status
)) {
6996 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
6998 int64_t long_number
= U_INT64_MIN
; // -9223372036854775808L;
7000 // memcpy(bits,&long_number,8);
7001 // for(int i=0;i<8;i++) {
7002 // logln("bits: %02X", (unsigned int)bits[i]);
7004 UnicodeString expect
= "-9223372036854775808";
7005 UnicodeString result
;
7007 df
.format(long_number
, result
, pos
);
7008 if(U_FAILURE(status
)||expect
!=result
) {
7009 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775808",
7010 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7012 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on -9223372036854775808");
7017 UErrorCode status
=U_ZERO_ERROR
;
7018 DecimalFormat
df(UnicodeString(u
"0000000000000000000"),status
);
7019 if (U_FAILURE(status
)) {
7020 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7022 int64_t long_number
= U_INT64_MAX
; // -9223372036854775808L;
7024 // memcpy(bits,&long_number,8);
7025 // for(int i=0;i<8;i++) {
7026 // logln("bits: %02X", (unsigned int)bits[i]);
7028 UnicodeString expect
= "9223372036854775807";
7029 UnicodeString result
;
7031 df
.format(long_number
, result
, pos
);
7032 if(U_FAILURE(status
)||expect
!=result
) {
7033 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on U_INT64_MAX",
7034 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7036 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on U_INT64_MAX");
7041 UErrorCode status
=U_ZERO_ERROR
;
7042 DecimalFormat
df(UnicodeString("0000000000000000000",""),status
);
7043 if (U_FAILURE(status
)) {
7044 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7046 int64_t long_number
= 0;
7048 // memcpy(bits,&long_number,8);
7049 // for(int i=0;i<8;i++) {
7050 // logln("bits: %02X", (unsigned int)bits[i]);
7052 UnicodeString expect
= "0000000000000000000";
7053 UnicodeString result
;
7055 df
.format(long_number
, result
, pos
);
7056 if(U_FAILURE(status
)||expect
!=result
) {
7057 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on 0",
7058 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7060 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on 0");
7065 UErrorCode status
=U_ZERO_ERROR
;
7066 DecimalFormat
df(UnicodeString("0000000000000000000",""),status
);
7067 if (U_FAILURE(status
)) {
7068 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7070 int64_t long_number
= U_INT64_MIN
+ 1;
7071 UnicodeString expect
= "-9223372036854775807";
7072 UnicodeString result
;
7074 df
.format(long_number
, result
, pos
);
7075 if(U_FAILURE(status
)||expect
!=result
) {
7076 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775807",
7077 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7079 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on -9223372036854775807");
7086 void NumberFormatTest::TestFormattableSize(void) { // test ICU 61 behavior
7087 if(sizeof(FmtStackData
) > UNUM_INTERNAL_STACKARRAY_SIZE
) {
7088 errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
7089 sizeof(FmtStackData
), UNUM_INTERNAL_STACKARRAY_SIZE
);
7090 } else if(sizeof(FmtStackData
) < UNUM_INTERNAL_STACKARRAY_SIZE
) {
7091 logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
7092 sizeof(FmtStackData
), UNUM_INTERNAL_STACKARRAY_SIZE
);
7094 logln("sizeof(Formattable)=%d, 112=%d\n",
7095 sizeof(Formattable
), 112);
7099 UBool
NumberFormatTest::testFormattableAsUFormattable(const char *file
, int line
, Formattable
&f
) {
7100 UnicodeString fileLine
= UnicodeString(file
)+UnicodeString(":")+line
+UnicodeString(": ");
7102 UFormattable
*u
= f
.toUFormattable();
7105 errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
7108 logln("%s:%d: comparing Formattable with UFormattable", file
, line
);
7109 logln(fileLine
+ toString(f
));
7111 UErrorCode status
= U_ZERO_ERROR
;
7112 UErrorCode valueStatus
= U_ZERO_ERROR
;
7113 UFormattableType expectUType
= UFMT_COUNT
; // invalid
7115 UBool triedExact
= FALSE
; // did we attempt an exact comparison?
7116 UBool exactMatch
= FALSE
; // was the exact comparison true?
7118 switch( f
.getType() ) {
7119 case Formattable::kDate
:
7120 expectUType
= UFMT_DATE
;
7121 exactMatch
= (f
.getDate()==ufmt_getDate(u
, &valueStatus
));
7124 case Formattable::kDouble
:
7125 expectUType
= UFMT_DOUBLE
;
7126 exactMatch
= (f
.getDouble()==ufmt_getDouble(u
, &valueStatus
));
7129 case Formattable::kLong
:
7130 expectUType
= UFMT_LONG
;
7131 exactMatch
= (f
.getLong()==ufmt_getLong(u
, &valueStatus
));
7134 case Formattable::kString
:
7135 expectUType
= UFMT_STRING
;
7140 const UChar
* uch
= ufmt_getUChars(u
, &len
, &valueStatus
);
7141 if(U_SUCCESS(valueStatus
)) {
7142 UnicodeString
str2(uch
, len
);
7143 assertTrue("UChar* NULL-terminated", uch
[len
]==0);
7144 exactMatch
= (str
== str2
);
7149 case Formattable::kArray
:
7150 expectUType
= UFMT_ARRAY
;
7153 int32_t count
= ufmt_getArrayLength(u
, &valueStatus
);
7155 const Formattable
*array2
= f
.getArray(count2
);
7156 exactMatch
= assertEquals(fileLine
+ " array count", count
, count2
);
7159 for(int i
=0;U_SUCCESS(valueStatus
) && i
<count
;i
++) {
7160 UFormattable
*uu
= ufmt_getArrayItemByIndex(u
, i
, &valueStatus
);
7161 if(*Formattable::fromUFormattable(uu
) != (array2
[i
])) {
7162 errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file
, line
, i
,
7163 (const void*)Formattable::fromUFormattable(uu
), (const void*)&(array2
[i
]));
7166 if(!testFormattableAsUFormattable("(sub item)",i
,*Formattable::fromUFormattable(uu
))) {
7174 case Formattable::kInt64
:
7175 expectUType
= UFMT_INT64
;
7176 exactMatch
= (f
.getInt64()==ufmt_getInt64(u
, &valueStatus
));
7179 case Formattable::kObject
:
7180 expectUType
= UFMT_OBJECT
;
7181 exactMatch
= (f
.getObject()==ufmt_getObject(u
, &valueStatus
));
7185 UFormattableType uType
= ufmt_getType(u
, &status
);
7187 if(U_FAILURE(status
)) {
7188 errln("%s:%d: Error calling ufmt_getType - %s", file
, line
, u_errorName(status
));
7192 if(uType
!= expectUType
) {
7193 errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file
, line
, (int) uType
, (int) expectUType
);
7197 if(U_FAILURE(valueStatus
)) {
7198 errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file
, line
, u_errorName(valueStatus
));
7199 } else if(!exactMatch
) {
7200 errln("%s:%d: failed exact match for the Formattable type", file
, line
);
7202 logln("%s:%d: exact match OK", file
, line
);
7205 logln("%s:%d: note, did not attempt exact match for this formattable type", file
, line
);
7208 if( assertEquals(fileLine
+ " isNumeric()", f
.isNumeric(), ufmt_isNumeric(u
))
7210 UErrorCode convStatus
= U_ZERO_ERROR
;
7212 if(uType
!= UFMT_INT64
) { // may fail to compare
7213 assertTrue(fileLine
+ " as doubles ==", f
.getDouble(convStatus
)==ufmt_getDouble(u
, &convStatus
));
7216 if( assertSuccess(fileLine
+ " (numeric conversion status)", convStatus
) ) {
7217 StringPiece fDecNum
= f
.getDecimalNumber(convStatus
);
7220 const char *decNumChars
= ufmt_getDecNumChars(u
, &len
, &convStatus
);
7223 char decNumChars
[200];
7224 int32_t len
= ufmt_getDecNumChars(u
, decNumChars
, 200, &convStatus
);
7227 if( assertSuccess(fileLine
+ " (decNumbers conversion)", convStatus
) ) {
7228 logln(fileLine
+ decNumChars
);
7229 assertEquals(fileLine
+ " decNumChars length==", len
, fDecNum
.length());
7230 assertEquals(fileLine
+ " decNumChars digits", decNumChars
, fDecNum
.data());
7233 UErrorCode int64ConversionF
= U_ZERO_ERROR
;
7234 int64_t l
= f
.getInt64(int64ConversionF
);
7235 UErrorCode int64ConversionU
= U_ZERO_ERROR
;
7236 int64_t r
= ufmt_getInt64(u
, &int64ConversionU
);
7239 && ( uType
!= UFMT_INT64
) // int64 better not overflow
7240 && (U_INVALID_FORMAT_ERROR
==int64ConversionU
)
7241 && (U_INVALID_FORMAT_ERROR
==int64ConversionF
) ) {
7242 logln("%s:%d: OK: 64 bit overflow", file
, line
);
7244 assertEquals(fileLine
+ " as int64 ==", l
, r
);
7245 assertSuccess(fileLine
+ " Formattable.getnt64()", int64ConversionF
);
7246 assertSuccess(fileLine
+ " ufmt_getInt64()", int64ConversionU
);
7250 return exactMatch
|| !triedExact
;
7253 void NumberFormatTest::TestUFormattable(void) {
7255 // test that a default formattable is equal to Formattable()
7256 UErrorCode status
= U_ZERO_ERROR
;
7257 LocalUFormattablePointer
defaultUFormattable(ufmt_open(&status
));
7258 assertSuccess("calling umt_open", status
);
7259 Formattable defaultFormattable
;
7260 assertTrue((UnicodeString
)"comparing ufmt_open() with Formattable()",
7262 == *(Formattable::fromUFormattable(defaultUFormattable
.getAlias()))));
7263 assertTrue((UnicodeString
)"comparing ufmt_open() with Formattable()",
7265 == *(Formattable::fromUFormattable(defaultUFormattable
.getAlias()))));
7266 assertTrue((UnicodeString
)"comparing Formattable() round tripped through UFormattable",
7268 == *(Formattable::fromUFormattable(defaultFormattable
.toUFormattable()))));
7269 assertTrue((UnicodeString
)"comparing &Formattable() round tripped through UFormattable",
7270 ((&defaultFormattable
)
7271 == Formattable::fromUFormattable(defaultFormattable
.toUFormattable())));
7272 assertFalse((UnicodeString
)"comparing &Formattable() with ufmt_open()",
7273 ((&defaultFormattable
)
7274 == Formattable::fromUFormattable(defaultUFormattable
.getAlias())));
7275 testFormattableAsUFormattable(__FILE__
, __LINE__
, defaultFormattable
);
7277 // test some random Formattables
7279 Formattable
f(ucal_getNow(), Formattable::kIsDate
);
7280 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7283 Formattable
f((double)1.61803398874989484820); // golden ratio
7284 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7287 Formattable
f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
7288 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7291 Formattable
f((int32_t)4); // random number, source: http://www.xkcd.com/221/
7292 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7295 Formattable
f("Hello world."); // should be invariant?
7296 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7299 UErrorCode status2
= U_ZERO_ERROR
;
7300 Formattable
f(StringPiece("73476730924573500000000.0"), status2
); // weight of the moon, kg
7301 assertSuccess("Constructing a StringPiece", status2
);
7302 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7305 UErrorCode status2
= U_ZERO_ERROR
;
7306 UObject
*obj
= new Locale();
7308 assertSuccess("Constructing a Formattable from a default constructed Locale()", status2
);
7309 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7312 const Formattable array
[] = {
7313 Formattable(ucal_getNow(), Formattable::kIsDate
),
7314 Formattable((int32_t)4),
7315 Formattable((double)1.234),
7318 Formattable
fa(array
, 3);
7319 testFormattableAsUFormattable(__FILE__
, __LINE__
, fa
);
7323 void NumberFormatTest::TestSignificantDigits(void) {
7330 123.44501, -123.44501,
7331 0.001234, -0.001234,
7332 0.00000000123, -0.00000000123,
7333 0.0000000000000000000123, -0.0000000000000000000123,
7335 0.0000000012344501, -0.0000000012344501,
7336 123445.01, -123445.01,
7337 12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
7339 const char* expected
[] = {
7344 "123.45", "-123.45",
7345 "123.45", "-123.45",
7346 "0.001234", "-0.001234",
7347 "0.00000000123", "-0.00000000123",
7348 "0.0000000000000000000123", "-0.0000000000000000000123",
7350 "0.0000000012345", "-0.0000000012345",
7351 "123450", "-123450",
7352 "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
7355 UErrorCode status
= U_ZERO_ERROR
;
7356 Locale
locale("en_US");
7357 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7358 NumberFormat::createInstance(locale
, status
)));
7359 CHECK_DATA(status
,"NumberFormat::createInstance")
7361 numberFormat
->setSignificantDigitsUsed(TRUE
);
7362 numberFormat
->setMinimumSignificantDigits(3);
7363 numberFormat
->setMaximumSignificantDigits(5);
7364 numberFormat
->setGroupingUsed(false);
7366 UnicodeString result
;
7367 UnicodeString expectedResult
;
7368 for (unsigned int i
= 0; i
< UPRV_LENGTHOF(input
); ++i
) {
7369 numberFormat
->format(input
[i
], result
);
7370 UnicodeString
expectedResult(expected
[i
]);
7371 if (result
!= expectedResult
) {
7372 errln((UnicodeString
)"Expected: '" + expectedResult
+ "' got '" + result
);
7378 void NumberFormatTest::TestShowZero() {
7379 UErrorCode status
= U_ZERO_ERROR
;
7380 Locale
locale("en_US");
7381 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7382 NumberFormat::createInstance(locale
, status
)));
7383 CHECK_DATA(status
, "NumberFormat::createInstance")
7385 numberFormat
->setSignificantDigitsUsed(TRUE
);
7386 numberFormat
->setMaximumSignificantDigits(3);
7388 UnicodeString result
;
7389 numberFormat
->format(0.0, result
);
7390 if (result
!= "0") {
7391 errln((UnicodeString
)"Expected: 0, got " + result
);
7395 void NumberFormatTest::TestBug9936() {
7396 UErrorCode status
= U_ZERO_ERROR
;
7397 Locale
locale("en_US");
7398 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7399 NumberFormat::createInstance(locale
, status
)));
7400 if (U_FAILURE(status
)) {
7401 dataerrln("File %s, Line %d: status = %s.\n", __FILE__
, __LINE__
, u_errorName(status
));
7405 if (numberFormat
->areSignificantDigitsUsed() == TRUE
) {
7406 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__
, __LINE__
);
7408 numberFormat
->setSignificantDigitsUsed(TRUE
);
7409 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7410 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7413 numberFormat
->setSignificantDigitsUsed(FALSE
);
7414 if (numberFormat
->areSignificantDigitsUsed() == TRUE
) {
7415 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__
, __LINE__
);
7418 numberFormat
->setMinimumSignificantDigits(3);
7419 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7420 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7423 numberFormat
->setSignificantDigitsUsed(FALSE
);
7424 numberFormat
->setMaximumSignificantDigits(6);
7425 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7426 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7431 void NumberFormatTest::TestParseNegativeWithFaLocale() {
7432 UErrorCode status
= U_ZERO_ERROR
;
7433 DecimalFormat
*test
= (DecimalFormat
*) NumberFormat::createInstance("fa", status
);
7434 CHECK_DATA(status
, "NumberFormat::createInstance")
7435 test
->setLenient(TRUE
);
7438 UnicodeString
value("\\u200e-0,5");
7439 value
= value
.unescape();
7440 test
->parse(value
, af
, ppos
);
7441 if (ppos
.getIndex() == 0) {
7442 errln("Expected -0,5 to parse for Farsi.");
7447 void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() {
7448 UErrorCode status
= U_ZERO_ERROR
;
7449 DecimalFormat
*test
= (DecimalFormat
*) NumberFormat::createInstance("en", status
);
7450 CHECK_DATA(status
, "NumberFormat::createInstance")
7451 test
->setLenient(TRUE
);
7454 UnicodeString
value("\\u208B0.5");
7455 value
= value
.unescape();
7456 test
->parse(value
, af
, ppos
);
7457 if (ppos
.getIndex() == 0) {
7458 errln(UnicodeString("Expected ") + value
+ UnicodeString(" to parse."));
7463 void NumberFormatTest::TestCustomCurrencySignAndSeparator() {
7464 UErrorCode status
= U_ZERO_ERROR
;
7465 DecimalFormatSymbols
custom(Locale::getUS(), status
);
7466 CHECK(status
, "DecimalFormatSymbols constructor");
7468 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "*");
7469 custom
.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
, "^");
7470 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, ":");
7472 UnicodeString
pat(" #,##0.00");
7473 pat
.insert(0, (UChar
)0x00A4);
7475 DecimalFormat
fmt(pat
, custom
, status
);
7476 CHECK(status
, "DecimalFormat constructor");
7478 UnicodeString
numstr("* 1^234:56");
7479 expect2(fmt
, (Formattable
)((double)1234.56), numstr
);
7483 const char * locale
;
7485 UnicodeString numString
;
7487 } SignsAndMarksItem
;
7490 void NumberFormatTest::TestParseSignsAndMarks() {
7491 const SignsAndMarksItem items
[] = {
7492 // locale lenient numString value
7493 { "en", FALSE
, CharsToUnicodeString("12"), 12 },
7494 { "en", TRUE
, CharsToUnicodeString("12"), 12 },
7495 { "en", FALSE
, CharsToUnicodeString("-23"), -23 },
7496 { "en", TRUE
, CharsToUnicodeString("-23"), -23 },
7497 { "en", TRUE
, CharsToUnicodeString("- 23"), -23 },
7498 { "en", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7499 { "en", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7500 { "en", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7502 { "en@numbers=arab", FALSE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7503 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7504 { "en@numbers=arab", FALSE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7505 { "en@numbers=arab", TRUE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7506 { "en@numbers=arab", TRUE
, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7507 { "en@numbers=arab", FALSE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7508 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7509 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7511 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7512 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7513 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7514 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7515 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7516 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7517 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7518 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7520 { "he", FALSE
, CharsToUnicodeString("12"), 12 },
7521 { "he", TRUE
, CharsToUnicodeString("12"), 12 },
7522 { "he", FALSE
, CharsToUnicodeString("-23"), -23 },
7523 { "he", TRUE
, CharsToUnicodeString("-23"), -23 },
7524 { "he", TRUE
, CharsToUnicodeString("- 23"), -23 },
7525 { "he", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7526 { "he", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7527 { "he", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7529 { "ar", FALSE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7530 { "ar", TRUE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7531 { "ar", FALSE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7532 { "ar", TRUE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7533 { "ar", TRUE
, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7534 { "ar", FALSE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7535 { "ar", TRUE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7536 { "ar", TRUE
, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7538 { "ar_MA", FALSE
, CharsToUnicodeString("12"), 12 },
7539 { "ar_MA", TRUE
, CharsToUnicodeString("12"), 12 },
7540 { "ar_MA", FALSE
, CharsToUnicodeString("-23"), -23 },
7541 { "ar_MA", TRUE
, CharsToUnicodeString("-23"), -23 },
7542 { "ar_MA", TRUE
, CharsToUnicodeString("- 23"), -23 },
7543 { "ar_MA", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7544 { "ar_MA", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7545 { "ar_MA", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7547 { "fa", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7548 { "fa", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7549 { "fa", FALSE
, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7550 { "fa", TRUE
, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7551 { "fa", TRUE
, CharsToUnicodeString("\\u2212 \\u06F6\\u06F7"), -67 },
7552 { "fa", FALSE
, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7553 { "fa", TRUE
, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7554 { "fa", TRUE
, CharsToUnicodeString("\\u200E\\u2212\\u200E \\u06F6\\u06F7"), -67 },
7556 { "ps", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7557 { "ps", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7558 { "ps", FALSE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7559 { "ps", TRUE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7560 { "ps", TRUE
, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7561 { "ps", FALSE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7562 { "ps", TRUE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7563 { "ps", TRUE
, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7564 { "ps", FALSE
, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7565 { "ps", TRUE
, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7566 { "ps", TRUE
, CharsToUnicodeString("-\\u200E \\u06F6\\u06F7"), -67 },
7568 { NULL
, 0, UnicodeString(""), 0 },
7571 const SignsAndMarksItem
* itemPtr
;
7572 for (itemPtr
= items
; itemPtr
->locale
!= NULL
; itemPtr
++ ) {
7573 UErrorCode status
= U_ZERO_ERROR
;
7574 NumberFormat
*numfmt
= NumberFormat::createInstance(Locale(itemPtr
->locale
), status
);
7575 if (U_SUCCESS(status
)) {
7576 numfmt
->setLenient(itemPtr
->lenient
);
7579 numfmt
->parse(itemPtr
->numString
, fmtobj
, ppos
);
7580 if (ppos
.getIndex() == itemPtr
->numString
.length()) {
7581 double parsedValue
= fmtobj
.getDouble(status
);
7582 if (U_FAILURE(status
) || parsedValue
!= itemPtr
->value
) {
7583 errln((UnicodeString
)"FAIL: locale " + itemPtr
->locale
+ ", lenient " + itemPtr
->lenient
+ ", parse of \"" + itemPtr
->numString
+ "\" gives value " + parsedValue
);
7586 errln((UnicodeString
)"FAIL: locale " + itemPtr
->locale
+ ", lenient " + itemPtr
->lenient
+ ", parse of \"" + itemPtr
->numString
+ "\" gives position " + ppos
.getIndex());
7589 dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr
->locale
, u_errorName(status
));
7596 DecimalFormat::ERoundingMode mode
;
7598 UnicodeString expected
;
7602 // Tests that rounding works right when fractional digits is set to 0.
7603 void NumberFormatTest::Test10419RoundingWith0FractionDigits() {
7604 const Test10419Data items
[] = {
7605 { DecimalFormat::kRoundCeiling
, 1.488, "2"},
7606 { DecimalFormat::kRoundDown
, 1.588, "1"},
7607 { DecimalFormat::kRoundFloor
, 1.888, "1"},
7608 { DecimalFormat::kRoundHalfDown
, 1.5, "1"},
7609 { DecimalFormat::kRoundHalfEven
, 2.5, "2"},
7610 { DecimalFormat::kRoundHalfUp
, 2.5, "3"},
7611 { DecimalFormat::kRoundUp
, 1.5, "2"},
7613 UErrorCode status
= U_ZERO_ERROR
;
7614 LocalPointer
<DecimalFormat
> decfmt((DecimalFormat
*) NumberFormat::createInstance(Locale("en_US"), status
));
7615 if (U_FAILURE(status
)) {
7616 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
7619 for (int32_t i
= 0; i
< UPRV_LENGTHOF(items
); ++i
) {
7620 decfmt
->setRoundingMode(items
[i
].mode
);
7621 decfmt
->setMaximumFractionDigits(0);
7622 UnicodeString actual
;
7623 if (items
[i
].expected
!= decfmt
->format(items
[i
].value
, actual
)) {
7624 errln("Expected " + items
[i
].expected
+ ", got " + actual
);
7629 void NumberFormatTest::Test10468ApplyPattern() {
7630 // Padding char of fmt is now 'a'
7631 UErrorCode status
= U_ZERO_ERROR
;
7632 DecimalFormat
fmt("'I''ll'*a###.##", status
);
7634 if (U_FAILURE(status
)) {
7635 errcheckln(status
, "DecimalFormat constructor failed - %s", u_errorName(status
));
7639 assertEquals("Padding character should be 'a'.", u
"a", fmt
.getPadCharacterString());
7641 // Padding char of fmt ought to be '*' since that is the default and no
7642 // explicit padding char is specified in the new pattern.
7643 fmt
.applyPattern("AA#,##0.00ZZ", status
);
7645 // Oops this still prints 'a' even though we changed the pattern.
7646 assertEquals("applyPattern did not clear padding character.", u
" ", fmt
.getPadCharacterString());
7649 void NumberFormatTest::TestRoundingScientific10542() {
7650 UErrorCode status
= U_ZERO_ERROR
;
7651 DecimalFormat
format("0.00E0", status
);
7652 if (U_FAILURE(status
)) {
7653 errcheckln(status
, "DecimalFormat constructor failed - %s", u_errorName(status
));
7657 DecimalFormat::ERoundingMode roundingModes
[] = {
7658 DecimalFormat::kRoundCeiling
,
7659 DecimalFormat::kRoundDown
,
7660 DecimalFormat::kRoundFloor
,
7661 DecimalFormat::kRoundHalfDown
,
7662 DecimalFormat::kRoundHalfEven
,
7663 DecimalFormat::kRoundHalfUp
,
7664 DecimalFormat::kRoundUp
};
7665 const char *descriptions
[] = {
7675 double values
[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
7676 // The order of these expected values correspond to the order of roundingModes and the order of values.
7677 const char *expected
[] = {
7678 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3",
7679 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7680 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7681 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3",
7682 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7683 "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7684 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"};
7691 UPRV_LENGTHOF(values
),
7692 UPRV_LENGTHOF(roundingModes
));
7695 double values
[] = {-3006.0, -3005, -3004, 3014, 3015, 3016};
7696 // The order of these expected values correspond to the order of roundingModes and the order of values.
7697 const char *expected
[] = {
7698 "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3",
7699 "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3",
7700 "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3",
7701 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3",
7702 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7703 "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7704 "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"};
7711 UPRV_LENGTHOF(values
),
7712 UPRV_LENGTHOF(roundingModes
));
7714 /* Commented out for now until we decide how rounding to zero should work, +0 vs. -0
7716 double values[] = {0.0, -0.0};
7717 // The order of these expected values correspond to the order of roundingModes and the order of values.
7718 const char *expected[] = {
7719 "0.00E0", "-0.00E0",
7720 "0.00E0", "-0.00E0",
7721 "0.00E0", "-0.00E0",
7722 "0.00E0", "-0.00E0",
7723 "0.00E0", "-0.00E0",
7724 "0.00E0", "-0.00E0",
7725 "0.00E0", "-0.00E0"};
7732 UPRV_LENGTHOF(values),
7733 UPRV_LENGTHOF(roundingModes));
7738 double values
[] = {1e25
, 1e25
+ 1e15
, 1e25
- 1e15
};
7739 // The order of these expected values correspond to the order of roundingModes and the order of values.
7740 const char *expected
[] = {
7741 "1.00E25", "1.01E25", "1.00E25",
7742 "1.00E25", "1.00E25", "9.99E24",
7743 "1.00E25", "1.00E25", "9.99E24",
7744 "1.00E25", "1.00E25", "1.00E25",
7745 "1.00E25", "1.00E25", "1.00E25",
7746 "1.00E25", "1.00E25", "1.00E25",
7747 "1.00E25", "1.01E25", "1.00E25"};
7754 UPRV_LENGTHOF(values
),
7755 UPRV_LENGTHOF(roundingModes
));
7758 double values
[] = {-1e25
, -1e25
+ 1e15
, -1e25
- 1e15
};
7759 // The order of these expected values correspond to the order of roundingModes and the order of values.
7760 const char *expected
[] = {
7761 "-1.00E25", "-9.99E24", "-1.00E25",
7762 "-1.00E25", "-9.99E24", "-1.00E25",
7763 "-1.00E25", "-1.00E25", "-1.01E25",
7764 "-1.00E25", "-1.00E25", "-1.00E25",
7765 "-1.00E25", "-1.00E25", "-1.00E25",
7766 "-1.00E25", "-1.00E25", "-1.00E25",
7767 "-1.00E25", "-1.00E25", "-1.01E25"};
7774 UPRV_LENGTHOF(values
),
7775 UPRV_LENGTHOF(roundingModes
));
7778 double values
[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35};
7779 // The order of these expected values correspond to the order of roundingModes and the order of values.
7780 const char *expected
[] = {
7781 "1.00E-25", "1.01E-25", "1.00E-25",
7782 "1.00E-25", "1.00E-25", "9.99E-26",
7783 "1.00E-25", "1.00E-25", "9.99E-26",
7784 "1.00E-25", "1.00E-25", "1.00E-25",
7785 "1.00E-25", "1.00E-25", "1.00E-25",
7786 "1.00E-25", "1.00E-25", "1.00E-25",
7787 "1.00E-25", "1.01E-25", "1.00E-25"};
7794 UPRV_LENGTHOF(values
),
7795 UPRV_LENGTHOF(roundingModes
));
7798 double values
[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35};
7799 // The order of these expected values correspond to the order of roundingModes and the order of values.
7800 const char *expected
[] = {
7801 "-1.00E-25", "-9.99E-26", "-1.00E-25",
7802 "-1.00E-25", "-9.99E-26", "-1.00E-25",
7803 "-1.00E-25", "-1.00E-25", "-1.01E-25",
7804 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7805 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7806 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7807 "-1.00E-25", "-1.00E-25", "-1.01E-25"};
7814 UPRV_LENGTHOF(values
),
7815 UPRV_LENGTHOF(roundingModes
));
7819 void NumberFormatTest::TestZeroScientific10547() {
7820 UErrorCode status
= U_ZERO_ERROR
;
7821 DecimalFormat
fmt("0.00E0", status
);
7822 if (!assertSuccess("Format creation", status
)) {
7826 fmt
.format(-0.0, out
);
7827 assertEquals("format", "-0.00E0", out
, true);
7830 void NumberFormatTest::verifyRounding(
7831 DecimalFormat
& format
,
7832 const double *values
,
7833 const char * const *expected
,
7834 const DecimalFormat::ERoundingMode
*roundingModes
,
7835 const char * const *descriptions
,
7837 int32_t roundingModeSize
) {
7838 for (int32_t i
= 0; i
< roundingModeSize
; ++i
) {
7839 format
.setRoundingMode(roundingModes
[i
]);
7840 for (int32_t j
= 0; j
< valueSize
; j
++) {
7841 UnicodeString
currentExpected(expected
[i
* valueSize
+ j
]);
7842 currentExpected
= currentExpected
.unescape();
7843 UnicodeString actual
;
7844 format
.format(values
[j
], actual
);
7845 if (currentExpected
!= actual
) {
7846 dataerrln("For %s value %f, expected '%s', got '%s'",
7847 descriptions
[i
], values
[j
], CStr(currentExpected
)(), CStr(actual
)());
7853 void NumberFormatTest::TestAccountingCurrency() {
7854 UErrorCode status
= U_ZERO_ERROR
;
7855 UNumberFormatStyle style
= UNUM_CURRENCY_ACCOUNTING
;
7857 expect(NumberFormat::createInstance("en_US", style
, status
),
7858 (Formattable
)(double)1234.5, "$1,234.50", TRUE
, status
);
7859 expect(NumberFormat::createInstance("en_US", style
, status
),
7860 (Formattable
)(double)-1234.5, "($1,234.50)", TRUE
, status
);
7861 expect(NumberFormat::createInstance("en_US", style
, status
),
7862 (Formattable
)(double)0, "$0.00", TRUE
, status
);
7863 expect(NumberFormat::createInstance("en_US", style
, status
),
7864 (Formattable
)(double)-0.2, "($0.20)", TRUE
, status
);
7865 expect(NumberFormat::createInstance("ja_JP", style
, status
),
7866 (Formattable
)10000, UnicodeString("\\u00A510,000").unescape(), TRUE
, status
);
7867 expect(NumberFormat::createInstance("ja_JP", style
, status
),
7868 (Formattable
)-1000.5, UnicodeString("(\\u00A51,000)").unescape(), FALSE
, status
);
7869 expect(NumberFormat::createInstance("de_DE", style
, status
),
7870 (Formattable
)(double)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE
, status
);
7874 void NumberFormatTest::TestEquality() {
7875 UErrorCode status
= U_ZERO_ERROR
;
7876 DecimalFormatSymbols
symbols(Locale("root"), status
);
7877 if (U_FAILURE(status
)) {
7878 dataerrln("Fail: can't create DecimalFormatSymbols for root");
7881 UnicodeString
pattern("#,##0.###");
7882 DecimalFormat
fmtBase(pattern
, symbols
, status
);
7883 if (U_FAILURE(status
)) {
7884 dataerrln("Fail: can't create DecimalFormat using root symbols");
7888 DecimalFormat
* fmtClone
= (DecimalFormat
*)fmtBase
.clone();
7889 fmtClone
->setFormatWidth(fmtBase
.getFormatWidth() + 32);
7890 if (*fmtClone
== fmtBase
) {
7891 errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
7896 void NumberFormatTest::TestCurrencyUsage() {
7897 double agent
= 123.567;
7902 // compare the Currency and Currency Cash Digits
7903 // Note that as of CLDR 26:
7904 // * TWD switches from 0 decimals to 2; PKR still has 0, so change test to that
7905 // * CAD rounds to .05 in cash mode only
7906 // 1st time for getter/setter, 2nd time for factory method
7907 Locale
enUS_PKR("en_US@currency=PKR");
7909 for(int i
=0; i
<2; i
++){
7910 status
= U_ZERO_ERROR
;
7912 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_PKR
, UNUM_CURRENCY
, status
);
7913 if (assertSuccess("en_US@currency=PKR/CURRENCY", status
, TRUE
) == FALSE
) {
7917 UnicodeString original
;
7918 fmt
->format(agent
,original
);
7919 assertEquals("Test Currency Usage 1", u
"PKR124", original
); // use ICU 61 behavior
7921 // test the getter here
7922 UCurrencyUsage curUsage
= fmt
->getCurrencyUsage();
7923 assertEquals("Test usage getter - standard", (int32_t)curUsage
, (int32_t)UCURR_USAGE_STANDARD
);
7925 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
7927 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_PKR
, UNUM_CASH_CURRENCY
, status
);
7928 if (assertSuccess("en_US@currency=PKR/CASH", status
, TRUE
) == FALSE
) {
7933 // must be usage = cash
7934 UCurrencyUsage curUsage
= fmt
->getCurrencyUsage();
7935 assertEquals("Test usage getter - cash", (int32_t)curUsage
, (int32_t)UCURR_USAGE_CASH
);
7937 UnicodeString cash_currency
;
7938 fmt
->format(agent
,cash_currency
);
7939 assertEquals("Test Currency Usage 2", u
"PKR124", cash_currency
); // use ICU 61 behavior
7943 // compare the Currency and Currency Cash Rounding
7944 // 1st time for getter/setter, 2nd time for factory method
7945 Locale
enUS_CAD("en_US@currency=CAD");
7946 for(int i
=0; i
<2; i
++){
7947 status
= U_ZERO_ERROR
;
7949 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CURRENCY
, status
);
7950 if (assertSuccess("en_US@currency=CAD/CURRENCY", status
, TRUE
) == FALSE
) {
7954 UnicodeString original_rounding
;
7955 fmt
->format(agent
, original_rounding
);
7956 assertEquals("Test Currency Usage 3", u
"CA$123.57", original_rounding
);
7957 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
7959 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CASH_CURRENCY
, status
);
7960 if (assertSuccess("en_US@currency=CAD/CASH", status
, TRUE
) == FALSE
) {
7965 UnicodeString cash_rounding_currency
;
7966 fmt
->format(agent
, cash_rounding_currency
);
7967 assertEquals("Test Currency Usage 4", u
"CA$123.55", cash_rounding_currency
);
7971 // Test the currency change
7972 // 1st time for getter/setter, 2nd time for factory method
7973 const UChar CUR_PKR
[] = {0x50, 0x4B, 0x52, 0};
7974 for(int i
=0; i
<2; i
++){
7975 status
= U_ZERO_ERROR
;
7977 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CURRENCY
, status
);
7978 if (assertSuccess("en_US@currency=CAD/CURRENCY", status
, TRUE
) == FALSE
) {
7981 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
7983 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CASH_CURRENCY
, status
);
7984 if (assertSuccess("en_US@currency=CAD/CASH", status
, TRUE
) == FALSE
) {
7989 UnicodeString cur_original
;
7990 fmt
->setCurrencyUsage(UCURR_USAGE_STANDARD
, &status
);
7991 fmt
->format(agent
, cur_original
);
7992 assertEquals("Test Currency Usage 5", u
"CA$123.57", cur_original
);
7994 fmt
->setCurrency(CUR_PKR
, status
);
7995 assertSuccess("Set currency to PKR", status
);
7997 UnicodeString PKR_changed
;
7998 fmt
->format(agent
, PKR_changed
);
7999 assertEquals("Test Currency Usage 6", u
"PKR124", PKR_changed
); // use ICU 61 behavior
8005 // Check the constant MAX_INT64_IN_DOUBLE.
8006 // The value should convert to a double with no loss of precision.
8007 // A failure may indicate a platform with a different double format, requiring
8008 // a revision to the constant.
8010 // Note that this is actually hard to test, because the language standard gives
8011 // compilers considerable flexibility to do unexpected things with rounding and
8012 // with overflow in simple int to/from float conversions. Some compilers will completely optimize
8013 // away a simple round-trip conversion from int64_t -> double -> int64_t.
8015 void NumberFormatTest::TestDoubleLimit11439() {
8017 for (int64_t num
= MAX_INT64_IN_DOUBLE
-10; num
<=MAX_INT64_IN_DOUBLE
; num
++) {
8018 sprintf(buf
, "%lld", (long long)num
);
8020 sscanf(buf
, "%lf", &fNum
);
8021 int64_t rtNum
= static_cast<int64_t>(fNum
);
8023 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__
, __LINE__
, (long long)num
, (long long)rtNum
);
8027 for (int64_t num
= -MAX_INT64_IN_DOUBLE
+10; num
>=-MAX_INT64_IN_DOUBLE
; num
--) {
8028 sprintf(buf
, "%lld", (long long)num
);
8030 sscanf(buf
, "%lf", &fNum
);
8031 int64_t rtNum
= static_cast<int64_t>(fNum
);
8033 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__
, __LINE__
, (long long)num
, (long long)rtNum
);
8039 void NumberFormatTest::TestGetAffixes() {
8040 UErrorCode status
= U_ZERO_ERROR
;
8041 DecimalFormatSymbols
sym("en_US", status
);
8042 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8043 pattern
= pattern
.unescape();
8044 DecimalFormat
fmt(pattern
, sym
, status
);
8045 if (U_FAILURE(status
)) {
8046 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8049 UnicodeString affixStr
;
8050 assertEquals("", "US dollars ", fmt
.getPositivePrefix(affixStr
));
8051 assertEquals("", " %USD", fmt
.getPositiveSuffix(affixStr
));
8052 assertEquals("", "-US dollars ", fmt
.getNegativePrefix(affixStr
));
8053 assertEquals("", " %USD", fmt
.getNegativeSuffix(affixStr
));
8055 // Test equality with affixes. set affix methods can't capture special
8056 // characters which is why equality should fail.
8058 DecimalFormat
fmtCopy(fmt
);
8059 assertTrue("", fmt
== fmtCopy
);
8060 UnicodeString someAffix
;
8061 fmtCopy
.setPositivePrefix(fmtCopy
.getPositivePrefix(someAffix
));
8062 assertTrue("", fmt
!= fmtCopy
);
8065 DecimalFormat
fmtCopy(fmt
);
8066 assertTrue("", fmt
== fmtCopy
);
8067 UnicodeString someAffix
;
8068 fmtCopy
.setPositiveSuffix(fmtCopy
.getPositiveSuffix(someAffix
));
8069 assertTrue("", fmt
!= fmtCopy
);
8072 DecimalFormat
fmtCopy(fmt
);
8073 assertTrue("", fmt
== fmtCopy
);
8074 UnicodeString someAffix
;
8075 fmtCopy
.setNegativePrefix(fmtCopy
.getNegativePrefix(someAffix
));
8076 assertTrue("", fmt
!= fmtCopy
);
8079 DecimalFormat
fmtCopy(fmt
);
8080 assertTrue("", fmt
== fmtCopy
);
8081 UnicodeString someAffix
;
8082 fmtCopy
.setNegativeSuffix(fmtCopy
.getNegativeSuffix(someAffix
));
8083 assertTrue("", fmt
!= fmtCopy
);
8085 fmt
.setPositivePrefix("Don't");
8086 fmt
.setPositiveSuffix("do");
8087 UnicodeString
someAffix("be''eet\\u00a4\\u00a4\\u00a4 it.");
8088 someAffix
= someAffix
.unescape();
8089 fmt
.setNegativePrefix(someAffix
);
8090 fmt
.setNegativeSuffix("%");
8091 assertEquals("", "Don't", fmt
.getPositivePrefix(affixStr
));
8092 assertEquals("", "do", fmt
.getPositiveSuffix(affixStr
));
8093 assertEquals("", someAffix
, fmt
.getNegativePrefix(affixStr
));
8094 assertEquals("", "%", fmt
.getNegativeSuffix(affixStr
));
8097 void NumberFormatTest::TestToPatternScientific11648() {
8098 UErrorCode status
= U_ZERO_ERROR
;
8100 DecimalFormatSymbols
sym(en
, status
);
8101 DecimalFormat
fmt("0.00", sym
, status
);
8102 if (U_FAILURE(status
)) {
8103 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8106 fmt
.setScientificNotation(TRUE
);
8107 UnicodeString pattern
;
8108 assertEquals("", "0.00E0", fmt
.toPattern(pattern
));
8109 DecimalFormat
fmt2(pattern
, sym
, status
);
8110 assertSuccess("", status
);
8113 void NumberFormatTest::TestBenchmark() {
8115 UErrorCode status = U_ZERO_ERROR;
8117 DecimalFormatSymbols sym(en, status);
8118 DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(sym), status);
8119 // DecimalFormat fmt("0.00000E0", new DecimalFormatSymbols(sym), status);
8120 // DecimalFormat fmt("0", new DecimalFormatSymbols(sym), status);
8121 FieldPosition fpos(FieldPosition::DONT_CARE);
8122 clock_t start = clock();
8123 for (int32_t i = 0; i < 1000000; ++i) {
8124 UnicodeString append;
8125 fmt.format(3.0, append, fpos, status);
8126 // fmt.format(4.6692016, append, fpos, status);
8127 // fmt.format(1234567.8901, append, fpos, status);
8128 // fmt.format(2.99792458E8, append, fpos, status);
8129 // fmt.format(31, append);
8131 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8132 assertSuccess("", status);
8134 UErrorCode status = U_ZERO_ERROR;
8135 MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status);
8136 FieldPosition fpos(FieldPosition::DONT_CARE);
8137 Formattable one(1.0);
8138 Formattable three(3.0);
8139 clock_t start = clock();
8140 for (int32_t i = 0; i < 500000; ++i) {
8141 UnicodeString append;
8142 fmt.format(&one, 1, append, fpos, status);
8143 UnicodeString append2;
8144 fmt.format(&three, 1, append2, fpos, status);
8146 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8147 assertSuccess("", status);
8149 UErrorCode status = U_ZERO_ERROR;
8151 Measure measureC(23, MeasureUnit::createCelsius(status), status);
8152 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
8153 FieldPosition fpos(FieldPosition::DONT_CARE);
8154 clock_t start = clock();
8155 for (int32_t i = 0; i < 1000000; ++i) {
8156 UnicodeString appendTo;
8158 &measureC, 1, appendTo, fpos, status);
8160 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8161 assertSuccess("", status);
8165 void NumberFormatTest::TestFractionalDigitsForCurrency() {
8166 UErrorCode status
= U_ZERO_ERROR
;
8167 LocalPointer
<NumberFormat
> fmt(NumberFormat::createCurrencyInstance("en", status
));
8168 if (U_FAILURE(status
)) {
8169 dataerrln("Error creating NumberFormat - %s", u_errorName(status
));
8172 UChar JPY
[] = {0x4A, 0x50, 0x59, 0x0};
8173 fmt
->setCurrency(JPY
, status
);
8174 if (!assertSuccess("", status
)) {
8177 assertEquals("", 0, fmt
->getMaximumFractionDigits());
8181 void NumberFormatTest::TestFormatCurrencyPlural() {
8182 UErrorCode status
= U_ZERO_ERROR
;
8183 Locale locale
= Locale::createCanonical("en_US");
8184 NumberFormat
*fmt
= NumberFormat::createInstance(locale
, UNUM_CURRENCY_PLURAL
, status
);
8185 if (U_FAILURE(status
)) {
8186 dataerrln("Error creating NumberFormat - %s", u_errorName(status
));
8189 UnicodeString formattedNum
;
8190 fmt
->format(11234.567, formattedNum
, NULL
, status
);
8191 assertEquals("", "11,234.57 US dollars", formattedNum
);
8195 void NumberFormatTest::TestCtorApplyPatternDifference() {
8196 UErrorCode status
= U_ZERO_ERROR
;
8197 DecimalFormatSymbols
sym("en_US", status
);
8198 UnicodeString
pattern("\\u00a40");
8199 DecimalFormat
fmt(pattern
.unescape(), sym
, status
);
8200 if (U_FAILURE(status
)) {
8201 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8204 UnicodeString result
;
8206 "ctor favors precision of currency",
8208 fmt
.format((double)5, result
));
8210 fmt
.applyPattern(pattern
.unescape(), status
);
8212 "applyPattern favors precision of pattern",
8214 fmt
.format((double)5, result
));
8217 void NumberFormatTest::Test11868() {
8218 double posAmt
= 34.567;
8219 double negAmt
= -9876.543;
8221 Locale
selectedLocale("en_US");
8222 UErrorCode status
= U_ZERO_ERROR
;
8224 UnicodeString result
;
8225 FieldPosition
fpCurr(UNUM_CURRENCY_FIELD
);
8226 LocalPointer
<NumberFormat
> fmt(
8227 NumberFormat::createInstance(
8228 selectedLocale
, UNUM_CURRENCY_PLURAL
, status
));
8229 if (!assertSuccess("Format creation", status
)) {
8232 fmt
->format(posAmt
, result
, fpCurr
, status
);
8233 assertEquals("", "34.57 US dollars", result
);
8234 assertEquals("begin index", 6, fpCurr
.getBeginIndex());
8235 assertEquals("end index", 16, fpCurr
.getEndIndex());
8237 // Test field position iterator
8239 NumberFormatTest_Attributes attributes
[] = {
8240 {UNUM_INTEGER_FIELD
, 0, 2},
8241 {UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3},
8242 {UNUM_FRACTION_FIELD
, 3, 5},
8243 {UNUM_CURRENCY_FIELD
, 6, 16},
8245 UnicodeString result
;
8246 FieldPositionIterator iter
;
8247 fmt
->format(posAmt
, result
, &iter
, status
);
8248 assertEquals("", "34.57 US dollars", result
);
8249 verifyFieldPositionIterator(attributes
, iter
);
8253 fmt
->format(negAmt
, result
, fpCurr
, status
);
8254 assertEquals("", "-9,876.54 US dollars", result
);
8255 assertEquals("begin index", 10, fpCurr
.getBeginIndex());
8256 assertEquals("end index", 20, fpCurr
.getEndIndex());
8258 // Test field position iterator
8260 NumberFormatTest_Attributes attributes
[] = {
8261 {UNUM_SIGN_FIELD
, 0, 1},
8262 {UNUM_GROUPING_SEPARATOR_FIELD
, 2, 3},
8263 {UNUM_INTEGER_FIELD
, 1, 6},
8264 {UNUM_DECIMAL_SEPARATOR_FIELD
, 6, 7},
8265 {UNUM_FRACTION_FIELD
, 7, 9},
8266 {UNUM_CURRENCY_FIELD
, 10, 20},
8268 UnicodeString result
;
8269 FieldPositionIterator iter
;
8270 fmt
->format(negAmt
, result
, &iter
, status
);
8271 assertEquals("", "-9,876.54 US dollars", result
);
8272 verifyFieldPositionIterator(attributes
, iter
);
8276 void NumberFormatTest::Test10727_RoundingZero() {
8277 IcuTestErrorCode
status(*this, "Test10727_RoundingZero");
8279 dq
.setToDouble(-0.0);
8280 assertTrue("", dq
.isNegative());
8281 dq
.roundToMagnitude(0, UNUM_ROUND_HALFEVEN
, status
);
8282 assertTrue("", dq
.isNegative());
8285 void NumberFormatTest::Test11739_ParseLongCurrency() {
8286 IcuTestErrorCode
status(*this, "Test11739_ParseLongCurrency");
8287 LocalPointer
<NumberFormat
> nf(NumberFormat::createCurrencyInstance("sr_BA", status
));
8288 if (status
.errDataIfFailureAndReset()) { return; }
8289 ((DecimalFormat
*) nf
.getAlias())->applyPattern(u
"#,##0.0 ¤¤¤", status
);
8290 ParsePosition
ppos(0);
8291 LocalPointer
<CurrencyAmount
> result(nf
->parseCurrency(u
"1.500 амерички долар", ppos
));
8292 assertEquals("Should parse to 1500 USD", -1, ppos
.getErrorIndex());
8293 assertEquals("Should parse to 1500 USD", 1500LL, result
->getNumber().getInt64(status
));
8294 assertEquals("Should parse to 1500 USD", u
"USD", result
->getISOCurrency());
8297 void NumberFormatTest::Test13035_MultiCodePointPaddingInPattern() {
8298 IcuTestErrorCode
status(*this, "Test13035_MultiCodePointPaddingInPattern");
8299 DecimalFormat
df(u
"a*'நி'###0b", status
);
8300 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8301 UnicodeString result
;
8302 df
.format(12, result
.remove());
8303 // TODO(13034): Re-enable this test when support is added in ICU4C.
8304 //assertEquals("Multi-codepoint padding should not be split", u"aநிநி12b", result);
8305 df
= DecimalFormat(u
"a*\U0001F601###0b", status
);
8306 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8307 result
= df
.format(12, result
.remove());
8308 assertEquals("Single-codepoint padding should not be split", u
"a\U0001F601\U0001F60112b", result
, true);
8309 df
= DecimalFormat(u
"a*''###0b", status
);
8310 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8311 result
= df
.format(12, result
.remove());
8312 assertEquals("Quote should be escapable in padding syntax", "a''12b", result
, true);
8315 void NumberFormatTest::Test13737_ParseScientificStrict() {
8316 IcuTestErrorCode
status(*this, "Test13737_ParseScientificStrict");
8317 LocalPointer
<NumberFormat
> df(NumberFormat::createScientificInstance("en", status
), status
);
8318 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {return;}
8319 df
->setLenient(FALSE
);
8321 expect(*df
, u
"1.2", 1.2);
8324 void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
8326 const UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8327 UErrorCode status
= U_ZERO_ERROR
;
8328 LocalPointer
<NumberFormat
> fmt(
8329 NumberFormat::createCurrencyInstance("en", status
));
8330 if (!assertSuccess("", status
)) {
8333 DecimalFormat
*dfmt
= (DecimalFormat
*) fmt
.getAlias();
8334 dfmt
->setCurrency(USD
);
8335 UnicodeString result
;
8337 // This line should be a no-op. I am setting the positive prefix
8338 // to be the same thing it was before.
8339 dfmt
->setPositivePrefix(dfmt
->getPositivePrefix(result
));
8341 UnicodeString appendTo
;
8342 assertEquals("", "$3.78", dfmt
->format(3.78, appendTo
, status
));
8343 assertSuccess("", status
);
8346 const UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8347 UErrorCode status
= U_ZERO_ERROR
;
8348 LocalPointer
<NumberFormat
> fmt(
8349 NumberFormat::createInstance("en", UNUM_CURRENCY_PLURAL
, status
));
8350 if (!assertSuccess("", status
)) {
8353 DecimalFormat
*dfmt
= (DecimalFormat
*) fmt
.getAlias();
8354 UnicodeString result
;
8355 UnicodeString
tripleIntlCurrency(" \\u00a4\\u00a4\\u00a4");
8356 tripleIntlCurrency
= tripleIntlCurrency
.unescape();
8357 assertEquals("", tripleIntlCurrency
, dfmt
->getPositiveSuffix(result
)); // use ICU 61 behavior
8358 dfmt
->setCurrency(USD
);
8360 // getPositiveSuffix() always returns the suffix for the
8361 // "other" plural category
8362 assertEquals("", " US dollars", dfmt
->getPositiveSuffix(result
));
8363 UnicodeString appendTo
;
8364 assertEquals("", "3.78 US dollars", dfmt
->format(3.78, appendTo
, status
));
8365 assertEquals("", " US dollars", dfmt
->getPositiveSuffix(result
));
8366 dfmt
->setPositiveSuffix("booya");
8368 assertEquals("", "3.78booya", dfmt
->format(3.78, appendTo
, status
));
8369 assertEquals("", "booya", dfmt
->getPositiveSuffix(result
));
8373 void NumberFormatTest::Test11475_signRecognition() {
8374 UErrorCode status
= U_ZERO_ERROR
;
8375 DecimalFormatSymbols
sym("en", status
);
8376 UnicodeString result
;
8378 DecimalFormat
fmt("+0.00", sym
, status
);
8379 if (!assertSuccess("", status
)) {
8382 NumberFormatTest_Attributes attributes
[] = {
8383 {UNUM_SIGN_FIELD
, 0, 1},
8384 {UNUM_INTEGER_FIELD
, 1, 2},
8385 {UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3},
8386 {UNUM_FRACTION_FIELD
, 3, 5},
8388 UnicodeString result
;
8389 FieldPositionIterator iter
;
8390 fmt
.format(2.3, result
, &iter
, status
);
8391 assertEquals("", "+2.30", result
);
8392 verifyFieldPositionIterator(attributes
, iter
);
8395 DecimalFormat
fmt("++0.00+;-(#)--", sym
, status
);
8396 if (!assertSuccess("", status
)) {
8400 NumberFormatTest_Attributes attributes
[] = {
8401 {UNUM_SIGN_FIELD
, 0, 2},
8402 {UNUM_INTEGER_FIELD
, 2, 3},
8403 {UNUM_DECIMAL_SEPARATOR_FIELD
, 3, 4},
8404 {UNUM_FRACTION_FIELD
, 4, 6},
8405 {UNUM_SIGN_FIELD
, 6, 7},
8407 UnicodeString result
;
8408 FieldPositionIterator iter
;
8409 fmt
.format(2.3, result
, &iter
, status
);
8410 assertEquals("", "++2.30+", result
);
8411 verifyFieldPositionIterator(attributes
, iter
);
8414 NumberFormatTest_Attributes attributes
[] = {
8415 {UNUM_SIGN_FIELD
, 0, 1},
8416 {UNUM_INTEGER_FIELD
, 2, 3},
8417 {UNUM_DECIMAL_SEPARATOR_FIELD
, 3, 4},
8418 {UNUM_FRACTION_FIELD
, 4, 6},
8419 {UNUM_SIGN_FIELD
, 7, 9},
8421 UnicodeString result
;
8422 FieldPositionIterator iter
;
8423 fmt
.format(-2.3, result
, &iter
, status
);
8424 assertEquals("", "-(2.30)--", result
);
8425 verifyFieldPositionIterator(attributes
, iter
);
8430 void NumberFormatTest::Test11640_getAffixes() {
8431 UErrorCode status
= U_ZERO_ERROR
;
8432 DecimalFormatSymbols
symbols("en_US", status
);
8433 if (!assertSuccess("", status
)) {
8436 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8437 pattern
= pattern
.unescape();
8438 DecimalFormat
fmt(pattern
, symbols
, status
);
8439 if (!assertSuccess("", status
)) {
8442 UnicodeString affixStr
;
8443 assertEquals("", "US dollars ", fmt
.getPositivePrefix(affixStr
));
8444 assertEquals("", " %USD", fmt
.getPositiveSuffix(affixStr
));
8445 assertEquals("", "-US dollars ", fmt
.getNegativePrefix(affixStr
));
8446 assertEquals("", " %USD", fmt
.getNegativeSuffix(affixStr
));
8449 void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
8450 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00");
8451 pattern
= pattern
.unescape();
8452 UErrorCode status
= U_ZERO_ERROR
;
8453 DecimalFormat
fmt(pattern
, status
);
8454 if (!assertSuccess("", status
)) {
8457 static UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8458 fmt
.setCurrency(USD
);
8459 UnicodeString appendTo
;
8461 assertEquals("", "US dollars 12.34", fmt
.format(12.34, appendTo
));
8463 UnicodeString topattern
;
8464 fmt
.toPattern(topattern
);
8465 DecimalFormat
fmt2(topattern
, status
);
8466 if (!assertSuccess("", status
)) {
8469 fmt2
.setCurrency(USD
);
8472 assertEquals("", "US dollars 12.34", fmt2
.format(12.34, appendTo
));
8475 void NumberFormatTest::Test13327_numberingSystemBufferOverflow() {
8476 UErrorCode status
= U_ZERO_ERROR
;
8477 for (int runId
= 0; runId
< 2; runId
++) {
8478 // Construct a locale string with a very long "numbers" value.
8479 // The first time, make the value length exactly equal to ULOC_KEYWORDS_CAPACITY.
8480 // The second time, make it exceed ULOC_KEYWORDS_CAPACITY.
8481 int extraLength
= (runId
== 0) ? 0 : 5;
8483 CharString
localeId("en@numbers=", status
);
8484 for (int i
= 0; i
< ULOC_KEYWORDS_CAPACITY
+ extraLength
; i
++) {
8485 localeId
.append('x', status
);
8487 assertSuccess("Constructing locale string", status
);
8488 Locale
locale(localeId
.data());
8490 LocalPointer
<NumberingSystem
> ns(NumberingSystem::createInstance(locale
, status
));
8491 assertFalse("Should not be null", ns
.getAlias() == nullptr);
8492 assertSuccess("Should create with no error", status
);
8496 void NumberFormatTest::Test13391_chakmaParsing() {
8497 UErrorCode status
= U_ZERO_ERROR
;
8498 LocalPointer
<DecimalFormat
> df(dynamic_cast<DecimalFormat
*>(
8499 NumberFormat::createInstance(Locale("ccp"), status
)));
8500 if (df
== nullptr) {
8501 dataerrln("%s %d Chakma df is null", __FILE__
, __LINE__
);
8504 const UChar
* expected
= u
"\U00011137\U00011138,\U00011139\U0001113A\U0001113B";
8505 UnicodeString actual
;
8506 df
->format(12345, actual
, status
);
8507 assertSuccess("Should not fail when formatting in ccp", status
);
8508 assertEquals("Should produce expected output in ccp", expected
, actual
);
8511 df
->parse(expected
, result
, status
);
8512 assertSuccess("Should not fail when parsing in ccp", status
);
8513 assertEquals("Should parse to 12345 in ccp", 12345, result
);
8515 const UChar
* expectedScientific
= u
"\U00011137.\U00011139E\U00011138";
8516 UnicodeString actualScientific
;
8517 df
.adoptInstead(static_cast<DecimalFormat
*>(
8518 NumberFormat::createScientificInstance(Locale("ccp"), status
)));
8519 df
->format(130, actualScientific
, status
);
8520 assertSuccess("Should not fail when formatting scientific in ccp", status
);
8521 assertEquals("Should produce expected scientific output in ccp",
8522 expectedScientific
, actualScientific
);
8524 Formattable resultScientific
;
8525 df
->parse(expectedScientific
, resultScientific
, status
);
8526 assertSuccess("Should not fail when parsing scientific in ccp", status
);
8527 assertEquals("Should parse scientific to 130 in ccp", 130, resultScientific
);
8531 void NumberFormatTest::verifyFieldPositionIterator(
8532 NumberFormatTest_Attributes
*expected
, FieldPositionIterator
&iter
) {
8535 while (iter
.next(fp
)) {
8536 if (expected
[idx
].spos
== -1) {
8537 errln("Iterator should have ended. got %d", fp
.getField());
8540 assertEquals("id", expected
[idx
].id
, fp
.getField());
8541 assertEquals("start", expected
[idx
].spos
, fp
.getBeginIndex());
8542 assertEquals("end", expected
[idx
].epos
, fp
.getEndIndex());
8545 if (expected
[idx
].spos
!= -1) {
8546 errln("Premature end of iterator. expected %d", expected
[idx
].id
);
8550 void NumberFormatTest::Test11735_ExceptionIssue() {
8551 IcuTestErrorCode
status(*this, "Test11735_ExceptionIssue");
8552 Locale
enLocale("en");
8553 DecimalFormatSymbols
symbols(enLocale
, status
);
8554 if (status
.isSuccess()) {
8555 DecimalFormat
fmt("0", symbols
, status
);
8556 assertSuccess("Fail: Construct DecimalFormat formatter", status
, true, __FILE__
, __LINE__
);
8557 ParsePosition
ppos(0);
8558 fmt
.parseCurrency("53.45", ppos
); // NPE thrown here in ICU4J.
8559 assertEquals("Issue11735 ppos", 0, ppos
.getIndex());
8563 void NumberFormatTest::Test11035_FormatCurrencyAmount() {
8564 UErrorCode status
= U_ZERO_ERROR
;
8565 double amount
= 12345.67;
8566 const char16_t* expected
= u
"12,345$67 ";
8568 // Test two ways to set a currency via API
8570 Locale loc1
= Locale("pt_PT");
8571 LocalPointer
<NumberFormat
> fmt1(NumberFormat::createCurrencyInstance("loc1", status
),
8573 if (U_FAILURE(status
)) {
8574 dataerrln("%s %d NumberFormat instance fmt1 is null", __FILE__
, __LINE__
);
8577 fmt1
->setCurrency(u
"PTE", status
);
8578 assertSuccess("Setting currency on fmt1", status
);
8579 UnicodeString actualSetCurrency
;
8580 fmt1
->format(amount
, actualSetCurrency
);
8582 Locale loc2
= Locale("pt_PT@currency=PTE");
8583 LocalPointer
<NumberFormat
> fmt2(NumberFormat::createCurrencyInstance(loc2
, status
));
8584 assertSuccess("Creating fmt2", status
);
8585 UnicodeString actualLocaleString
;
8586 fmt2
->format(amount
, actualLocaleString
);
8588 // TODO: The following test will fail until DecimalFormat wraps NumberFormatter.
8589 if (!logKnownIssue("13574")) {
8590 assertEquals("Custom Currency Pattern, Set Currency", expected
, actualSetCurrency
);
8594 void NumberFormatTest::Test11318_DoubleConversion() {
8595 IcuTestErrorCode
status(*this, "Test11318_DoubleConversion");
8596 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance("en", status
), status
);
8597 if (U_FAILURE(status
)) {
8598 dataerrln("%s %d Error in NumberFormat instance creation", __FILE__
, __LINE__
);
8601 nf
->setMaximumFractionDigits(40);
8602 nf
->setMaximumIntegerDigits(40);
8603 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
.getAlias());
8605 UErrorCode status
= U_ZERO_ERROR
;
8606 df
->setAttribute(UNUM_FORMAT_WITH_FULL_PRECISION
, TRUE
, status
); // Apple
8608 UnicodeString appendTo
;
8609 nf
->format(999999999999999.9, appendTo
);
8610 assertEquals("Should render all digits", u
"999,999,999,999,999.9", appendTo
);
8613 void NumberFormatTest::TestParsePercentRegression() {
8614 IcuTestErrorCode
status(*this, "TestParsePercentRegression");
8615 LocalPointer
<DecimalFormat
> df1((DecimalFormat
*) NumberFormat::createInstance("en", status
), status
);
8616 LocalPointer
<DecimalFormat
> df2((DecimalFormat
*) NumberFormat::createPercentInstance("en", status
), status
);
8617 if (status
.isFailure()) {return; }
8618 df1
->setLenient(TRUE
);
8619 df2
->setLenient(TRUE
);
8624 df1
->parse("50%", result
, ppos
);
8625 assertEquals("df1 should accept a number but not the percent sign", 2, ppos
.getIndex());
8626 assertEquals("df1 should return the number as 50", 50.0, result
.getDouble(status
));
8631 df2
->parse("50%", result
, ppos
);
8632 assertEquals("df2 should accept the percent sign", 3, ppos
.getIndex());
8633 assertEquals("df2 should return the number as 0.5", 0.5, result
.getDouble(status
));
8638 df2
->parse("50", result
, ppos
);
8639 assertEquals("df2 should return the number as 0.5 even though the percent sign is missing",
8641 result
.getDouble(status
));
8645 void NumberFormatTest::TestMultiplierWithScale() {
8649 void NumberFormatTest::TestFastFormatInt32() {
8650 IcuTestErrorCode
status(*this, "TestFastFormatInt32");
8652 // The two simplest formatters, old API and new API.
8653 // Old API should use the fastpath for ints.
8654 LocalizedNumberFormatter lnf
= NumberFormatter::withLocale("en");
8655 LocalPointer
<NumberFormat
> df(NumberFormat::createInstance("en", status
), status
);
8656 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {return;}
8680 static_cast<double>(INT32_MAX
) - 1,
8681 static_cast<double>(INT32_MAX
),
8682 static_cast<double>(INT32_MAX
) + 1,
8683 static_cast<double>(INT32_MIN
) - 1,
8684 static_cast<double>(INT32_MIN
),
8685 static_cast<double>(INT32_MIN
) + 1};
8687 for (auto num
: nums
) {
8688 UnicodeString expected
= lnf
.formatDouble(num
, status
).toString();
8689 UnicodeString actual
;
8690 df
->format(num
, actual
);
8691 assertEquals(UnicodeString("d = ") + num
, expected
, actual
);
8695 void NumberFormatTest::Test11646_Equality() {
8696 UErrorCode status
= U_ZERO_ERROR
;
8697 DecimalFormatSymbols
symbols(Locale::getEnglish(), status
);
8698 UnicodeString
pattern(u
"\u00a4\u00a4\u00a4 0.00 %\u00a4\u00a4");
8699 DecimalFormat
fmt(pattern
, symbols
, status
);
8700 if (!assertSuccess("", status
)) return;
8702 // Test equality with affixes. set affix methods can't capture special
8703 // characters which is why equality should fail.
8705 DecimalFormat
fmtCopy(fmt
);
8706 assertTrue("", fmt
== fmtCopy
);
8707 UnicodeString positivePrefix
;
8708 fmtCopy
.setPositivePrefix(fmtCopy
.getPositivePrefix(positivePrefix
));
8709 assertFalse("", fmt
== fmtCopy
);
8712 DecimalFormat fmtCopy
= DecimalFormat(fmt
);
8713 assertTrue("", fmt
== fmtCopy
);
8714 UnicodeString positivePrefix
;
8715 fmtCopy
.setPositiveSuffix(fmtCopy
.getPositiveSuffix(positivePrefix
));
8716 assertFalse("", fmt
== fmtCopy
);
8719 DecimalFormat
fmtCopy(fmt
);
8720 assertTrue("", fmt
== fmtCopy
);
8721 UnicodeString negativePrefix
;
8722 fmtCopy
.setNegativePrefix(fmtCopy
.getNegativePrefix(negativePrefix
));
8723 assertFalse("", fmt
== fmtCopy
);
8726 DecimalFormat
fmtCopy(fmt
);
8727 assertTrue("", fmt
== fmtCopy
);
8728 UnicodeString negativePrefix
;
8729 fmtCopy
.setNegativeSuffix(fmtCopy
.getNegativeSuffix(negativePrefix
));
8730 assertFalse("", fmt
== fmtCopy
);
8734 void NumberFormatTest::TestParseNaN() {
8735 IcuTestErrorCode
status(*this, "TestParseNaN");
8737 DecimalFormat
df("0", { "en", status
}, status
);
8738 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8739 Formattable parseResult
;
8740 df
.parse(u
"NaN", parseResult
, status
);
8741 assertEquals("NaN should parse successfully", NAN
, parseResult
.getDouble());
8742 assertFalse("Result NaN should be positive", std::signbit(parseResult
.getDouble()));
8743 UnicodeString formatResult
;
8744 df
.format(parseResult
.getDouble(), formatResult
);
8745 assertEquals("NaN should round-trip", u
"NaN", formatResult
);
8748 void NumberFormatTest::Test11897_LocalizedPatternSeparator() {
8749 IcuTestErrorCode
status(*this, "Test11897_LocalizedPatternSeparator");
8751 // In a locale with a different <list> symbol, like arabic,
8752 // kPatternSeparatorSymbol should still be ';'
8754 DecimalFormatSymbols
dfs("ar", status
);
8755 assertEquals("pattern separator symbol should be ;",
8757 dfs
.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
));
8760 // However, the custom symbol should be used in localized notation
8761 // when set manually via API
8763 DecimalFormatSymbols
dfs("en", status
);
8764 dfs
.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
, u
"!", FALSE
);
8765 DecimalFormat
df(u
"0", dfs
, status
);
8766 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8767 df
.applyPattern("a0;b0", status
); // should not throw
8768 UnicodeString result
;
8769 assertEquals("should apply the normal pattern",
8770 df
.getNegativePrefix(result
.remove()),
8772 df
.applyLocalizedPattern(u
"c0!d0", status
); // should not throw
8773 assertEquals("should apply the localized pattern",
8774 df
.getNegativePrefix(result
.remove()),
8779 void NumberFormatTest::Test13055_PercentageRounding() {
8780 IcuTestErrorCode
status(*this, "PercentageRounding");
8781 UnicodeString actual
;
8782 LocalPointer
<NumberFormat
>pFormat(NumberFormat::createPercentInstance("en_US", status
));
8783 if (U_FAILURE(status
)) {
8784 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
8787 pFormat
->setMaximumFractionDigits(0);
8788 pFormat
->setRoundingMode(DecimalFormat::kRoundHalfEven
);
8789 pFormat
->format(2.155, actual
);
8790 assertEquals("Should round percent toward even number", "216%", actual
);
8793 void NumberFormatTest::Test11839() {
8794 IcuTestErrorCode
errorCode(*this, "Test11839");
8795 // Ticket #11839: DecimalFormat does not respect custom plus sign
8796 LocalPointer
<DecimalFormatSymbols
> dfs(new DecimalFormatSymbols(Locale::getEnglish(), errorCode
), errorCode
);
8797 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
8798 dfs
->setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
"a∸");
8799 dfs
->setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
"b∔"); // ∔ U+2214 DOT PLUS
8800 DecimalFormat
df(u
"0.00+;0.00-", dfs
.orphan(), errorCode
);
8801 UnicodeString result
;
8802 df
.format(-1.234, result
, errorCode
);
8803 assertEquals("Locale-specific minus sign should be used", u
"1.23a∸", result
);
8804 df
.format(1.234, result
.remove(), errorCode
);
8805 assertEquals("Locale-specific plus sign should be used", u
"1.23b∔", result
);
8806 // Test round-trip with parse
8807 expect2(df
, -456, u
"456.00a∸");
8808 expect2(df
, 456, u
"456.00b∔");
8811 void NumberFormatTest::Test10354() {
8812 IcuTestErrorCode
errorCode(*this, "Test10354");
8813 // Ticket #10354: invalid FieldPositionIterator when formatting with empty NaN
8814 DecimalFormatSymbols
dfs(errorCode
);
8815 UnicodeString empty
;
8816 dfs
.setSymbol(DecimalFormatSymbols::kNaNSymbol
, empty
);
8817 DecimalFormat
df(errorCode
);
8818 df
.setDecimalFormatSymbols(dfs
);
8819 UnicodeString result
;
8820 FieldPositionIterator positions
;
8821 df
.format(NAN
, result
, &positions
, errorCode
);
8822 errorCode
.errIfFailureAndReset("DecimalFormat.format(NAN, FieldPositionIterator) failed");
8824 while (positions
.next(fp
)) {
8825 // Should not loop forever
8829 void NumberFormatTest::Test11645_ApplyPatternEquality() {
8830 IcuTestErrorCode
status(*this, "Test11645_ApplyPatternEquality");
8831 const char16_t* pattern
= u
"#,##0.0#";
8832 LocalPointer
<DecimalFormat
> fmt((DecimalFormat
*) NumberFormat::createInstance(status
), status
);
8833 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8834 fmt
->applyPattern(pattern
, status
);
8835 LocalPointer
<DecimalFormat
> fmtCopy
;
8837 static const int32_t newMultiplier
= 37;
8838 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
8839 assertFalse("Value before setter", fmtCopy
->getMultiplier() == newMultiplier
);
8840 fmtCopy
->setMultiplier(newMultiplier
);
8841 assertEquals("Value after setter", fmtCopy
->getMultiplier(), newMultiplier
);
8842 fmtCopy
->applyPattern(pattern
, status
);
8843 //assertEquals("Value after applyPattern", fmtCopy->getMultiplier(), newMultiplier);
8844 //assertFalse("multiplier", *fmt == *fmtCopy);
8846 static const NumberFormat::ERoundingMode newRoundingMode
= NumberFormat::ERoundingMode::kRoundCeiling
;
8847 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
8848 assertFalse("Value before setter", fmtCopy
->getRoundingMode() == newRoundingMode
);
8849 fmtCopy
->setRoundingMode(newRoundingMode
);
8850 assertEquals("Value after setter", fmtCopy
->getRoundingMode(), newRoundingMode
);
8851 fmtCopy
->applyPattern(pattern
, status
);
8852 assertEquals("Value after applyPattern", fmtCopy
->getRoundingMode(), newRoundingMode
);
8853 assertFalse("roundingMode", *fmt
== *fmtCopy
);
8855 static const char16_t *const newCurrency
= u
"EAT";
8856 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
8857 assertFalse("Value before setter", fmtCopy
->getCurrency() == newCurrency
);
8858 fmtCopy
->setCurrency(newCurrency
);
8859 assertEquals("Value after setter", fmtCopy
->getCurrency(), newCurrency
);
8860 fmtCopy
->applyPattern(pattern
, status
);
8861 assertEquals("Value after applyPattern", fmtCopy
->getCurrency(), newCurrency
);
8862 assertFalse("currency", *fmt
== *fmtCopy
);
8864 static const UCurrencyUsage newCurrencyUsage
= UCurrencyUsage::UCURR_USAGE_CASH
;
8865 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
8866 assertFalse("Value before setter", fmtCopy
->getCurrencyUsage() == newCurrencyUsage
);
8867 fmtCopy
->setCurrencyUsage(newCurrencyUsage
, status
);
8868 assertEquals("Value after setter", fmtCopy
->getCurrencyUsage(), newCurrencyUsage
);
8869 fmtCopy
->applyPattern(pattern
, status
);
8870 assertEquals("Value after applyPattern", fmtCopy
->getCurrencyUsage(), newCurrencyUsage
);
8871 assertFalse("currencyUsage", *fmt
== *fmtCopy
);
8874 void NumberFormatTest::Test12567() {
8875 IcuTestErrorCode
errorCode(*this, "Test12567");
8876 // Ticket #12567: DecimalFormat.equals() may not be symmetric
8877 LocalPointer
<DecimalFormat
> df1((DecimalFormat
*)
8878 NumberFormat::createInstance(Locale::getUS(), UNUM_CURRENCY
, errorCode
));
8879 LocalPointer
<DecimalFormat
> df2((DecimalFormat
*)
8880 NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, errorCode
));
8881 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
8882 // NOTE: CurrencyPluralInfo equality not tested in C++ because its operator== is not defined.
8883 df1
->applyPattern(u
"0.00", errorCode
);
8884 df2
->applyPattern(u
"0.00", errorCode
);
8885 //assertTrue("df1 == df2", *df1 == *df2);
8886 //assertTrue("df2 == df1", *df2 == *df1);
8887 df2
->setPositivePrefix(u
"abc");
8888 assertTrue("df1 != df2", *df1
!= *df2
);
8889 assertTrue("df2 != df1", *df2
!= *df1
);
8892 void NumberFormatTest::Test11626_CustomizeCurrencyPluralInfo() {
8893 IcuTestErrorCode
errorCode(*this, "Test11626_CustomizeCurrencyPluralInfo");
8894 // Ticket #11626: No unit test demonstrating how to use CurrencyPluralInfo to
8895 // change formatting spelled out currencies
8896 // Use locale sr because it has interesting plural rules.
8897 Locale
locale("sr");
8898 LocalPointer
<DecimalFormatSymbols
> symbols(new DecimalFormatSymbols(locale
, errorCode
), errorCode
);
8899 CurrencyPluralInfo
info(locale
, errorCode
);
8900 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
8901 info
.setCurrencyPluralPattern(u
"one", u
"0 qwerty", errorCode
);
8902 info
.setCurrencyPluralPattern(u
"few", u
"0 dvorak", errorCode
);
8903 DecimalFormat
df(u
"#", symbols
.orphan(), UNUM_CURRENCY_PLURAL
, errorCode
);
8904 df
.setCurrencyPluralInfo(info
);
8905 df
.setCurrency(u
"USD");
8906 df
.setMaximumFractionDigits(0);
8908 UnicodeString result
;
8909 //assertEquals("Plural one", u"1 qwerty", df.format(1, result, errorCode));
8910 //assertEquals("Plural few", u"3 dvorak", df.format(3, result.remove(), errorCode));
8911 assertEquals("Plural other", u
"99 америчких долара", df
.format(99, result
.remove(), errorCode
));
8913 info
.setPluralRules(u
"few: n is 1; one: n in 2..4", errorCode
);
8914 df
.setCurrencyPluralInfo(info
);
8915 //assertEquals("Plural one", u"1 dvorak", df.format(1, result.remove(), errorCode));
8916 //assertEquals("Plural few", u"3 qwerty", df.format(3, result.remove(), errorCode));
8917 assertEquals("Plural other", u
"99 америчких долара", df
.format(99, result
.remove(), errorCode
));
8920 void NumberFormatTest::Test13056_GroupingSize() {
8921 UErrorCode status
= U_ZERO_ERROR
;
8922 DecimalFormat
df(u
"#,##0", status
);
8923 if (!assertSuccess("", status
)) return;
8924 assertEquals("Primary grouping should return 3", 3, df
.getGroupingSize());
8925 assertEquals("Secondary grouping should return 0", 0, df
.getSecondaryGroupingSize());
8926 df
.setSecondaryGroupingSize(3);
8927 assertEquals("Primary grouping should still return 3", 3, df
.getGroupingSize());
8928 assertEquals("Secondary grouping should round-trip", 3, df
.getSecondaryGroupingSize());
8929 df
.setGroupingSize(4);
8930 assertEquals("Primary grouping should return 4", 4, df
.getGroupingSize());
8931 assertEquals("Secondary should remember explicit setting and return 3", 3, df
.getSecondaryGroupingSize());
8935 void NumberFormatTest::Test11025_CurrencyPadding() {
8936 UErrorCode status
= U_ZERO_ERROR
;
8937 UnicodeString
pattern(u
"¤¤ **####0.00");
8938 DecimalFormatSymbols
sym(Locale::getFrance(), status
);
8939 if (!assertSuccess("", status
)) return;
8940 DecimalFormat
fmt(pattern
, sym
, status
);
8941 if (!assertSuccess("", status
)) return;
8942 UnicodeString result
;
8943 fmt
.format(433.0, result
);
8944 assertEquals("Number should be padded to 11 characters", "EUR *433,00", result
);
8947 void NumberFormatTest::Test11648_ExpDecFormatMalPattern() {
8948 UErrorCode status
= U_ZERO_ERROR
;
8950 DecimalFormat
fmt("0.00", {"en", status
}, status
);
8951 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8952 fmt
.setScientificNotation(TRUE
);
8953 UnicodeString pattern
;
8955 assertEquals("A valid scientific notation pattern should be produced",
8957 fmt
.toPattern(pattern
));
8959 DecimalFormat
fmt2(pattern
, status
);
8960 assertSuccess("", status
);
8963 void NumberFormatTest::Test11649_DecFmtCurrencies() {
8964 IcuTestErrorCode
status(*this, "Test11649_DecFmtCurrencies");
8965 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00");
8966 pattern
= pattern
.unescape();
8967 DecimalFormat
fmt(pattern
, status
);
8968 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8969 static const UChar USD
[] = u
"USD";
8970 fmt
.setCurrency(USD
);
8971 UnicodeString appendTo
;
8973 assertEquals("", "US dollars 12.34", fmt
.format(12.34, appendTo
));
8974 UnicodeString topattern
;
8976 // assertEquals("", pattern, fmt.toPattern(topattern));
8977 DecimalFormat
fmt2(topattern
, status
);
8978 fmt2
.setCurrency(USD
);
8981 assertEquals("", "US dollars 12.34", fmt2
.format(12.34, appendTo
));
8984 void NumberFormatTest::Test13148_ParseGroupingSeparators() {
8985 IcuTestErrorCode
status(*this, "Test13148");
8986 LocalPointer
<DecimalFormat
> fmt(
8987 (DecimalFormat
*)NumberFormat::createInstance("en-ZA", status
), status
);
8988 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8990 DecimalFormatSymbols symbols
= *fmt
->getDecimalFormatSymbols();
8992 symbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
'.');
8993 symbols
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
',');
8994 fmt
->setDecimalFormatSymbols(symbols
);
8996 fmt
->parse(u
"300,000", number
, status
);
8997 assertEquals("Should parse as 300000", 300000LL, number
.getInt64(status
));
9000 void NumberFormatTest::Test12753_PatternDecimalPoint() {
9001 UErrorCode status
= U_ZERO_ERROR
;
9002 DecimalFormatSymbols
symbols(Locale::getUS(), status
);
9003 symbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
"*", false);
9004 DecimalFormat
df(u
"0.00", symbols
, status
);
9005 if (!assertSuccess("", status
)) return;
9006 df
.setDecimalPatternMatchRequired(true);
9008 df
.parse(u
"123",result
, status
);
9009 assertEquals("Parsing integer succeeded even though setDecimalPatternMatchRequired was set",
9010 U_INVALID_FORMAT_ERROR
, status
);
9013 void NumberFormatTest::Test11647_PatternCurrencySymbols() {
9014 UErrorCode status
= U_ZERO_ERROR
;
9015 DecimalFormat
df(status
);
9016 df
.applyPattern(u
"¤¤¤¤#", status
);
9017 if (!assertSuccess("", status
)) return;
9018 UnicodeString actual
;
9019 df
.format(123, actual
);
9020 //assertEquals("Should replace 4 currency signs with U+FFFD", u"\uFFFD123", actual);
9023 void NumberFormatTest::Test11913_BigDecimal() {
9024 UErrorCode status
= U_ZERO_ERROR
;
9025 LocalPointer
<NumberFormat
> df(NumberFormat::createInstance(Locale::getEnglish(), status
), status
);
9026 if (!assertSuccess("", status
)) return;
9027 UnicodeString result
;
9028 df
->format(StringPiece("1.23456789E400"), result
, nullptr, status
);
9029 assertSuccess("", status
);
9030 assertEquals("Should format more than 309 digits", u
"12,345,678", UnicodeString(result
, 0, 10));
9031 assertEquals("Should format more than 309 digits", 534, result
.length());
9034 void NumberFormatTest::Test11020_RoundingInScientificNotation() {
9035 UErrorCode status
= U_ZERO_ERROR
;
9036 DecimalFormatSymbols
sym(Locale::getFrance(), status
);
9037 DecimalFormat
fmt(u
"0.05E0", sym
, status
);
9038 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9039 assertSuccess("", status
);
9040 UnicodeString result
;
9041 fmt
.format(12301.2, result
);
9042 assertEquals("Rounding increment should be applied after magnitude scaling", u
"1,25E4", result
);
9045 void NumberFormatTest::Test11640_TripleCurrencySymbol() {
9046 IcuTestErrorCode
status(*this, "Test11640_TripleCurrencySymbol");
9047 UnicodeString actual
;
9048 DecimalFormat
dFormat(u
"¤¤¤ 0", status
);
9049 if (U_FAILURE(status
)) {
9050 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
9053 dFormat
.setCurrency(u
"USD");
9054 UnicodeString result
;
9055 dFormat
.getPositivePrefix(result
);
9056 assertEquals("Triple-currency should give long name on getPositivePrefix",
9057 "US dollars ", result
);
9061 void NumberFormatTest::Test13763_FieldPositionIteratorOffset() {
9062 IcuTestErrorCode
status(*this, "Test13763_FieldPositionIteratorOffset");
9063 FieldPositionIterator fpi
;
9064 UnicodeString
result(u
"foo\U0001F4FBbar"); // 8 code units
9065 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance("en", status
), status
);
9066 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9067 nf
->format(5142.3, result
, &fpi
, status
);
9069 int32_t expected
[] = {
9070 UNUM_GROUPING_SEPARATOR_FIELD
, 9, 10,
9071 UNUM_INTEGER_FIELD
, 8, 13,
9072 UNUM_DECIMAL_SEPARATOR_FIELD
, 13, 14,
9073 UNUM_FRACTION_FIELD
, 14, 15,
9075 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
9076 expectPositions(fpi
, expected
, tupleCount
, result
);
9079 void NumberFormatTest::Test13777_ParseLongNameNonCurrencyMode() {
9080 IcuTestErrorCode
status(*this, "Test13777_ParseLongNameNonCurrencyMode");
9082 LocalPointer
<NumberFormat
> df(
9083 NumberFormat::createInstance("en-us", UNumberFormatStyle::UNUM_CURRENCY_PLURAL
, status
), status
);
9084 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9085 expect2(*df
, 1.5, u
"1.50 US dollars");
9088 void NumberFormatTest::Test13804_EmptyStringsWhenParsing() {
9089 IcuTestErrorCode
status(*this, "Test13804_EmptyStringsWhenParsing");
9091 DecimalFormatSymbols
dfs("en", status
);
9092 if (status
.errIfFailureAndReset()) {
9095 dfs
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, u
"", FALSE
);
9096 dfs
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
"", FALSE
);
9097 dfs
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, u
"", FALSE
);
9098 dfs
.setSymbol(DecimalFormatSymbols::kOneDigitSymbol
, u
"", FALSE
);
9099 dfs
.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol
, u
"", FALSE
);
9100 dfs
.setSymbol(DecimalFormatSymbols::kThreeDigitSymbol
, u
"", FALSE
);
9101 dfs
.setSymbol(DecimalFormatSymbols::kFourDigitSymbol
, u
"", FALSE
);
9102 dfs
.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol
, u
"", FALSE
);
9103 dfs
.setSymbol(DecimalFormatSymbols::kSixDigitSymbol
, u
"", FALSE
);
9104 dfs
.setSymbol(DecimalFormatSymbols::kSevenDigitSymbol
, u
"", FALSE
);
9105 dfs
.setSymbol(DecimalFormatSymbols::kEightDigitSymbol
, u
"", FALSE
);
9106 dfs
.setSymbol(DecimalFormatSymbols::kNineDigitSymbol
, u
"", FALSE
);
9107 dfs
.setSymbol(DecimalFormatSymbols::kExponentMultiplicationSymbol
, u
"", FALSE
);
9108 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"", FALSE
);
9109 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
"", FALSE
);
9110 dfs
.setSymbol(DecimalFormatSymbols::kInfinitySymbol
, u
"", FALSE
);
9111 dfs
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, u
"", FALSE
);
9112 dfs
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
"", FALSE
);
9113 dfs
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, u
"", FALSE
);
9114 dfs
.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
, u
"", FALSE
);
9115 dfs
.setSymbol(DecimalFormatSymbols::kNaNSymbol
, u
"", FALSE
);
9116 dfs
.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT
, FALSE
, u
"");
9117 dfs
.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT
, TRUE
, u
"");
9118 dfs
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, u
"", FALSE
);
9119 dfs
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, u
"", FALSE
);
9120 dfs
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
"", FALSE
);
9122 DecimalFormat
df("0", dfs
, status
);
9123 if (status
.errIfFailureAndReset()) {
9126 df
.setGroupingUsed(TRUE
);
9127 df
.setScientificNotation(TRUE
);
9128 df
.setLenient(TRUE
); // enable all matchers
9130 UnicodeString result
;
9131 df
.format(0, result
); // should not crash or hit infinite loop
9133 const char16_t* samples
[] = {
9142 for (auto& sample
: samples
) {
9143 logln(UnicodeString(u
"Attempting parse on: ") + sample
);
9144 status
.setScope(sample
);
9145 // We don't care about the results, only that we don't crash and don't loop.
9147 ParsePosition
ppos(0);
9148 df
.parse(sample
, result
, ppos
);
9149 ppos
= ParsePosition(0);
9150 LocalPointer
<CurrencyAmount
> curramt(df
.parseCurrency(sample
, ppos
));
9151 status
.errIfFailureAndReset();
9154 // Test with a nonempty exponent separator symbol to cover more code
9155 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"E", FALSE
);
9156 df
.setDecimalFormatSymbols(dfs
);
9159 ParsePosition
ppos(0);
9160 df
.parse(u
"1E+2.3", result
, ppos
);
9164 #endif /* #if !UCONFIG_NO_FORMATTING */