1 // Copyright (C) 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/dcfmtsym.h"
19 #include "unicode/decimfmt.h"
20 #include "unicode/localpointer.h"
21 #include "unicode/ucurr.h"
22 #include "unicode/ustring.h"
23 #include "unicode/measfmt.h"
24 #include "unicode/curramt.h"
36 #include "unicode/numsys.h"
37 #include "fmtableimp.h"
38 #include "numberformattesttuple.h"
39 #include "datadrivennumberformattestsuite.h"
40 #include "unicode/msgfmt.h"
42 class NumberFormatTestDataDriven : public DataDrivenNumberFormatTestSuite {
45 const NumberFormatTestTuple &tuple,
46 UnicodeString &appendErrorMessage,
48 UBool isToPatternPass(
49 const NumberFormatTestTuple &tuple,
50 UnicodeString &appendErrorMessage,
53 const NumberFormatTestTuple &tuple,
54 UnicodeString &appendErrorMessage,
56 UBool isParseCurrencyPass(
57 const NumberFormatTestTuple &tuple,
58 UnicodeString &appendErrorMessage,
62 static DigitList &strToDigitList(
63 const UnicodeString &str,
66 if (U_FAILURE(status)) {
70 digitList.set(uprv_getNaN());
74 digitList.set(-1*uprv_getInfinity());
78 digitList.set(uprv_getInfinity());
81 CharString formatValue;
82 formatValue.appendInvariantChars(str, status);
83 digitList.set(StringPiece(formatValue.data()), status, 0);
87 static UnicodeString &format(
88 const DecimalFormat &fmt,
89 const DigitList &digitList,
90 UnicodeString &appendTo,
92 if (U_FAILURE(status)) {
95 FieldPosition fpos(FieldPosition::DONT_CARE);
96 return fmt.format(digitList, appendTo, fpos, status);
100 static UnicodeString &format(
101 const DecimalFormat &fmt,
103 UnicodeString &appendTo,
104 UErrorCode &status) {
105 if (U_FAILURE(status)) {
108 FieldPosition fpos(FieldPosition::DONT_CARE);
109 return fmt.format(value, appendTo, fpos, status);
112 static void adjustDecimalFormat(
113 const NumberFormatTestTuple &tuple,
115 UnicodeString &appendErrorMessage) {
116 if (tuple.minIntegerDigitsFlag) {
117 fmt.setMinimumIntegerDigits(tuple.minIntegerDigits);
119 if (tuple.maxIntegerDigitsFlag) {
120 fmt.setMaximumIntegerDigits(tuple.maxIntegerDigits);
122 if (tuple.minFractionDigitsFlag) {
123 fmt.setMinimumFractionDigits(tuple.minFractionDigits);
125 if (tuple.maxFractionDigitsFlag) {
126 fmt.setMaximumFractionDigits(tuple.maxFractionDigits);
128 if (tuple.currencyFlag) {
129 UErrorCode status = U_ZERO_ERROR;
130 UnicodeString currency(tuple.currency);
131 const UChar *terminatedCurrency = currency.getTerminatedBuffer();
132 fmt.setCurrency(terminatedCurrency, status);
133 if (U_FAILURE(status)) {
134 appendErrorMessage.append("Error setting currency.");
137 if (tuple.minGroupingDigitsFlag) {
138 fmt.setMinimumGroupingDigits(tuple.minGroupingDigits);
140 if (tuple.useSigDigitsFlag) {
141 fmt.setSignificantDigitsUsed(tuple.useSigDigits != 0);
143 if (tuple.minSigDigitsFlag) {
144 fmt.setMinimumSignificantDigits(tuple.minSigDigits);
146 if (tuple.maxSigDigitsFlag) {
147 fmt.setMaximumSignificantDigits(tuple.maxSigDigits);
149 if (tuple.useGroupingFlag) {
150 fmt.setGroupingUsed(tuple.useGrouping != 0);
152 if (tuple.multiplierFlag) {
153 fmt.setMultiplier(tuple.multiplier);
155 if (tuple.roundingIncrementFlag) {
156 fmt.setRoundingIncrement(tuple.roundingIncrement);
158 if (tuple.formatWidthFlag) {
159 fmt.setFormatWidth(tuple.formatWidth);
161 if (tuple.padCharacterFlag) {
162 fmt.setPadCharacter(tuple.padCharacter);
164 if (tuple.useScientificFlag) {
165 fmt.setScientificNotation(tuple.useScientific != 0);
167 if (tuple.groupingFlag) {
168 fmt.setGroupingSize(tuple.grouping);
170 if (tuple.grouping2Flag) {
171 fmt.setSecondaryGroupingSize(tuple.grouping2);
173 if (tuple.roundingModeFlag) {
174 fmt.setRoundingMode(tuple.roundingMode);
176 if (tuple.currencyUsageFlag) {
177 UErrorCode status = U_ZERO_ERROR;
178 fmt.setCurrencyUsage(tuple.currencyUsage, &status);
179 if (U_FAILURE(status)) {
180 appendErrorMessage.append("CurrencyUsage: error setting.");
183 if (tuple.minimumExponentDigitsFlag) {
184 fmt.setMinimumExponentDigits(tuple.minimumExponentDigits);
186 if (tuple.exponentSignAlwaysShownFlag) {
187 fmt.setExponentSignAlwaysShown(tuple.exponentSignAlwaysShown != 0);
189 if (tuple.decimalSeparatorAlwaysShownFlag) {
190 fmt.setDecimalSeparatorAlwaysShown(
191 tuple.decimalSeparatorAlwaysShown != 0);
193 if (tuple.padPositionFlag) {
194 fmt.setPadPosition(tuple.padPosition);
196 if (tuple.positivePrefixFlag) {
197 fmt.setPositivePrefix(tuple.positivePrefix);
199 if (tuple.positiveSuffixFlag) {
200 fmt.setPositiveSuffix(tuple.positiveSuffix);
202 if (tuple.negativePrefixFlag) {
203 fmt.setNegativePrefix(tuple.negativePrefix);
205 if (tuple.negativeSuffixFlag) {
206 fmt.setNegativeSuffix(tuple.negativeSuffix);
208 if (tuple.localizedPatternFlag) {
209 UErrorCode status = U_ZERO_ERROR;
210 fmt.applyLocalizedPattern(tuple.localizedPattern, status);
211 if (U_FAILURE(status)) {
212 appendErrorMessage.append("Error setting localized pattern.");
215 fmt.setLenient(NFTT_GET_FIELD(tuple, lenient, 1) != 0);
216 if (tuple.parseIntegerOnlyFlag) {
217 fmt.setParseIntegerOnly(tuple.parseIntegerOnly != 0);
219 if (tuple.decimalPatternMatchRequiredFlag) {
220 fmt.setDecimalPatternMatchRequired(
221 tuple.decimalPatternMatchRequired != 0);
223 if (tuple.parseNoExponentFlag) {
224 UErrorCode status = U_ZERO_ERROR;
226 UNUM_PARSE_NO_EXPONENT,
227 tuple.parseNoExponent,
229 if (U_FAILURE(status)) {
230 appendErrorMessage.append("Error setting parse no exponent flag.");
235 static DecimalFormat *newDecimalFormat(
236 const Locale &locale,
237 const UnicodeString &pattern,
238 UErrorCode &status) {
239 if (U_FAILURE(status)) {
242 LocalPointer<DecimalFormatSymbols> symbols(
243 new DecimalFormatSymbols(locale, status), status);
244 if (U_FAILURE(status)) {
248 LocalPointer<DecimalFormat> result(new DecimalFormat(
249 pattern, symbols.getAlias(), perror, status), status);
250 if (!result.isNull()) {
253 if (U_FAILURE(status)) {
256 return result.orphan();
259 static DecimalFormat *newDecimalFormat(
260 const NumberFormatTestTuple &tuple,
261 UErrorCode &status) {
262 if (U_FAILURE(status)) {
266 return newDecimalFormat(
267 NFTT_GET_FIELD(tuple, locale, en),
268 NFTT_GET_FIELD(tuple, pattern, "0"),
272 UBool NumberFormatTestDataDriven::isFormatPass(
273 const NumberFormatTestTuple &tuple,
274 UnicodeString &appendErrorMessage,
275 UErrorCode &status) {
276 if (U_FAILURE(status)) {
279 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
280 if (U_FAILURE(status)) {
281 appendErrorMessage.append("Error creating DecimalFormat.");
284 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
285 if (appendErrorMessage.length() > 0) {
289 strToDigitList(tuple.format, digitList, status);
291 UnicodeString appendTo;
292 format(*fmtPtr, digitList, appendTo, status);
293 if (U_FAILURE(status)) {
294 appendErrorMessage.append("Error formatting.");
297 if (appendTo != tuple.output) {
298 appendErrorMessage.append(
299 UnicodeString("Expected: ") + tuple.output + ", got: " + appendTo);
303 double doubleVal = digitList.getDouble();
305 UnicodeString appendTo;
306 format(*fmtPtr, doubleVal, appendTo, status);
307 if (U_FAILURE(status)) {
308 appendErrorMessage.append("Error formatting.");
311 if (appendTo != tuple.output) {
312 appendErrorMessage.append(
313 UnicodeString("double Expected: ") + tuple.output + ", got: " + appendTo);
317 if (!uprv_isNaN(doubleVal) && !uprv_isInfinite(doubleVal) && doubleVal == uprv_floor(doubleVal)) {
318 int64_t intVal = digitList.getInt64();
320 UnicodeString appendTo;
321 format(*fmtPtr, intVal, appendTo, status);
322 if (U_FAILURE(status)) {
323 appendErrorMessage.append("Error formatting.");
326 if (appendTo != tuple.output) {
327 appendErrorMessage.append(
328 UnicodeString("int64 Expected: ") + tuple.output + ", got: " + appendTo);
336 UBool NumberFormatTestDataDriven::isToPatternPass(
337 const NumberFormatTestTuple &tuple,
338 UnicodeString &appendErrorMessage,
339 UErrorCode &status) {
340 if (U_FAILURE(status)) {
343 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
344 if (U_FAILURE(status)) {
345 appendErrorMessage.append("Error creating DecimalFormat.");
348 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
349 if (appendErrorMessage.length() > 0) {
352 if (tuple.toPatternFlag) {
353 UnicodeString actual;
354 fmtPtr->toPattern(actual);
355 if (actual != tuple.toPattern) {
356 appendErrorMessage.append(
357 UnicodeString("Expected: ") + tuple.toPattern + ", got: " + actual + ". ");
360 if (tuple.toLocalizedPatternFlag) {
361 UnicodeString actual;
362 fmtPtr->toLocalizedPattern(actual);
363 if (actual != tuple.toLocalizedPattern) {
364 appendErrorMessage.append(
365 UnicodeString("Expected: ") + tuple.toLocalizedPattern + ", got: " + actual + ". ");
368 return appendErrorMessage.length() == 0;
371 UBool NumberFormatTestDataDriven::isParsePass(
372 const NumberFormatTestTuple &tuple,
373 UnicodeString &appendErrorMessage,
374 UErrorCode &status) {
375 if (U_FAILURE(status)) {
378 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
379 if (U_FAILURE(status)) {
380 appendErrorMessage.append("Error creating DecimalFormat.");
383 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
384 if (appendErrorMessage.length() > 0) {
389 fmtPtr->parse(tuple.parse, result, ppos);
390 if (ppos.getIndex() == 0) {
391 if (tuple.output != "fail") {
392 appendErrorMessage.append("Parse failed but was expected to succeed.");
397 UnicodeString resultStr(UnicodeString::fromUTF8(result.getDecimalNumber(status)));
398 if (tuple.output == "fail") {
399 appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
403 strToDigitList(tuple.output, expected, status);
404 if (U_FAILURE(status)) {
405 appendErrorMessage.append("Error parsing.");
408 if (expected != *result.getDigitList()) {
409 appendErrorMessage.append(
410 UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". ");
416 UBool NumberFormatTestDataDriven::isParseCurrencyPass(
417 const NumberFormatTestTuple &tuple,
418 UnicodeString &appendErrorMessage,
419 UErrorCode &status) {
420 if (U_FAILURE(status)) {
423 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
424 if (U_FAILURE(status)) {
425 appendErrorMessage.append("Error creating DecimalFormat.");
428 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
429 if (appendErrorMessage.length() > 0) {
433 LocalPointer<CurrencyAmount> currAmt(
434 fmtPtr->parseCurrency(tuple.parse, ppos));
435 if (ppos.getIndex() == 0) {
436 if (tuple.output != "fail") {
437 appendErrorMessage.append("Parse failed but was expected to succeed.");
442 UnicodeString currStr(currAmt->getISOCurrency());
443 Formattable resultFormattable(currAmt->getNumber());
444 UnicodeString resultStr(UnicodeString::fromUTF8(resultFormattable.getDecimalNumber(status)));
445 if (tuple.output == "fail") {
446 appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
450 strToDigitList(tuple.output, expected, status);
451 if (U_FAILURE(status)) {
452 appendErrorMessage.append("Error parsing.");
455 if (expected != *currAmt->getNumber().getDigitList()) {
456 appendErrorMessage.append(
457 UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". ");
460 if (currStr != tuple.outputCurrency) {
461 appendErrorMessage.append(UnicodeString(
462 "Expected currency: ") + tuple.outputCurrency + ", got: " + currStr + ". ");
468 //#define NUMFMTST_CACHE_DEBUG 1
469 #include "stdio.h" /* for sprintf */
470 // #include "iostream" // for cout
472 //#define NUMFMTST_DEBUG 1
474 static const UChar EUR[] = {69,85,82,0}; // "EUR"
475 static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD"
478 // *****************************************************************************
479 // class NumberFormatTest
480 // *****************************************************************************
482 #define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
483 #define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
485 void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
488 TESTCASE_AUTO(TestCurrencySign);
489 TESTCASE_AUTO(TestCurrency);
490 TESTCASE_AUTO(TestParse);
491 TESTCASE_AUTO(TestRounding487);
492 TESTCASE_AUTO(TestQuotes);
493 TESTCASE_AUTO(TestExponential);
494 TESTCASE_AUTO(TestPatterns);
496 // Upgrade to alphaWorks - liu 5/99
497 TESTCASE_AUTO(TestExponent);
498 TESTCASE_AUTO(TestScientific);
499 TESTCASE_AUTO(TestPad);
500 TESTCASE_AUTO(TestPatterns2);
501 TESTCASE_AUTO(TestSecondaryGrouping);
502 TESTCASE_AUTO(TestSurrogateSupport);
503 TESTCASE_AUTO(TestAPI);
505 TESTCASE_AUTO(TestCurrencyObject);
506 TESTCASE_AUTO(TestCurrencyPatterns);
507 //TESTCASE_AUTO(TestDigitList);
508 TESTCASE_AUTO(TestWhiteSpaceParsing);
509 TESTCASE_AUTO(TestComplexCurrency); // This test removed because CLDR no longer uses choice formats in currency symbols.
510 TESTCASE_AUTO(TestRegCurrency);
511 TESTCASE_AUTO(TestSymbolsWithBadLocale);
512 TESTCASE_AUTO(TestAdoptDecimalFormatSymbols);
514 TESTCASE_AUTO(TestScientific2);
515 TESTCASE_AUTO(TestScientificGrouping);
516 TESTCASE_AUTO(TestInt64);
518 TESTCASE_AUTO(TestPerMill);
519 TESTCASE_AUTO(TestIllegalPatterns);
520 TESTCASE_AUTO(TestCases);
522 TESTCASE_AUTO(TestCurrencyNames);
523 TESTCASE_AUTO(TestCurrencyAmount);
524 TESTCASE_AUTO(TestCurrencyUnit);
525 TESTCASE_AUTO(TestCoverage);
526 TESTCASE_AUTO(TestJB3832);
527 TESTCASE_AUTO(TestHost);
528 TESTCASE_AUTO(TestHostClone);
529 TESTCASE_AUTO(TestCurrencyFormat);
530 TESTCASE_AUTO(TestRounding);
531 TESTCASE_AUTO(TestNonpositiveMultiplier);
532 TESTCASE_AUTO(TestNumberingSystems);
533 TESTCASE_AUTO(TestSpaceParsing);
534 TESTCASE_AUTO(TestMultiCurrencySign);
535 TESTCASE_AUTO(TestCurrencyFormatForMixParsing);
536 TESTCASE_AUTO(TestDecimalFormatCurrencyParse);
537 TESTCASE_AUTO(TestCurrencyIsoPluralFormat);
538 TESTCASE_AUTO(TestCurrencyParsing);
539 TESTCASE_AUTO(TestParseCurrencyInUCurr);
540 TESTCASE_AUTO(TestFormatAttributes);
541 TESTCASE_AUTO(TestFieldPositionIterator);
542 TESTCASE_AUTO(TestDecimal);
543 TESTCASE_AUTO(TestCurrencyFractionDigits);
544 TESTCASE_AUTO(TestExponentParse);
545 TESTCASE_AUTO(TestExplicitParents);
546 TESTCASE_AUTO(TestLenientParse);
547 TESTCASE_AUTO(TestAvailableNumberingSystems);
548 TESTCASE_AUTO(TestRoundingPattern);
549 TESTCASE_AUTO(Test9087);
550 TESTCASE_AUTO(TestFormatFastpaths);
551 TESTCASE_AUTO(TestFormattableSize);
552 TESTCASE_AUTO(TestUFormattable);
553 TESTCASE_AUTO(TestSignificantDigits);
554 TESTCASE_AUTO(TestShowZero);
555 TESTCASE_AUTO(TestCompatibleCurrencies);
556 TESTCASE_AUTO(TestBug9936);
557 TESTCASE_AUTO(TestParseNegativeWithFaLocale);
558 TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign);
559 TESTCASE_AUTO(TestCustomCurrencySignAndSeparator);
560 TESTCASE_AUTO(TestParseSignsAndMarks);
561 TESTCASE_AUTO(Test10419RoundingWith0FractionDigits);
562 TESTCASE_AUTO(Test10468ApplyPattern);
563 TESTCASE_AUTO(TestRoundingScientific10542);
564 TESTCASE_AUTO(TestZeroScientific10547);
565 TESTCASE_AUTO(TestAccountingCurrency);
566 TESTCASE_AUTO(TestEquality);
567 TESTCASE_AUTO(TestCurrencyUsage);
568 TESTCASE_AUTO(TestNumberFormatTestTuple);
569 TESTCASE_AUTO(TestDataDriven);
570 TESTCASE_AUTO(TestDoubleLimit11439);
571 TESTCASE_AUTO(TestFastPathConsistent11524);
572 TESTCASE_AUTO(TestGetAffixes);
573 TESTCASE_AUTO(TestToPatternScientific11648);
574 TESTCASE_AUTO(TestBenchmark);
575 TESTCASE_AUTO(TestCtorApplyPatternDifference);
576 TESTCASE_AUTO(TestFractionalDigitsForCurrency);
577 TESTCASE_AUTO(TestFormatCurrencyPlural);
578 TESTCASE_AUTO(Test11868);
579 TESTCASE_AUTO(Test10727_RoundingZero);
580 TESTCASE_AUTO(Test11376_getAndSetPositivePrefix);
581 TESTCASE_AUTO(Test11475_signRecognition);
582 TESTCASE_AUTO(Test11640_getAffixes);
583 TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency);
587 // -------------------------------------
589 // Test API (increase code coverage)
591 NumberFormatTest::TestAPI(void)
594 UErrorCode status = U_ZERO_ERROR;
595 NumberFormat *test = NumberFormat::createInstance("root", status);
596 if(U_FAILURE(status)) {
597 dataerrln("unable to create format object - %s", u_errorName(status));
600 test->setMinimumIntegerDigits(10);
601 test->setMaximumIntegerDigits(2);
603 test->setMinimumFractionDigits(10);
604 test->setMaximumFractionDigits(2);
606 UnicodeString result;
608 Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers
609 test->format(bla, result, pos, status);
610 if(U_SUCCESS(status)) {
611 errln("Yuck... Formatted a duck... As a number!");
613 status = U_ZERO_ERROR;
618 test->format(ll, result);
619 if (result != "12.00"){
620 errln("format int64_t error");
624 LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos));
625 // old test for (U_FAILURE(status)) was bogus here, method does not set status!
626 if (ppos.getIndex()) {
627 errln("Parsed empty string as currency");
634 class StubNumberFormat :public NumberFormat{
636 StubNumberFormat(){};
637 virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
640 virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
641 return appendTo.append((UChar)0x0033);
643 virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
644 return NumberFormat::format(number, appendTo, pos);
646 virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
649 virtual void parse(const UnicodeString& ,
651 ParsePosition& ) const {}
652 virtual void parse( const UnicodeString& ,
654 UErrorCode& ) const {}
655 virtual UClassID getDynamicClassID(void) const {
656 static char classID = 0;
657 return (UClassID)&classID;
659 virtual Format* clone() const {return NULL;}
663 NumberFormatTest::TestCoverage(void){
664 StubNumberFormat stub;
665 UnicodeString agent("agent");
668 if (stub.format(num, agent, pos) != UnicodeString("agent3")){
669 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
673 // Test various patterns
675 NumberFormatTest::TestPatterns(void)
677 UErrorCode status = U_ZERO_ERROR;
678 DecimalFormatSymbols sym(Locale::getUS(), status);
679 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; }
681 const char* pat[] = { "#.#", "#.", ".#", "#" };
682 int32_t pat_length = UPRV_LENGTHOF(pat);
683 const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
684 const char* num[] = { "0", "0.", ".0", "0" };
685 for (int32_t i=0; i<pat_length; ++i)
687 status = U_ZERO_ERROR;
688 DecimalFormat fmt(pat[i], sym, status);
689 if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; }
690 UnicodeString newp; fmt.toPattern(newp);
691 if (!(newp == newpat[i]))
692 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
693 "; " + newp + " seen instead");
695 UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
698 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
699 "; " + s + " seen instead");
700 logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits());
706 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
707 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
708 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
712 NumberFormatTest::TestDigitList(void)
714 // API coverage for DigitList
717 list1.fDecimalAt = 1;
719 list2.set((int32_t)1);
720 if (list1 != list2) {
721 errln("digitlist append, operator!= or set failed ");
723 if (!(list1 == list2)) {
724 errln("digitlist append, operator== or set failed ");
729 // -------------------------------------
731 // Test exponential pattern
733 NumberFormatTest::TestExponential(void)
735 UErrorCode status = U_ZERO_ERROR;
736 DecimalFormatSymbols sym(Locale::getUS(), status);
737 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
738 const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
739 int32_t pat_length = UPRV_LENGTHOF(pat);
741 // The following #if statements allow this test to be built and run on
742 // platforms that do not have standard IEEE numerics. For example,
743 // S/390 doubles have an exponent range of -78 to +75. For the
744 // following #if statements to work, float.h must define
745 // DBL_MAX_10_EXP to be a compile-time constant.
747 // This section may be expanded as needed.
749 #if DBL_MAX_10_EXP > 300
750 double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
751 int32_t val_length = UPRV_LENGTHOF(val);
752 const char* valFormat[] =
755 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
757 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
759 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
761 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
765 0.01234, 123460000, 1.23E300, -3.1416E-271,
766 0.01234, 123460000, 1.23E300, -3.1416E-271,
767 0.01234, 123456800, 1.23E300, -3.141593E-271,
768 0.01234, 123500000, 1.23E300, -3.142E-271,
770 #elif DBL_MAX_10_EXP > 70
771 double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
772 int32_t val_length = UPRV_LENGTHOF(val);
776 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
778 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
780 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
782 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
786 0.01234, 123460000, 1.23E70, -3.1416E-71,
787 0.01234, 123460000, 1.23E70, -3.1416E-71,
788 0.01234, 123456800, 1.23E70, -3.141593E-71,
789 0.01234, 123500000, 1.23E70, -3.142E-71,
792 // Don't test double conversion
794 int32_t val_length = 0;
795 char** valFormat = 0;
796 double* valParse = 0;
797 logln("Warning: Skipping double conversion tests");
800 int32_t lval[] = { 0, -1, 1, 123456789 };
801 int32_t lval_length = UPRV_LENGTHOF(lval);
802 const char* lvalFormat[] =
805 "0E0", "-1E0", "1E0", "1.2346E8",
807 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
809 "0E000", "-1E000", "1E000", "123.4568E006",
811 "0E0", "[1E0]", "1E0", "1.235E8"
813 int32_t lvalParse[] =
820 int32_t ival = 0, ilval = 0;
821 for (int32_t p=0; p<pat_length; ++p)
823 DecimalFormat fmt(pat[p], sym, status);
824 if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
825 UnicodeString pattern;
826 logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" +
827 fmt.toPattern(pattern) + "\"");
829 for (v=0; v<val_length; ++v)
831 UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s);
832 logln((UnicodeString)" " + val[v] + " -format-> " + s);
833 if (s != valFormat[v+ival])
834 errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]);
836 ParsePosition pos(0);
838 fmt.parse(s, af, pos);
840 UBool useEpsilon = FALSE;
841 if (af.getType() == Formattable::kLong)
843 else if (af.getType() == Formattable::kDouble) {
845 #if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
846 // S/390 will show a failure like this:
847 //| -3.141592652999999e-271 -format-> -3.1416E-271
848 //| -parse-> -3.1416e-271
849 //| FAIL: Expected -3.141599999999999e-271
850 // To compensate, we use an epsilon-based equality
851 // test on S/390 only. We don't want to do this in
852 // general because it's less exacting.
857 errln((UnicodeString)"FAIL: Non-numeric Formattable returned");
860 if (pos.getIndex() == s.length())
862 logln((UnicodeString)" -parse-> " + a);
863 // Use epsilon comparison as necessary
865 (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
866 (!useEpsilon && a != valParse[v+ival]))
868 errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]);
872 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
873 errln((UnicodeString)" should be (" + s.length() + " chars) -> " + valParse[v+ival]);
876 for (v=0; v<lval_length; ++v)
879 (*(NumberFormat*)&fmt).format(lval[v], s);
880 logln((UnicodeString)" " + lval[v] + "L -format-> " + s);
881 if (s != lvalFormat[v+ilval])
882 errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s);
884 ParsePosition pos(0);
886 fmt.parse(s, af, pos);
887 if (af.getType() == Formattable::kLong ||
888 af.getType() == Formattable::kInt64) {
889 UErrorCode status = U_ZERO_ERROR;
890 int32_t a = af.getLong(status);
891 if (pos.getIndex() == s.length())
893 logln((UnicodeString)" -parse-> " + a);
894 if (a != lvalParse[v+ilval])
895 errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]);
898 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
901 errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
902 + " Double: " + af.getDouble()
903 + ", Long: " + af.getLong());
906 ilval += lval_length;
911 NumberFormatTest::TestScientific2() {
913 UErrorCode status = U_ZERO_ERROR;
914 DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
915 if (U_SUCCESS(status)) {
917 expect(*fmt, num, "$12.34");
918 fmt->setScientificNotation(TRUE);
919 expect(*fmt, num, "$1.23E1");
920 fmt->setScientificNotation(FALSE);
921 expect(*fmt, num, "$12.34");
927 NumberFormatTest::TestScientificGrouping() {
929 UErrorCode status = U_ZERO_ERROR;
930 DecimalFormat fmt("##0.00E0",status);
931 if (U_SUCCESS(status)) {
932 expect(fmt, .01234, "12.3E-3");
933 expect(fmt, .1234, "123E-3");
934 expect(fmt, 1.234, "1.23E0");
935 expect(fmt, 12.34, "12.3E0");
936 expect(fmt, 123.4, "123E0");
937 expect(fmt, 1234., "1.23E3");
941 /*static void setFromString(DigitList& dl, const char* str) {
943 UBool decimalSet = FALSE;
945 while ((c = *str++)) {
947 dl.fIsPositive = FALSE;
948 } else if (c == '+') {
949 dl.fIsPositive = TRUE;
950 } else if (c == '.') {
951 dl.fDecimalAt = dl.fCount;
958 dl.fDecimalAt = dl.fCount;
963 NumberFormatTest::TestInt64() {
964 UErrorCode status = U_ZERO_ERROR;
965 DecimalFormat fmt("#.#E0",status);
966 if (U_FAILURE(status)) {
967 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
970 fmt.setMaximumFractionDigits(20);
971 if (U_SUCCESS(status)) {
972 expect(fmt, (Formattable)(int64_t)0, "0E0");
973 expect(fmt, (Formattable)(int64_t)-1, "-1E0");
974 expect(fmt, (Formattable)(int64_t)1, "1E0");
975 expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9");
976 expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9");
977 expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18");
978 expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18");
981 // also test digitlist
982 /* int64_t int64max = U_INT64_MAX;
983 int64_t int64min = U_INT64_MIN;
984 const char* int64maxstr = "9223372036854775807";
985 const char* int64minstr = "-9223372036854775808";
986 UnicodeString fail("fail: ");
988 // test max int64 value
990 setFromString(dl, int64maxstr);
992 if (!dl.fitsIntoInt64(FALSE)) {
993 errln(fail + int64maxstr + " didn't fit");
995 int64_t int64Value = dl.getInt64();
996 if (int64Value != int64max) {
997 errln(fail + int64maxstr);
1000 int64Value = dl.getInt64();
1001 if (int64Value != int64max) {
1002 errln(fail + int64maxstr);
1005 // test negative of max int64 value (1 shy of min int64 value)
1006 dl.fIsPositive = FALSE;
1008 if (!dl.fitsIntoInt64(FALSE)) {
1009 errln(fail + "-" + int64maxstr + " didn't fit");
1011 int64_t int64Value = dl.getInt64();
1012 if (int64Value != -int64max) {
1013 errln(fail + "-" + int64maxstr);
1016 int64Value = dl.getInt64();
1017 if (int64Value != -int64max) {
1018 errln(fail + "-" + int64maxstr);
1021 // test min int64 value
1022 setFromString(dl, int64minstr);
1024 if (!dl.fitsIntoInt64(FALSE)) {
1025 errln(fail + "-" + int64minstr + " didn't fit");
1027 int64_t int64Value = dl.getInt64();
1028 if (int64Value != int64min) {
1029 errln(fail + int64minstr);
1032 int64Value = dl.getInt64();
1033 if (int64Value != int64min) {
1034 errln(fail + int64minstr);
1037 // test negative of min int 64 value (1 more than max int64 value)
1038 dl.fIsPositive = TRUE; // won't fit
1040 if (dl.fitsIntoInt64(FALSE)) {
1041 errln(fail + "-(" + int64minstr + ") didn't fit");
1046 // -------------------------------------
1048 // Test the handling of quotes
1050 NumberFormatTest::TestQuotes(void)
1052 UErrorCode status = U_ZERO_ERROR;
1054 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
1055 if (U_FAILURE(status)) {
1056 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
1060 pat = new UnicodeString("a'fo''o'b#");
1061 DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
1063 ((NumberFormat*)fmt)->format((int32_t)123, s);
1064 logln((UnicodeString)"Pattern \"" + *pat + "\"");
1065 logln((UnicodeString)" Format 123 -> " + escape(s));
1066 if (!(s=="afo'ob123"))
1067 errln((UnicodeString)"FAIL: Expected afo'ob123");
1073 pat = new UnicodeString("a''b#");
1074 fmt = new DecimalFormat(*pat, *sym, status);
1075 ((NumberFormat*)fmt)->format((int32_t)123, s);
1076 logln((UnicodeString)"Pattern \"" + *pat + "\"");
1077 logln((UnicodeString)" Format 123 -> " + escape(s));
1079 errln((UnicodeString)"FAIL: Expected a'b123");
1086 * Test the handling of the currency symbol in patterns.
1089 NumberFormatTest::TestCurrencySign(void)
1091 UErrorCode status = U_ZERO_ERROR;
1092 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
1094 UChar currency = 0x00A4;
1095 if (U_FAILURE(status)) {
1096 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
1100 // "\xA4#,##0.00;-\xA4#,##0.00"
1101 pat.append(currency).append("#,##0.00;-").
1102 append(currency).append("#,##0.00");
1103 DecimalFormat *fmt = new DecimalFormat(pat, *sym, status);
1104 UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s);
1106 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
1107 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
1108 if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56");
1110 ((NumberFormat*)fmt)->format(- 1234.56, s);
1111 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
1112 if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56");
1115 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
1116 pat.append(currency).append(currency).
1117 append(" #,##0.00;").
1118 append(currency).append(currency).
1119 append(" -#,##0.00");
1120 fmt = new DecimalFormat(pat, *sym, status);
1122 ((NumberFormat*)fmt)->format(1234.56, s);
1123 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
1124 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
1125 if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56");
1127 ((NumberFormat*)fmt)->format(-1234.56, s);
1128 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
1129 if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56");
1132 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status));
1135 // -------------------------------------
1137 static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
1140 NumberFormatTest::escape(UnicodeString& s)
1143 for (int32_t i=0; i<s.length(); ++i)
1145 UChar c = s[(int32_t)i];
1146 if (c <= (UChar)0x7F) buf += c;
1148 buf += (UChar)0x5c; buf += (UChar)0x55;
1149 buf += toHexString((c & 0xF000) >> 12);
1150 buf += toHexString((c & 0x0F00) >> 8);
1151 buf += toHexString((c & 0x00F0) >> 4);
1152 buf += toHexString(c & 0x000F);
1159 // -------------------------------------
1160 static const char* testCases[][2]= {
1161 /* locale ID */ /* expected */
1162 {"ca_ES_PREEURO", "\\u20A7\\u00A01.150" },
1163 {"de_LU_PREEURO", "1,150\\u00A0F" },
1164 {"el_GR_PREEURO", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
1165 {"en_BE_PREEURO", "1.150,50\\u00A0BEF" },
1166 {"es_ES_PREEURO", "1.150\\u00A0\\u20A7" },
1167 {"eu_ES_PREEURO", "\\u20A7\\u00A01.150" },
1168 {"gl_ES_PREEURO", "1.150\\u00A0\\u20A7" },
1169 {"it_IT_PREEURO", "ITL\\u00A01.150" },
1170 {"pt_PT_PREEURO", "1,150$50\\u00A0\\u200B"}, // per cldrbug 7670
1171 {"en_US@currency=JPY", "\\u00A51,150"},
1172 {"en_US@currency=jpy", "\\u00A51,150"},
1173 {"en-US-u-cu-jpy", "\\u00A51,150"}
1176 * Test localized currency patterns.
1179 NumberFormatTest::TestCurrency(void)
1181 UErrorCode status = U_ZERO_ERROR;
1182 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
1183 if (U_FAILURE(status)) {
1184 dataerrln("Error calling NumberFormat::createCurrencyInstance()");
1188 UnicodeString s; currencyFmt->format(1.50, s);
1189 logln((UnicodeString)"Un pauvre ici a..........." + s);
1190 if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
1191 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$");
1195 int len = uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
1196 (void)len; // Suppress unused variable warning.
1197 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
1198 currencyFmt->format(1.50, s);
1199 logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
1200 if (!(s==CharsToUnicodeString("1,50\\u00A0DM")))
1201 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM");
1204 len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
1205 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
1206 currencyFmt->format(1.50, s);
1207 logln((UnicodeString)"Un pauvre en France a....." + s);
1208 if (!(s==CharsToUnicodeString("1,50\\u00A0F")))
1209 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F");
1211 if (U_FAILURE(status))
1212 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1214 for(int i=0; i < UPRV_LENGTHOF(testCases); i++){
1215 status = U_ZERO_ERROR;
1216 const char *localeID = testCases[i][0];
1217 UnicodeString expected(testCases[i][1], -1, US_INV);
1218 expected = expected.unescape();
1221 uloc_canonicalize(localeID, loc, 256, &status);
1222 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
1223 if(U_FAILURE(status)){
1224 errln("Could not create currency formatter for locale %s",localeID);
1227 currencyFmt->format(1150.50, s);
1229 errln(UnicodeString("FAIL: Expected: ")+expected
1230 + UnicodeString(" Got: ") + s
1231 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
1233 if (U_FAILURE(status)){
1234 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1240 // -------------------------------------
1243 * Test the Currency object handling, new as of ICU 2.2.
1245 void NumberFormatTest::TestCurrencyObject() {
1246 UErrorCode ec = U_ZERO_ERROR;
1248 NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
1250 if (U_FAILURE(ec)) {
1251 dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec));
1256 Locale null("", "", "");
1258 expectCurrency(*fmt, null, 1234.56, "$1,234.56");
1260 expectCurrency(*fmt, Locale::getFrance(),
1261 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
1263 expectCurrency(*fmt, Locale::getJapan(),
1264 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
1266 expectCurrency(*fmt, Locale("fr", "CH", ""),
1267 1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
1269 expectCurrency(*fmt, Locale::getUS(),
1270 1234.56, "$1,234.56");
1273 fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
1275 if (U_FAILURE(ec)) {
1276 errln("FAIL: getCurrencyInstance(FRANCE)");
1281 expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
1283 expectCurrency(*fmt, Locale::getJapan(),
1284 1234.56, CharsToUnicodeString("1 235 JPY")); // Yen
1286 expectCurrency(*fmt, Locale("fr", "CH", ""),
1287 1234.56, "1 234,56 CHF"); // no more 0.05 rounding here, see cldrbug 5548
1289 expectCurrency(*fmt, Locale::getUS(),
1290 1234.56, "1 234,56 $US");
1292 expectCurrency(*fmt, Locale::getFrance(),
1293 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
1298 // -------------------------------------
1301 * Do rudimentary testing of parsing.
1304 NumberFormatTest::TestParse(void)
1306 UErrorCode status = U_ZERO_ERROR;
1307 UnicodeString arg("0");
1308 DecimalFormat* format = new DecimalFormat("00", status);
1310 Formattable n; format->parse(arg, n, status);
1311 logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
1312 if (n.getType() != Formattable::kLong ||
1313 n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
1315 if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status));
1317 //catch(Exception e) {
1318 // errln((UnicodeString)"Exception caught: " + e);
1322 // -------------------------------------
1324 static const char *lenientAffixTestCases[] = {
1331 static const char *lenientMinusTestCases[] = {
1337 static const char *lenientCurrencyTestCases[] = {
1348 // changed from () to - per cldrbug 5674
1349 static const char *lenientNegativeCurrencyTestCases[] = {
1357 "-$ 1\\u00A0000.00",
1361 static const char *lenientPercentTestCases[] = {
1370 static const char *lenientNegativePercentTestCases[] = {
1382 static const char *strictFailureTestCases[] = {
1389 * Test lenient parsing.
1392 NumberFormatTest::TestLenientParse(void)
1394 UErrorCode status = U_ZERO_ERROR;
1395 DecimalFormat *format = new DecimalFormat("(#,##0)", status);
1398 if (format == NULL || U_FAILURE(status)) {
1399 dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status));
1401 format->setLenient(TRUE);
1402 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientAffixTestCases); t += 1) {
1403 UnicodeString testCase = ctou(lenientAffixTestCases[t]);
1405 format->parse(testCase, n, status);
1406 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1408 if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
1410 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t] + (UnicodeString) "\"");
1411 status = U_ZERO_ERROR;
1417 Locale en_US("en_US");
1418 Locale sv_SE("sv_SE");
1420 NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
1422 if (mFormat == NULL || U_FAILURE(status)) {
1423 dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
1425 mFormat->setLenient(TRUE);
1426 for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
1427 UnicodeString testCase = ctou(lenientMinusTestCases[t]);
1429 mFormat->parse(testCase, n, status);
1430 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1432 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
1433 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
1434 status = U_ZERO_ERROR;
1440 mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
1442 if (mFormat == NULL || U_FAILURE(status)) {
1443 dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
1445 mFormat->setLenient(TRUE);
1446 for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
1447 UnicodeString testCase = ctou(lenientMinusTestCases[t]);
1449 mFormat->parse(testCase, n, status);
1450 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1452 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
1453 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
1454 status = U_ZERO_ERROR;
1460 NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
1462 if (cFormat == NULL || U_FAILURE(status)) {
1463 dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status));
1465 cFormat->setLenient(TRUE);
1466 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientCurrencyTestCases); t += 1) {
1467 UnicodeString testCase = ctou(lenientCurrencyTestCases[t]);
1469 cFormat->parse(testCase, n, status);
1470 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1472 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1473 n.getLong() != 1000) {
1474 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t] + (UnicodeString) "\"");
1475 status = U_ZERO_ERROR;
1479 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativeCurrencyTestCases); t += 1) {
1480 UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]);
1482 cFormat->parse(testCase, n, status);
1483 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1485 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1486 n.getLong() != -1000) {
1487 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t] + (UnicodeString) "\"");
1488 status = U_ZERO_ERROR;
1495 NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status);
1497 if (pFormat == NULL || U_FAILURE(status)) {
1498 dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status));
1500 pFormat->setLenient(TRUE);
1501 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientPercentTestCases); t += 1) {
1502 UnicodeString testCase = ctou(lenientPercentTestCases[t]);
1504 pFormat->parse(testCase, n, status);
1505 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1507 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1508 n.getDouble() != 0.25) {
1509 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t] + (UnicodeString) "\"");
1510 status = U_ZERO_ERROR;
1514 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativePercentTestCases); t += 1) {
1515 UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]);
1517 pFormat->parse(testCase, n, status);
1518 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1520 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1521 n.getDouble() != -0.25) {
1522 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t] + (UnicodeString) "\"");
1523 status = U_ZERO_ERROR;
1530 // Test cases that should fail with a strict parse and pass with a
1532 NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
1534 if (nFormat == NULL || U_FAILURE(status)) {
1535 dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
1537 // first, make sure that they fail with a strict parse
1538 for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
1539 UnicodeString testCase = ctou(strictFailureTestCases[t]);
1541 nFormat->parse(testCase, n, status);
1542 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1544 if (! U_FAILURE(status)) {
1545 errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1548 status = U_ZERO_ERROR;
1551 // then, make sure that they pass with a lenient parse
1552 nFormat->setLenient(TRUE);
1553 for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
1554 UnicodeString testCase = ctou(strictFailureTestCases[t]);
1556 nFormat->parse(testCase, n, status);
1557 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1559 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1560 n.getLong() != 1000) {
1561 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1562 status = U_ZERO_ERROR;
1570 // -------------------------------------
1573 * Test proper rounding by the format method.
1576 NumberFormatTest::TestRounding487(void)
1578 UErrorCode status = U_ZERO_ERROR;
1579 NumberFormat *nf = NumberFormat::createInstance(status);
1580 if (U_FAILURE(status)) {
1581 dataerrln("Error calling NumberFormat::createInstance()");
1585 roundingTest(*nf, 0.00159999, 4, "0.0016");
1586 roundingTest(*nf, 0.00995, 4, "0.01");
1588 roundingTest(*nf, 12.3995, 3, "12.4");
1590 roundingTest(*nf, 12.4999, 0, "12");
1591 roundingTest(*nf, - 19.5, 0, "-20");
1593 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1597 * Test the functioning of the secondary grouping value.
1599 void NumberFormatTest::TestSecondaryGrouping(void) {
1600 UErrorCode status = U_ZERO_ERROR;
1601 DecimalFormatSymbols US(Locale::getUS(), status);
1602 CHECK(status, "DecimalFormatSymbols ct");
1604 DecimalFormat f("#,##,###", US, status);
1605 CHECK(status, "DecimalFormat ct");
1607 expect2(f, (int32_t)123456789L, "12,34,56,789");
1608 expectPat(f, "#,##,###");
1609 f.applyPattern("#,###", status);
1610 CHECK(status, "applyPattern");
1612 f.setSecondaryGroupingSize(4);
1613 expect2(f, (int32_t)123456789L, "12,3456,789");
1614 expectPat(f, "#,####,###");
1615 NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
1616 CHECK_DATA(status, "createInstance(hi_IN)");
1619 int32_t l = (int32_t)1876543210L;
1622 // expect "1,87,65,43,210", but with Hindi digits
1625 if (out.length() != 14) {
1628 for (int32_t i=0; i<out.length(); ++i) {
1629 UBool expectGroup = FALSE;
1638 // Later -- fix this to get the actual grouping
1639 // character from the resource bundle.
1640 UBool isGroup = (out.charAt(i) == 0x002C);
1641 if (isGroup != expectGroup) {
1648 errln((UnicodeString)"FAIL Expected " + l +
1649 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1650 escape(out) + "\"");
1652 logln((UnicodeString)"Ok " + l +
1654 escape(out) + "\"");
1658 void NumberFormatTest::TestWhiteSpaceParsing(void) {
1659 UErrorCode ec = U_ZERO_ERROR;
1660 DecimalFormatSymbols US(Locale::getUS(), ec);
1661 DecimalFormat fmt("a b#0c ", US, ec);
1662 if (U_FAILURE(ec)) {
1663 errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
1667 expect(fmt, "a b1234c ", n);
1668 expect(fmt, "a b1234c ", n);
1672 * Test currencies whose display name is a ChoiceFormat.
1674 void NumberFormatTest::TestComplexCurrency() {
1676 // UErrorCode ec = U_ZERO_ERROR;
1677 // Locale loc("kn", "IN", "");
1678 // NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
1679 // if (U_SUCCESS(ec)) {
1680 // expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
1681 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
1682 // expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
1683 // expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
1684 // expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
1685 // expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
1686 // expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
1688 // errln("FAIL: getCurrencyInstance(kn_IN)");
1694 // -------------------------------------
1697 NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
1699 nf.setMaximumFractionDigits(maxFractionDigits);
1700 UnicodeString out; nf.format(x, out);
1701 logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
1702 if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected);
1706 * Upgrade to alphaWorks
1708 void NumberFormatTest::TestExponent(void) {
1709 UErrorCode status = U_ZERO_ERROR;
1710 DecimalFormatSymbols US(Locale::getUS(), status);
1711 CHECK(status, "DecimalFormatSymbols constructor");
1712 DecimalFormat fmt1(UnicodeString("0.###E0"), US, status);
1713 CHECK(status, "DecimalFormat(0.###E0)");
1714 DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status);
1715 CHECK(status, "DecimalFormat(0.###E+0)");
1717 expect2(fmt1, n, "1.234E3");
1718 expect2(fmt2, n, "1.234E+3");
1719 expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
1723 * Upgrade to alphaWorks
1725 void NumberFormatTest::TestScientific(void) {
1726 UErrorCode status = U_ZERO_ERROR;
1727 DecimalFormatSymbols US(Locale::getUS(), status);
1728 CHECK(status, "DecimalFormatSymbols constructor");
1730 // Test pattern round-trip
1731 const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1732 "0.###E0;[0.###E0]" };
1733 int32_t PAT_length = UPRV_LENGTHOF(PAT);
1734 int32_t DIGITS[] = {
1735 // min int, max int, min frac, max frac
1736 0, 1, 0, 0, // "#E0"
1737 1, 1, 0, 4, // "0.####E0"
1738 2, 2, 3, 3, // "00.000E00"
1739 1, 3, 0, 4, // "##0.####E000"
1740 1, 1, 0, 3, // "0.###E0;[0.###E0]"
1742 for (int32_t i=0; i<PAT_length; ++i) {
1743 UnicodeString pat(PAT[i]);
1744 DecimalFormat df(pat, US, status);
1745 CHECK(status, "DecimalFormat constructor");
1749 logln(UnicodeString("Ok Pattern rt \"") +
1753 errln(UnicodeString("FAIL Pattern rt \"") +
1757 // Make sure digit counts match what we expect
1758 if (df.getMinimumIntegerDigits() != DIGITS[4*i] ||
1759 df.getMaximumIntegerDigits() != DIGITS[4*i+1] ||
1760 df.getMinimumFractionDigits() != DIGITS[4*i+2] ||
1761 df.getMaximumFractionDigits() != DIGITS[4*i+3]) {
1762 errln(UnicodeString("FAIL \"" + pat +
1763 "\" min/max int; min/max frac = ") +
1764 df.getMinimumIntegerDigits() + "/" +
1765 df.getMaximumIntegerDigits() + ";" +
1766 df.getMinimumFractionDigits() + "/" +
1767 df.getMaximumFractionDigits() + ", expect " +
1769 DIGITS[4*i+1] + ";" +
1770 DIGITS[4*i+2] + "/" +
1776 // Test the constructor for default locale. We have to
1777 // manually set the default locale, as there is no
1778 // guarantee that the default locale has the same
1779 // scientific format.
1780 Locale def = Locale::getDefault();
1781 Locale::setDefault(Locale::getUS(), status);
1782 expect2(NumberFormat::createScientificInstance(status),
1784 "1.2345678901E4", status);
1785 Locale::setDefault(def, status);
1787 expect2(new DecimalFormat("#E0", US, status),
1789 "1.2345E4", status);
1790 expect(new DecimalFormat("0E0", US, status),
1793 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
1795 "1.2345678901E4", status);
1796 expect(new DecimalFormat("##0.###E0", US, status),
1799 expect(new DecimalFormat("##0.###E0", US, status),
1802 expect2(new DecimalFormat("##0.####E0", US, status),
1804 "12.345E3", status);
1805 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
1807 "1,2345678901E4", status);
1808 expect(new DecimalFormat("##0.####E0", US, status),
1810 "789.12E-9", status);
1811 expect2(new DecimalFormat("##0.####E0", US, status),
1814 expect(new DecimalFormat(".###E0", US, status),
1817 expect2(new DecimalFormat(".###E0", US, status),
1821 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1822 new DecimalFormat("##E0", US),
1823 new DecimalFormat("####E0", US),
1824 new DecimalFormat("0E0", US),
1825 new DecimalFormat("00E0", US),
1826 new DecimalFormat("000E0", US),
1829 new String[] { "4.5678E7",
1838 ! Unroll this test into individual tests below...
1841 expect2(new DecimalFormat("#E0", US, status),
1842 (int32_t) 45678000, "4.5678E7", status);
1843 expect2(new DecimalFormat("##E0", US, status),
1844 (int32_t) 45678000, "45.678E6", status);
1845 expect2(new DecimalFormat("####E0", US, status),
1846 (int32_t) 45678000, "4567.8E4", status);
1847 expect(new DecimalFormat("0E0", US, status),
1848 (int32_t) 45678000, "5E7", status);
1849 expect(new DecimalFormat("00E0", US, status),
1850 (int32_t) 45678000, "46E6", status);
1851 expect(new DecimalFormat("000E0", US, status),
1852 (int32_t) 45678000, "457E5", status);
1854 expect(new DecimalFormat("###E0", US, status),
1855 new Object[] { new Double(0.0000123), "12.3E-6",
1856 new Double(0.000123), "123E-6",
1857 new Double(0.00123), "1.23E-3",
1858 new Double(0.0123), "12.3E-3",
1859 new Double(0.123), "123E-3",
1860 new Double(1.23), "1.23E0",
1861 new Double(12.3), "12.3E0",
1862 new Double(123), "123E0",
1863 new Double(1230), "1.23E3",
1866 ! Unroll this test into individual tests below...
1869 expect2(new DecimalFormat("###E0", US, status),
1870 0.0000123, "12.3E-6", status);
1871 expect2(new DecimalFormat("###E0", US, status),
1872 0.000123, "123E-6", status);
1873 expect2(new DecimalFormat("###E0", US, status),
1874 0.00123, "1.23E-3", status);
1875 expect2(new DecimalFormat("###E0", US, status),
1876 0.0123, "12.3E-3", status);
1877 expect2(new DecimalFormat("###E0", US, status),
1878 0.123, "123E-3", status);
1879 expect2(new DecimalFormat("###E0", US, status),
1880 1.23, "1.23E0", status);
1881 expect2(new DecimalFormat("###E0", US, status),
1882 12.3, "12.3E0", status);
1883 expect2(new DecimalFormat("###E0", US, status),
1884 123.0, "123E0", status);
1885 expect2(new DecimalFormat("###E0", US, status),
1886 1230.0, "1.23E3", status);
1888 expect(new DecimalFormat("0.#E+00", US, status),
1889 new Object[] { new Double(0.00012), "1.2E-04",
1890 new Long(12000), "1.2E+04",
1893 ! Unroll this test into individual tests below...
1896 expect2(new DecimalFormat("0.#E+00", US, status),
1897 0.00012, "1.2E-04", status);
1898 expect2(new DecimalFormat("0.#E+00", US, status),
1899 (int32_t) 12000, "1.2E+04", status);
1903 * Upgrade to alphaWorks
1905 void NumberFormatTest::TestPad(void) {
1906 UErrorCode status = U_ZERO_ERROR;
1907 DecimalFormatSymbols US(Locale::getUS(), status);
1908 CHECK(status, "DecimalFormatSymbols constructor");
1910 expect2(new DecimalFormat("*^##.##", US, status),
1911 int32_t(0), "^^^^0", status);
1912 expect2(new DecimalFormat("*^##.##", US, status),
1913 -1.3, "^-1.3", status);
1914 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1915 int32_t(0), "0.0E0______ g-m/s^2", status);
1916 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1917 1.0/3, "333.333E-3_ g-m/s^2", status);
1918 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1919 int32_t(0), "0.0______ g-m/s^2", status);
1920 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1921 1.0/3, "0.33333__ g-m/s^2", status);
1923 // Test padding before a sign
1924 const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1925 expect2(new DecimalFormat(formatStr, US, status),
1926 int32_t(-10), "xxxxxxxxxx(10.0)", status);
1927 expect2(new DecimalFormat(formatStr, US, status),
1928 int32_t(-1000),"xxxxxxx(1,000.0)", status);
1929 expect2(new DecimalFormat(formatStr, US, status),
1930 int32_t(-1000000),"xxx(1,000,000.0)", status);
1931 expect2(new DecimalFormat(formatStr, US, status),
1932 -100.37, "xxxxxxxx(100.37)", status);
1933 expect2(new DecimalFormat(formatStr, US, status),
1934 -10456.37, "xxxxx(10,456.37)", status);
1935 expect2(new DecimalFormat(formatStr, US, status),
1936 -1120456.37, "xx(1,120,456.37)", status);
1937 expect2(new DecimalFormat(formatStr, US, status),
1938 -112045600.37, "(112,045,600.37)", status);
1939 expect2(new DecimalFormat(formatStr, US, status),
1940 -1252045600.37,"(1,252,045,600.37)", status);
1942 expect2(new DecimalFormat(formatStr, US, status),
1943 int32_t(10), "xxxxxxxxxxxx10.0", status);
1944 expect2(new DecimalFormat(formatStr, US, status),
1945 int32_t(1000),"xxxxxxxxx1,000.0", status);
1946 expect2(new DecimalFormat(formatStr, US, status),
1947 int32_t(1000000),"xxxxx1,000,000.0", status);
1948 expect2(new DecimalFormat(formatStr, US, status),
1949 100.37, "xxxxxxxxxx100.37", status);
1950 expect2(new DecimalFormat(formatStr, US, status),
1951 10456.37, "xxxxxxx10,456.37", status);
1952 expect2(new DecimalFormat(formatStr, US, status),
1953 1120456.37, "xxxx1,120,456.37", status);
1954 expect2(new DecimalFormat(formatStr, US, status),
1955 112045600.37, "xx112,045,600.37", status);
1956 expect2(new DecimalFormat(formatStr, US, status),
1957 10252045600.37,"10,252,045,600.37", status);
1960 // Test padding between a sign and a number
1961 const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1962 expect2(new DecimalFormat(formatStr2, US, status),
1963 int32_t(-10), "(10.0xxxxxxxxxx)", status);
1964 expect2(new DecimalFormat(formatStr2, US, status),
1965 int32_t(-1000),"(1,000.0xxxxxxx)", status);
1966 expect2(new DecimalFormat(formatStr2, US, status),
1967 int32_t(-1000000),"(1,000,000.0xxx)", status);
1968 expect2(new DecimalFormat(formatStr2, US, status),
1969 -100.37, "(100.37xxxxxxxx)", status);
1970 expect2(new DecimalFormat(formatStr2, US, status),
1971 -10456.37, "(10,456.37xxxxx)", status);
1972 expect2(new DecimalFormat(formatStr2, US, status),
1973 -1120456.37, "(1,120,456.37xx)", status);
1974 expect2(new DecimalFormat(formatStr2, US, status),
1975 -112045600.37, "(112,045,600.37)", status);
1976 expect2(new DecimalFormat(formatStr2, US, status),
1977 -1252045600.37,"(1,252,045,600.37)", status);
1979 expect2(new DecimalFormat(formatStr2, US, status),
1980 int32_t(10), "10.0xxxxxxxxxxxx", status);
1981 expect2(new DecimalFormat(formatStr2, US, status),
1982 int32_t(1000),"1,000.0xxxxxxxxx", status);
1983 expect2(new DecimalFormat(formatStr2, US, status),
1984 int32_t(1000000),"1,000,000.0xxxxx", status);
1985 expect2(new DecimalFormat(formatStr2, US, status),
1986 100.37, "100.37xxxxxxxxxx", status);
1987 expect2(new DecimalFormat(formatStr2, US, status),
1988 10456.37, "10,456.37xxxxxxx", status);
1989 expect2(new DecimalFormat(formatStr2, US, status),
1990 1120456.37, "1,120,456.37xxxx", status);
1991 expect2(new DecimalFormat(formatStr2, US, status),
1992 112045600.37, "112,045,600.37xx", status);
1993 expect2(new DecimalFormat(formatStr2, US, status),
1994 10252045600.37,"10,252,045,600.37", status);
1996 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1997 DecimalFormat fmt("#", US, status);
1998 CHECK(status, "DecimalFormat constructor");
1999 UnicodeString padString("P");
2000 fmt.setPadCharacter(padString);
2001 expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString);
2002 fmt.setPadCharacter((UnicodeString)"^");
2003 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^");
2004 //commented untill implementation is complete
2005 /* fmt.setPadCharacter((UnicodeString)"^^^");
2006 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
2008 padString.append((UChar)0x0061);
2009 padString.append((UChar)0x0302);
2010 fmt.setPadCharacter(padString);
2011 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
2012 UnicodeString pattern(patternChars);
2013 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
2019 * Upgrade to alphaWorks
2021 void NumberFormatTest::TestPatterns2(void) {
2022 UErrorCode status = U_ZERO_ERROR;
2023 DecimalFormatSymbols US(Locale::getUS(), status);
2024 CHECK(status, "DecimalFormatSymbols constructor");
2026 DecimalFormat fmt("#", US, status);
2027 CHECK(status, "DecimalFormat constructor");
2029 UChar hat = 0x005E; /*^*/
2031 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
2032 expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
2033 expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
2034 expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
2035 expectPad(fmt, "$*^$#", ILLEGAL);
2036 expectPad(fmt, "#$*^$", ILLEGAL);
2037 expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
2038 12, (UChar)0x0078 /*x*/);
2039 expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
2040 3, (UChar)0x0078 /*x*/);
2041 expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
2042 10, (UChar)0x0061 /*a*/);
2044 fmt.applyPattern("AA#,##0.00ZZ", status);
2045 CHECK(status, "applyPattern");
2046 fmt.setPadCharacter(hat);
2048 fmt.setFormatWidth(10);
2050 fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
2051 expectPat(fmt, "*^AA#,##0.00ZZ");
2053 fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
2054 expectPat(fmt, "AA#,##0.00*^ZZ");
2056 fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
2057 expectPat(fmt, "AA#,##0.00ZZ*^");
2060 UnicodeString exp("AA*^#,##0.00ZZ", "");
2061 fmt.setFormatWidth(12);
2062 fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
2063 expectPat(fmt, exp);
2065 fmt.setFormatWidth(13);
2067 expectPat(fmt, "AA*^##,##0.00ZZ");
2069 fmt.setFormatWidth(14);
2071 expectPat(fmt, "AA*^###,##0.00ZZ");
2073 fmt.setFormatWidth(15);
2075 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
2077 fmt.setFormatWidth(16);
2078 // 12 34567890123456
2079 expectPat(fmt, "AA*^#,###,##0.00ZZ");
2082 void NumberFormatTest::TestSurrogateSupport(void) {
2083 UErrorCode status = U_ZERO_ERROR;
2084 DecimalFormatSymbols custom(Locale::getUS(), status);
2085 CHECK(status, "DecimalFormatSymbols constructor");
2087 custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
2088 custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
2089 custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
2090 custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
2092 UnicodeString patternStr("*\\U00010000##.##", "");
2093 patternStr = patternStr.unescape();
2094 UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
2095 expStr = expStr.unescape();
2096 expect2(new DecimalFormat(patternStr, custom, status),
2097 int32_t(0), expStr, status);
2099 status = U_ZERO_ERROR;
2100 expect2(new DecimalFormat("*^##.##", custom, status),
2101 int32_t(0), "^^^^0", status);
2102 status = U_ZERO_ERROR;
2103 expect2(new DecimalFormat("##.##", custom, status),
2104 -1.3, " minus 1decimal3", status);
2105 status = U_ZERO_ERROR;
2106 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
2107 int32_t(0), "0decimal0exponent0 g-m/s^2", status);
2108 status = U_ZERO_ERROR;
2109 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
2110 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
2111 status = U_ZERO_ERROR;
2112 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
2113 int32_t(0), "0decimal0 g-m/s^2", status);
2114 status = U_ZERO_ERROR;
2115 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
2116 1.0/3, "0decimal33333 g-m/s^2", status);
2118 UnicodeString zero((UChar32)0x10000);
2119 UnicodeString one((UChar32)0x10001);
2120 UnicodeString two((UChar32)0x10002);
2121 UnicodeString five((UChar32)0x10005);
2122 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
2123 custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one);
2124 custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two);
2125 custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five);
2126 expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
2127 expStr = expStr.unescape();
2128 status = U_ZERO_ERROR;
2129 expect2(new DecimalFormat("##0.000", custom, status),
2130 1.25, expStr, status);
2132 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
2133 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
2134 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
2135 patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
2136 patternStr = patternStr.unescape();
2137 expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", "");
2138 status = U_ZERO_ERROR;
2139 expect2(new DecimalFormat(patternStr, custom, status),
2140 int32_t(-20), expStr, status);
2142 custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent");
2143 patternStr = "'You''ve lost ' -0.00 %' of your money today'";
2144 patternStr = patternStr.unescape();
2145 expStr = UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
2146 status = U_ZERO_ERROR;
2147 expect2(new DecimalFormat(patternStr, custom, status),
2148 int32_t(-20), expStr, status);
2151 void NumberFormatTest::TestCurrencyPatterns(void) {
2152 int32_t i, locCount;
2153 const Locale* locs = NumberFormat::getAvailableLocales(locCount);
2154 for (i=0; i<locCount; ++i) {
2155 UErrorCode ec = U_ZERO_ERROR;
2156 NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec);
2157 if (U_FAILURE(ec)) {
2158 errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
2160 // Make sure currency formats do not have a variable number
2161 // of fraction digits
2162 int32_t min = nf->getMinimumFractionDigits();
2163 int32_t max = nf->getMaximumFractionDigits();
2167 nf->format(1.125, b);
2168 errln((UnicodeString)"FAIL: " + locs[i].getName() +
2169 " min fraction digits != max fraction digits; "
2170 "x 1.0 => " + escape(a) +
2171 "; x 1.125 => " + escape(b));
2174 // Make sure EURO currency formats have exactly 2 fraction digits
2175 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
2177 if (u_strcmp(EUR, df->getCurrency()) == 0) {
2178 if (min != 2 || max != 2) {
2181 errln((UnicodeString)"FAIL: " + locs[i].getName() +
2182 " is a EURO format but it does not have 2 fraction digits; "
2193 void NumberFormatTest::TestRegCurrency(void) {
2194 #if !UCONFIG_NO_SERVICE
2195 UErrorCode status = U_ZERO_ERROR;
2197 ucurr_forLocale("en_US", USD, 4, &status);
2199 ucurr_forLocale("ja_JP", YEN, 4, &status);
2201 static const UChar QQQ[] = {0x51, 0x51, 0x51, 0};
2202 if(U_FAILURE(status)) {
2203 errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status));
2207 UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
2208 UCurrRegistryKey enUSEUROkey = ucurr_register(QQQ, "en_US_EURO", &status);
2210 ucurr_forLocale("en_US", TMP, 4, &status);
2211 if (u_strcmp(YEN, TMP) != 0) {
2212 errln("FAIL: didn't return YEN registered for en_US");
2215 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
2216 if (u_strcmp(QQQ, TMP) != 0) {
2217 errln("FAIL: didn't return QQQ for en_US_EURO");
2220 int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
2222 errln("FAIL: tried to fallback en_XX_BAR");
2224 status = U_ZERO_ERROR; // reset
2226 if (!ucurr_unregister(enkey, &status)) {
2227 errln("FAIL: couldn't unregister enkey");
2230 ucurr_forLocale("en_US", TMP, 4, &status);
2231 if (u_strcmp(USD, TMP) != 0) {
2232 errln("FAIL: didn't return USD for en_US after unregister of en_US");
2234 status = U_ZERO_ERROR; // reset
2236 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
2237 if (u_strcmp(QQQ, TMP) != 0) {
2238 errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
2241 ucurr_forLocale("en_US_BLAH", TMP, 4, &status);
2242 if (u_strcmp(USD, TMP) != 0) {
2243 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
2245 status = U_ZERO_ERROR; // reset
2247 if (!ucurr_unregister(enUSEUROkey, &status)) {
2248 errln("FAIL: couldn't unregister enUSEUROkey");
2251 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
2252 if (u_strcmp(EUR, TMP) != 0) {
2253 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
2255 status = U_ZERO_ERROR; // reset
2259 void NumberFormatTest::TestCurrencyNames(void) {
2260 // Do a basic check of getName()
2261 // USD { "US$", "US Dollar" } // 04/04/1792-
2262 UErrorCode ec = U_ZERO_ERROR;
2263 static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/
2264 static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/
2265 static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
2266 static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
2267 UBool isChoiceFormat;
2269 const UBool possibleDataError = TRUE;
2270 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
2271 // THE LOCALE DATA before diving into the code.
2272 assertEquals("USD.getName(SYMBOL_NAME)",
2274 UnicodeString(ucurr_getName(USD, "en",
2276 &isChoiceFormat, &len, &ec)),
2278 assertEquals("USD.getName(LONG_NAME)",
2279 UnicodeString("US Dollar"),
2280 UnicodeString(ucurr_getName(USD, "en",
2282 &isChoiceFormat, &len, &ec)),
2284 assertEquals("CAD.getName(SYMBOL_NAME)",
2285 UnicodeString("CA$"),
2286 UnicodeString(ucurr_getName(CAD, "en",
2288 &isChoiceFormat, &len, &ec)),
2290 assertEquals("CAD.getName(SYMBOL_NAME)",
2292 UnicodeString(ucurr_getName(CAD, "en_CA",
2294 &isChoiceFormat, &len, &ec)),
2296 assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
2297 UnicodeString("US$"),
2298 UnicodeString(ucurr_getName(USD, "en_NZ",
2300 &isChoiceFormat, &len, &ec)),
2302 assertEquals("CAD.getName(SYMBOL_NAME)",
2303 UnicodeString("CA$"),
2304 UnicodeString(ucurr_getName(CAD, "en_NZ",
2306 &isChoiceFormat, &len, &ec)),
2308 assertEquals("USX.getName(LONG_NAME)",
2309 UnicodeString("USX"),
2310 UnicodeString(ucurr_getName(USX, "en_US",
2312 &isChoiceFormat, &len, &ec)),
2314 assertSuccess("ucurr_getName", ec);
2318 // Test that a default or fallback warning is being returned. JB 4239.
2319 ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat,
2321 assertTrue("ucurr_getName (es_ES fallback)",
2322 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
2324 ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat,
2326 assertTrue("ucurr_getName (zh_TW fallback)",
2327 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
2329 ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
2331 assertTrue("ucurr_getName (en_US default)",
2332 U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE);
2334 ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat,
2336 assertTrue("ucurr_getName (ti default)",
2337 U_USING_DEFAULT_WARNING == ec, TRUE);
2339 // Test that a default warning is being returned when falling back to root. JB 4536.
2340 ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
2342 assertTrue("ucurr_getName (cy default to root)",
2343 U_USING_DEFAULT_WARNING == ec, TRUE);
2345 // TODO add more tests later
2348 void NumberFormatTest::TestCurrencyUnit(void){
2349 UErrorCode ec = U_ZERO_ERROR;
2350 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
2351 static const UChar BAD[] = {63, 63, 63, 0}; /*???*/
2352 static const UChar BAD2[] = {63, 63, 65, 0}; /*???*/
2353 CurrencyUnit cu(USD, ec);
2354 assertSuccess("CurrencyUnit", ec);
2356 const UChar * r = cu.getISOCurrency(); // who is the buffer owner ?
2357 assertEquals("getISOCurrency()", USD, r);
2359 CurrencyUnit cu2(cu);
2361 errln("CurrencyUnit copy constructed object should be same");
2364 CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
2366 errln("CurrencyUnit cloned object should be same");
2368 CurrencyUnit bad(BAD, ec);
2369 assertSuccess("CurrencyUnit", ec);
2370 if (cu.getIndex() == bad.getIndex()) {
2371 errln("Indexes of different currencies should differ.");
2373 CurrencyUnit bad2(BAD2, ec);
2374 assertSuccess("CurrencyUnit", ec);
2375 if (bad2.getIndex() != bad.getIndex()) {
2376 errln("Indexes of unrecognized currencies should be the same.");
2379 errln("Different unrecognized currencies should not be equal.");
2383 errln("Currency unit assignment should be the same.");
2388 void NumberFormatTest::TestCurrencyAmount(void){
2389 UErrorCode ec = U_ZERO_ERROR;
2390 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
2391 CurrencyAmount ca(9, USD, ec);
2392 assertSuccess("CurrencyAmount", ec);
2394 CurrencyAmount ca2(ca);
2396 errln("CurrencyAmount copy constructed object should be same");
2401 errln("CurrencyAmount assigned object should be same");
2404 CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone();
2406 errln("CurrencyAmount cloned object should be same");
2411 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
2413 static const char *badLocales[] = {
2414 // length < ULOC_FULLNAME_CAPACITY
2415 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
2417 // length > ULOC_FULLNAME_CAPACITY
2418 "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"
2419 }; // expect U_USING_DEFAULT_WARNING for both
2422 for (i = 0; i < UPRV_LENGTHOF(badLocales); i++) {
2423 const char *localeName = badLocales[i];
2424 Locale locBad(localeName);
2425 TEST_ASSERT_TRUE(!locBad.isBogus());
2426 UErrorCode status = U_ZERO_ERROR;
2427 UnicodeString intlCurrencySymbol((UChar)0xa4);
2429 intlCurrencySymbol.append((UChar)0xa4);
2431 logln("Current locale is %s", Locale::getDefault().getName());
2432 Locale::setDefault(locBad, status);
2433 logln("Current locale is %s", Locale::getDefault().getName());
2434 DecimalFormatSymbols mySymbols(status);
2435 if (status != U_USING_DEFAULT_WARNING) {
2436 errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
2438 if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
2439 errln("DecimalFormatSymbols does not have the right locale.", locBad.getName());
2441 int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol;
2442 for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) {
2443 UnicodeString symbolString = mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum);
2444 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ") + prettify(symbolString));
2445 if (symbolString.length() == 0
2446 && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
2447 && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
2449 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
2453 status = U_ZERO_ERROR;
2454 Locale::setDefault(locDefault, status);
2455 logln("Current locale is %s", Locale::getDefault().getName());
2460 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
2461 * behave the same, except for memory ownership semantics. (No
2462 * version of this test on Java, since Java has only one method.)
2464 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
2465 UErrorCode ec = U_ZERO_ERROR;
2466 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2467 if (U_FAILURE(ec)) {
2468 errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec));
2472 UnicodeString pat(" #,##0.00");
2473 pat.insert(0, (UChar)0x00A4);
2474 DecimalFormat fmt(pat, sym, ec);
2475 if (U_FAILURE(ec)) {
2476 errln("Fail: DecimalFormat constructor");
2481 fmt.format(2350.75, str);
2482 if (str == "$ 2,350.75") {
2485 dataerrln("Fail: " + str + ", expected $ 2,350.75");
2488 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2489 if (U_FAILURE(ec)) {
2490 errln("Fail: DecimalFormatSymbols constructor");
2494 sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2495 fmt.adoptDecimalFormatSymbols(sym);
2498 fmt.format(2350.75, str);
2499 if (str == "Q 2,350.75") {
2502 dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2505 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2506 if (U_FAILURE(ec)) {
2507 errln("Fail: DecimalFormatSymbols constructor");
2511 DecimalFormat fmt2(pat, sym, ec);
2512 if (U_FAILURE(ec)) {
2513 errln("Fail: DecimalFormat constructor");
2517 DecimalFormatSymbols sym2(Locale::getUS(), ec);
2518 if (U_FAILURE(ec)) {
2519 errln("Fail: DecimalFormatSymbols constructor");
2522 sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2523 fmt2.setDecimalFormatSymbols(sym2);
2526 fmt2.format(2350.75, str);
2527 if (str == "Q 2,350.75") {
2530 dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2534 void NumberFormatTest::TestPerMill() {
2535 UErrorCode ec = U_ZERO_ERROR;
2537 DecimalFormat fmt(ctou("###.###\\u2030"), ec);
2538 if (!assertSuccess("DecimalFormat ct", ec)) return;
2539 assertEquals("0.4857 x ###.###\\u2030",
2540 ctou("485.7\\u2030"), fmt.format(0.4857, str));
2542 DecimalFormatSymbols sym(Locale::getUS(), ec);
2543 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
2544 DecimalFormat fmt2("", sym, ec);
2545 fmt2.applyLocalizedPattern("###.###m", ec);
2546 if (!assertSuccess("setup", ec)) return;
2548 assertEquals("0.4857 x ###.###m",
2549 "485.7m", fmt2.format(0.4857, str));
2553 * Generic test for patterns that should be legal/illegal.
2555 void NumberFormatTest::TestIllegalPatterns() {
2557 // Prefix with "-:" for illegal patterns
2558 // Prefix with "+:" for legal patterns
2559 const char* DATA[] = {
2560 // Unquoted special characters in the suffix are illegal
2565 for (int32_t i=0; DATA[i]; ++i) {
2566 const char* pat=DATA[i];
2567 UBool valid = (*pat) == '+';
2569 UErrorCode ec = U_ZERO_ERROR;
2570 DecimalFormat fmt(pat, ec); // locale doesn't matter here
2571 if (U_SUCCESS(ec) == valid) {
2572 logln("Ok: pattern \"%s\": %s",
2573 pat, u_errorName(ec));
2575 errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s",
2576 pat, (valid?"succeeded":"failed"),
2582 //----------------------------------------------------------------------
2584 static const char* KEYWORDS[] = {
2585 /*0*/ "ref=", // <reference pattern to parse numbers>
2586 /*1*/ "loc=", // <locale for formats>
2587 /*2*/ "f:", // <pattern or '-'> <number> <exp. string>
2588 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
2589 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
2590 /*5*/ "p:", // <pattern or '-'> <string> <exp. number>
2591 /*6*/ "perr:", // <pattern or '-'> <invalid string>
2592 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
2593 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2598 * Return an integer representing the next token from this
2599 * iterator. The integer will be an index into the given list, or
2600 * -1 if there are no more tokens, or -2 if the token is not on
2603 static int32_t keywordIndex(const UnicodeString& tok) {
2604 for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
2605 if (tok==KEYWORDS[i]) {
2613 * Parse a CurrencyAmount using the given NumberFormat, with
2614 * the 'delim' character separating the number and the currency.
2616 static void parseCurrencyAmount(const UnicodeString& str,
2617 const NumberFormat& fmt,
2619 Formattable& result,
2621 UnicodeString num, cur;
2622 int32_t i = str.indexOf(delim);
2623 str.extractBetween(0, i, num);
2624 str.extractBetween(i+1, INT32_MAX, cur);
2626 fmt.parse(num, n, ec);
2627 result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
2630 void NumberFormatTest::TestCases() {
2631 UErrorCode ec = U_ZERO_ERROR;
2632 TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
2633 if (U_FAILURE(ec)) {
2634 dataerrln("Couldn't open NumberFormatTestCases.txt");
2637 TokenIterator tokens(&reader);
2639 Locale loc("en", "US", "");
2640 DecimalFormat *ref = 0, *fmt = 0;
2641 MeasureFormat *mfmt = 0;
2642 UnicodeString pat, tok, mloc, str, out, where, currAmt;
2647 if (!tokens.next(tok, ec)) {
2650 where = UnicodeString("(") + tokens.getLineNumber() + ") ";
2651 int32_t cmd = keywordIndex(tok);
2654 // ref= <reference pattern>
2655 if (!tokens.next(tok, ec)) goto error;
2657 ref = new DecimalFormat(tok,
2658 new DecimalFormatSymbols(Locale::getUS(), ec), ec);
2659 if (U_FAILURE(ec)) {
2660 dataerrln("Error constructing DecimalFormat");
2666 if (!tokens.next(tok, ec)) goto error;
2667 loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
2673 if (!tokens.next(tok, ec)) goto error;
2677 fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
2678 if (U_FAILURE(ec)) {
2679 errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
2681 if (!tokens.next(tok, ec)) goto error;
2682 if (!tokens.next(tok, ec)) goto error;
2684 if (!tokens.next(tok, ec)) goto error;
2689 if (cmd == 2 || cmd == 3 || cmd == 4) {
2690 // f: <pattern or '-'> <number> <exp. string>
2691 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
2692 // rt: <pattern or '-'> <number> <string>
2694 if (!tokens.next(num, ec)) goto error;
2695 if (!tokens.next(str, ec)) goto error;
2696 ref->parse(num, n, ec);
2697 assertSuccess("parse", ec);
2698 assertEquals(where + "\"" + pat + "\".format(" + num + ")",
2699 str, fmt->format(n, out.remove(), ec));
2700 assertSuccess("format", ec);
2701 if (cmd == 3) { // fp:
2702 if (!tokens.next(num, ec)) goto error;
2703 ref->parse(num, n, ec);
2704 assertSuccess("parse", ec);
2706 if (cmd != 2) { // != f:
2708 fmt->parse(str, m, ec);
2709 assertSuccess("parse", ec);
2710 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2714 // p: <pattern or '-'> <string to parse> <exp. number>
2716 UnicodeString expstr;
2717 if (!tokens.next(str, ec)) goto error;
2718 if (!tokens.next(expstr, ec)) goto error;
2720 ref->parse(expstr, exp, ec);
2721 assertSuccess("parse", ec);
2722 fmt->parse(str, n, ec);
2723 assertSuccess("parse", ec);
2724 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2729 if (!tokens.next(tok, ec)) goto error;
2733 mfmt = MeasureFormat::createCurrencyFormat(
2734 Locale::createFromName(
2735 CharString().appendInvariantChars(mloc, ec).data()), ec);
2736 if (U_FAILURE(ec)) {
2737 errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
2739 if (!tokens.next(tok, ec)) goto error;
2740 if (!tokens.next(tok, ec)) goto error;
2741 if (!tokens.next(tok, ec)) goto error;
2744 } else if (mfmt == NULL) {
2745 errln("FAIL: " + where + "Loc \"" + mloc + "\": skip case using previous locale, no valid MeasureFormat");
2746 if (!tokens.next(tok, ec)) goto error;
2747 if (!tokens.next(tok, ec)) goto error;
2748 if (!tokens.next(tok, ec)) goto error;
2751 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2752 if (!tokens.next(currAmt, ec)) goto error;
2753 if (!tokens.next(str, ec)) goto error;
2754 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2755 if (assertSuccess("parseCurrencyAmount", ec)) {
2756 assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
2757 str, mfmt->format(n, out.remove(), ec));
2758 assertSuccess("format", ec);
2760 if (!tokens.next(currAmt, ec)) goto error;
2761 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2762 if (assertSuccess("parseCurrencyAmount", ec)) {
2765 mfmt->parseObject(str, m, ec);
2766 if (assertSuccess("parseCurrency", ec)) {
2767 assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
2770 errln("FAIL: source " + str);
2775 // perr: <pattern or '-'> <invalid string>
2776 errln("FAIL: Under construction");
2779 // pat: <pattern> <exp. toPattern, or '-' or 'err'>
2780 UnicodeString testpat;
2781 UnicodeString exppat;
2782 if (!tokens.next(testpat, ec)) goto error;
2783 if (!tokens.next(exppat, ec)) goto error;
2784 UBool err = exppat == "err";
2785 UBool existingPat = FALSE;
2786 if (testpat == "-") {
2788 errln("FAIL: " + where + "Invalid command \"pat: - err\"");
2794 if (exppat == "-") exppat = testpat;
2795 DecimalFormat* f = 0;
2796 UErrorCode ec2 = U_ZERO_ERROR;
2800 f = new DecimalFormat(testpat, ec2);
2802 if (U_SUCCESS(ec2)) {
2804 errln("FAIL: " + where + "Invalid pattern \"" + testpat +
2808 assertEquals(where + "\"" + testpat + "\".toPattern()",
2809 exppat, f->toPattern(pat2));
2813 logln("Ok: " + where + "Invalid pattern \"" + testpat +
2814 "\" failed: " + u_errorName(ec2));
2816 errln("FAIL: " + where + "Valid pattern \"" + testpat +
2817 "\" failed: " + u_errorName(ec2));
2820 if (!existingPat) delete f;
2823 errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
2830 if (U_SUCCESS(ec)) {
2831 errln("FAIL: Unexpected EOF");
2833 errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
2843 //----------------------------------------------------------------------
2845 //----------------------------------------------------------------------
2847 UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
2848 if (a.getType() == b.getType()) {
2852 if (a.getType() == Formattable::kLong) {
2853 if (b.getType() == Formattable::kInt64) {
2854 return a.getLong() == b.getLong();
2855 } else if (b.getType() == Formattable::kDouble) {
2856 return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
2858 } else if (a.getType() == Formattable::kDouble) {
2859 if (b.getType() == Formattable::kLong) {
2860 return a.getDouble() == (double) b.getLong();
2861 } else if (b.getType() == Formattable::kInt64) {
2862 return a.getDouble() == (double)b.getInt64();
2864 } else if (a.getType() == Formattable::kInt64) {
2865 if (b.getType() == Formattable::kLong) {
2866 return a.getInt64() == (int64_t)b.getLong();
2867 } else if (b.getType() == Formattable::kDouble) {
2868 return a.getInt64() == (int64_t)b.getDouble();
2874 void NumberFormatTest::expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2875 // Don't round-trip format test, since we explicitly do it
2876 expect_rbnf(fmt, n, str, FALSE);
2877 expect_rbnf(fmt, str, n);
2880 void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2881 // Don't round-trip format test, since we explicitly do it
2882 expect(fmt, n, str, FALSE);
2883 expect(fmt, str, n);
2886 void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
2887 const UnicodeString& exp,
2888 UErrorCode status) {
2889 if (fmt == NULL || U_FAILURE(status)) {
2890 dataerrln("FAIL: NumberFormat constructor");
2892 expect2(*fmt, n, exp);
2897 void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2898 UErrorCode status = U_ZERO_ERROR;
2900 fmt.parse(str, num, status);
2901 if (U_FAILURE(status)) {
2902 dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status));
2906 ((DecimalFormat*) &fmt)->toPattern(pat);
2907 if (equalValue(num, n)) {
2908 logln(UnicodeString("Ok \"") + str + "\" x " +
2912 dataerrln(UnicodeString("FAIL \"") + str + "\" x " +
2914 toString(num) + ", expected " + toString(n));
2918 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2919 UErrorCode status = U_ZERO_ERROR;
2921 fmt.parse(str, num, status);
2922 if (U_FAILURE(status)) {
2923 errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
2926 if (equalValue(num, n)) {
2927 logln(UnicodeString("Ok \"") + str + " = " +
2930 errln(UnicodeString("FAIL \"") + str + " = " +
2931 toString(num) + ", expected " + toString(n));
2935 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n,
2936 const UnicodeString& exp, UBool rt) {
2939 UErrorCode status = U_ZERO_ERROR;
2940 fmt.format(n, saw, pos, status);
2941 CHECK(status, "NumberFormat::format");
2943 logln(UnicodeString("Ok ") + toString(n) +
2945 escape(saw) + "\"");
2946 // We should be able to round-trip the formatted string =>
2947 // number => string (but not the other way around: number
2948 // => string => number2, might have number2 != number):
2951 fmt.parse(exp, n2, status);
2952 if (U_FAILURE(status)) {
2953 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
2957 fmt.format(n2, saw2, pos, status);
2958 CHECK(status, "NumberFormat::format");
2960 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2961 " => \"" + saw2 + "\"");
2965 errln(UnicodeString("FAIL ") + toString(n) +
2967 escape(saw) + "\", expected \"" + exp + "\"");
2971 void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
2972 const UnicodeString& exp, UBool rt) {
2975 UErrorCode status = U_ZERO_ERROR;
2976 fmt.format(n, saw, pos, status);
2977 CHECK(status, "NumberFormat::format");
2979 ((DecimalFormat*) &fmt)->toPattern(pat);
2981 logln(UnicodeString("Ok ") + toString(n) + " x " +
2982 escape(pat) + " = \"" +
2983 escape(saw) + "\"");
2984 // We should be able to round-trip the formatted string =>
2985 // number => string (but not the other way around: number
2986 // => string => number2, might have number2 != number):
2989 fmt.parse(exp, n2, status);
2990 if (U_FAILURE(status)) {
2991 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status));
2995 fmt.format(n2, saw2, pos, status);
2996 CHECK(status, "NumberFormat::format");
2998 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2999 " => \"" + saw2 + "\"");
3003 dataerrln(UnicodeString("FAIL ") + toString(n) + " x " +
3004 escape(pat) + " = \"" +
3005 escape(saw) + "\", expected \"" + exp + "\"");
3009 void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
3010 const UnicodeString& exp, UBool rt,
3011 UErrorCode status) {
3012 if (fmt == NULL || U_FAILURE(status)) {
3013 dataerrln("FAIL: NumberFormat constructor");
3015 expect(*fmt, n, exp, rt);
3020 void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale,
3021 double value, const UnicodeString& string) {
3022 UErrorCode ec = U_ZERO_ERROR;
3023 DecimalFormat& fmt = * (DecimalFormat*) &nf;
3024 const UChar DEFAULT_CURR[] = {45/*-*/,0};
3026 u_strcpy(curr, DEFAULT_CURR);
3027 if (*locale.getLanguage() != 0) {
3028 ucurr_forLocale(locale.getName(), curr, 4, &ec);
3029 assertSuccess("ucurr_forLocale", ec);
3030 fmt.setCurrency(curr, ec);
3031 assertSuccess("DecimalFormat::setCurrency", ec);
3032 fmt.setCurrency(curr); //Deprecated variant, for coverage only
3035 fmt.format(value, s);
3036 s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
3038 // Default display of the number yields "1234.5599999999999"
3039 // instead of "1234.56". Use a formatter to fix this.
3041 NumberFormat::createInstance(Locale::getUS(), ec);
3043 if (U_FAILURE(ec)) {
3044 // Oops; bad formatter. Use default op+= display.
3045 v = (UnicodeString)"" + value;
3047 f->setMaximumFractionDigits(4);
3048 f->setGroupingUsed(FALSE);
3049 f->format(value, v);
3054 logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
3056 errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
3057 ", expected " + prettify(string));
3061 void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
3065 logln(UnicodeString("Ok \"") + pat + "\"");
3067 errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
3071 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
3073 expectPad(fmt, pat, pos, 0, (UnicodeString)"");
3075 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
3076 int32_t pos, int32_t width, UChar pad) {
3077 expectPad(fmt, pat, pos, width, UnicodeString(pad));
3079 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
3080 int32_t pos, int32_t width, const UnicodeString& pad) {
3081 int32_t apos = 0, awidth = 0;
3082 UnicodeString apadStr;
3083 UErrorCode status = U_ZERO_ERROR;
3084 fmt.applyPattern(pat, status);
3085 if (U_SUCCESS(status)) {
3086 apos = fmt.getPadPosition();
3087 awidth = fmt.getFormatWidth();
3088 apadStr=fmt.getPadCharacterString();
3094 if (apos == pos && awidth == width && apadStr == pad) {
3095 UnicodeString infoStr;
3096 if (pos == ILLEGAL) {
3097 infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
3099 logln(UnicodeString("Ok \"") + pat + "\" pos=" + apos + infoStr);
3101 errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
3102 " width=" + awidth + " pad=" + apadStr +
3103 ", expected " + pos + " " + width + " " + pad);
3107 // This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale - FIXME
3108 void NumberFormatTest::TestCompatibleCurrencies() {
3110 static const UChar JPY[] = {0x4A, 0x50, 0x59, 0};
3111 static const UChar CNY[] = {0x43, 0x4E, 0x59, 0};
3112 UErrorCode status = U_ZERO_ERROR;
3113 LocalPointer<NumberFormat> fmt(
3114 NumberFormat::createCurrencyInstance(Locale::getUS(), status));
3115 if (U_FAILURE(status)) {
3116 errln("Could not create number format instance.");
3119 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
3120 expectParseCurrency(*fmt, JPY, 1235, "\\u00A51,235");
3121 logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__);
3122 expectParseCurrency(*fmt, JPY, 1235, "\\uFFE51,235");
3123 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
3124 expectParseCurrency(*fmt, CNY, 1235, "CN\\u00A51,235");
3126 LocalPointer<NumberFormat> fmtTW(
3127 NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
3129 logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__);
3130 expectParseCurrency(*fmtTW, CNY, 1235, "\\u00A51,235");
3131 logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__);
3132 expectParseCurrency(*fmtTW, CNY, 1235, "\\uFFE51,235");
3134 LocalPointer<NumberFormat> fmtJP(
3135 NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
3137 logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__);
3138 expectParseCurrency(*fmtJP, JPY, 1235, "\\u00A51,235");
3139 logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
3140 expectParseCurrency(*fmtJP, JPY, 1235, "\\uFFE51,235");
3146 void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text) {
3148 UnicodeString utext = ctou(text);
3149 LocalPointer<CurrencyAmount> currencyAmount(fmt.parseCurrency(utext, ppos));
3150 if (!ppos.getIndex()) {
3151 errln(UnicodeString("Parse of ") + utext + " should have succeeded.");
3154 UErrorCode status = U_ZERO_ERROR;
3157 sprintf(theInfo, "For locale %s, string \"%s\", currency ",
3158 fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(),
3160 u_austrcpy(theInfo+uprv_strlen(theInfo), currency);
3162 char theOperation[100];
3164 uprv_strcpy(theOperation, theInfo);
3165 uprv_strcat(theOperation, ", check amount:");
3166 assertTrue(theOperation, amount == currencyAmount->getNumber().getDouble(status));
3168 uprv_strcpy(theOperation, theInfo);
3169 uprv_strcat(theOperation, ", check currency:");
3170 assertEquals(theOperation, currency, currencyAmount->getISOCurrency());
3174 void NumberFormatTest::TestJB3832(){
3175 const char* localeID = "pt_PT@currency=PTE";
3176 Locale loc(localeID);
3177 UErrorCode status = U_ZERO_ERROR;
3178 UnicodeString expected(CharsToUnicodeString("1,150$50\\u00A0\\u200B")); // per cldrbug 7670
3180 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
3181 if(U_FAILURE(status)){
3182 dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status));
3185 currencyFmt->format(1150.50, s);
3187 errln(UnicodeString("FAIL: Expected: ")+expected
3188 + UnicodeString(" Got: ") + s
3189 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
3191 if (U_FAILURE(status)){
3192 errln("FAIL: Status %s", u_errorName(status));
3197 void NumberFormatTest::TestHost()
3199 #if U_PLATFORM_USES_ONLY_WIN32_API
3200 Win32NumberTest::testLocales(this);
3202 Locale loc("en_US@compat=host");
3203 for (UNumberFormatStyle k = UNUM_DECIMAL;
3204 k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) {
3205 UErrorCode status = U_ZERO_ERROR;
3206 LocalPointer<NumberFormat> full(NumberFormat::createInstance(loc, k, status));
3207 if (!NumberFormat::isStyleSupported(k)) {
3208 if (status != U_UNSUPPORTED_ERROR) {
3209 errln("FAIL: expected style %d to be unsupported - %s",
3210 k, u_errorName(status));
3214 if (full.isNull() || U_FAILURE(status)) {
3215 dataerrln("FAIL: Can't create number instance of style %d for host - %s",
3216 k, u_errorName(status));
3219 UnicodeString result1;
3220 Formattable number(10.00);
3221 full->format(number, result1, status);
3222 if (U_FAILURE(status)) {
3223 errln("FAIL: Can't format for host");
3226 Formattable formattable;
3227 full->parse(result1, formattable, status);
3228 if (U_FAILURE(status)) {
3229 errln("FAIL: Can't parse for host");
3235 void NumberFormatTest::TestHostClone()
3238 Verify that a cloned formatter gives the same results
3239 and is useable after the original has been deleted.
3241 // This is mainly important on Windows.
3242 UErrorCode status = U_ZERO_ERROR;
3243 Locale loc("en_US@compat=host");
3244 UDate now = Calendar::getNow();
3245 NumberFormat *full = NumberFormat::createInstance(loc, status);
3246 if (full == NULL || U_FAILURE(status)) {
3247 dataerrln("FAIL: Can't create Relative date instance - %s", u_errorName(status));
3250 UnicodeString result1;
3251 full->format(now, result1, status);
3252 Format *fullClone = full->clone();
3256 UnicodeString result2;
3257 fullClone->format(now, result2, status);
3258 if (U_FAILURE(status)) {
3259 errln("FAIL: format failure.");
3261 if (result1 != result2) {
3262 errln("FAIL: Clone returned different result from non-clone.");
3267 void NumberFormatTest::TestCurrencyFormat()
3269 // This test is here to increase code coverage.
3270 UErrorCode status = U_ZERO_ERROR;
3271 MeasureFormat *cloneObj;
3273 Formattable toFormat, result;
3274 static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
3276 Locale saveDefaultLocale = Locale::getDefault();
3277 Locale::setDefault( Locale::getUK(), status );
3278 if (U_FAILURE(status)) {
3279 errln("couldn't set default Locale!");
3283 MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
3284 Locale::setDefault( saveDefaultLocale, status );
3285 if (U_FAILURE(status)){
3286 dataerrln("FAIL: Status %s", u_errorName(status));
3289 cloneObj = (MeasureFormat *)measureObj->clone();
3290 if (cloneObj == NULL) {
3291 errln("Clone doesn't work");
3294 toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status));
3295 measureObj->format(toFormat, str, status);
3296 measureObj->parseObject(str, result, status);
3297 if (U_FAILURE(status)){
3298 errln("FAIL: Status %s", u_errorName(status));
3300 if (result != toFormat) {
3301 errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
3303 status = U_ZERO_ERROR;
3305 cloneObj->format(toFormat, str, status);
3306 cloneObj->parseObject(str, result, status);
3307 if (U_FAILURE(status)){
3308 errln("FAIL: Status %s", u_errorName(status));
3310 if (result != toFormat) {
3311 errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
3313 if (*measureObj != *cloneObj) {
3314 errln("Cloned object is not equal to the original object");
3319 status = U_USELESS_COLLATOR_ERROR;
3320 if (MeasureFormat::createCurrencyFormat(status) != NULL) {
3321 errln("createCurrencyFormat should have returned NULL.");
3325 /* Port of ICU4J rounding test. */
3326 void NumberFormatTest::TestRounding() {
3327 UErrorCode status = U_ZERO_ERROR;
3328 DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
3330 if (U_FAILURE(status)) {
3331 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
3335 int roundingIncrements[]={1, 2, 5, 20, 50, 100};
3336 int testValues[]={0, 300};
3338 for (int j=0; j<2; j++) {
3339 for (int mode=DecimalFormat::kRoundUp;mode<DecimalFormat::kRoundHalfEven;mode++) {
3340 df->setRoundingMode((DecimalFormat::ERoundingMode)mode);
3341 for (int increment=0; increment<6; increment++) {
3342 double base=testValues[j];
3343 double rInc=roundingIncrements[increment];
3344 checkRounding(df, base, 20, rInc);
3345 rInc=1.000000000/rInc;
3346 checkRounding(df, base, 20, rInc);
3353 void NumberFormatTest::TestRoundingPattern() {
3354 UErrorCode status = U_ZERO_ERROR;
3356 UnicodeString pattern;
3358 UnicodeString expected;
3360 { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" },
3361 { (UnicodeString)"#50", 1230, (UnicodeString)"1250" }
3363 int32_t numOfTests = UPRV_LENGTHOF(tests);
3364 UnicodeString result;
3366 DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
3367 if (U_FAILURE(status)) {
3368 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
3372 for (int32_t i = 0; i < numOfTests; i++) {
3375 df->applyPattern(tests[i].pattern, status);
3376 if (U_FAILURE(status)) {
3377 errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status));
3380 df->format(tests[i].testCase, result);
3382 if (result != tests[i].expected) {
3383 errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
3390 void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) {
3391 df->setRoundingIncrement(increment);
3392 double lastParsed=INT32_MIN; //Intger.MIN_VALUE
3393 for (int i=-iterations; i<=iterations;i++) {
3394 double iValue=base+(increment*(i*0.1));
3395 double smallIncrement=0.00000001;
3397 smallIncrement*=iValue;
3399 //we not only test the value, but some values in a small range around it
3400 lastParsed=checkRound(df, iValue-smallIncrement, lastParsed);
3401 lastParsed=checkRound(df, iValue, lastParsed);
3402 lastParsed=checkRound(df, iValue+smallIncrement, lastParsed);
3406 double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) {
3407 UErrorCode status=U_ZERO_ERROR;
3408 UnicodeString formattedDecimal;
3411 df->format(iValue, formattedDecimal, status);
3413 if (U_FAILURE(status)) {
3414 errln("Error formatting number.");
3417 df->parse(formattedDecimal, result, status);
3419 if (U_FAILURE(status)) {
3420 errln("Error parsing number.");
3423 parsed=result.getDouble();
3425 if (lastParsed>parsed) {
3426 errln("Rounding wrong direction! %d > %d", lastParsed, parsed);
3432 void NumberFormatTest::TestNonpositiveMultiplier() {
3433 UErrorCode status = U_ZERO_ERROR;
3434 DecimalFormatSymbols US(Locale::getUS(), status);
3435 CHECK(status, "DecimalFormatSymbols constructor");
3436 DecimalFormat df(UnicodeString("0"), US, status);
3437 CHECK(status, "DecimalFormat(0)");
3439 // test zero multiplier
3441 int32_t mult = df.getMultiplier();
3442 df.setMultiplier(0);
3443 if (df.getMultiplier() != mult) {
3444 errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
3447 // test negative multiplier
3449 df.setMultiplier(-1);
3450 if (df.getMultiplier() != -1) {
3451 errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
3455 expect(df, "1122.123", -1122.123);
3456 expect(df, "-1122.123", 1122.123);
3457 expect(df, "1.2", -1.2);
3458 expect(df, "-1.2", 1.2);
3460 // Note: the tests with the final parameter of FALSE will not round trip.
3461 // The initial numeric value will format correctly, after the multiplier.
3462 // Parsing the formatted text will be out-of-range for an int64, however.
3463 // The expect() function could be modified to detect this and fall back
3464 // to looking at the decimal parsed value, but it doesn't.
3465 expect(df, U_INT64_MIN, "9223372036854775808", FALSE);
3466 expect(df, U_INT64_MIN+1, "9223372036854775807");
3467 expect(df, (int64_t)-123, "123");
3468 expect(df, (int64_t)123, "-123");
3469 expect(df, U_INT64_MAX-1, "-9223372036854775806");
3470 expect(df, U_INT64_MAX, "-9223372036854775807");
3472 df.setMultiplier(-2);
3473 expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806");
3474 expect(df, -(U_INT64_MIN/2), "-9223372036854775808");
3475 expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE);
3477 df.setMultiplier(-7);
3478 expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE);
3479 expect(df, -(U_INT64_MAX/7), "9223372036854775807");
3480 expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800");
3482 // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
3483 // (right now the big numbers get turned into doubles and lose tons of accuracy)
3484 //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
3485 //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
3486 //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
3487 //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
3489 // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
3490 //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3491 //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3492 //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3493 //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3497 const char * stringToParse;
3501 } TestSpaceParsingItem;
3504 NumberFormatTest::TestSpaceParsing() {
3506 // the string to be parsed, parsed position, parsed error index
3507 const TestSpaceParsingItem DATA[] = {
3508 // TOTO: Update the following TODOs, some may be handled now
3509 {"$124", 4, -1, FALSE},
3510 {"$124 $124", 4, -1, FALSE},
3511 {"$124 ", 4, -1, FALSE},
3512 //{"$ 124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
3513 //{"$\\u00A0124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
3514 {"$ 124 ", 0, 1, FALSE}, // errorIndex used to be 0, now 1 (better)
3515 {"$\\u00A0124 ", 0, 1, FALSE}, // errorIndex used to be 0, now 1 (better)
3516 {" $ 124 ", 0, 0, FALSE}, // TODO: need to handle space correctly
3517 {"124$", 0, 3, FALSE}, // TODO: need to handle space correctly
3518 // {"124 $", 5, -1, FALSE}, // TODO: OK or not, need currency spacing rule
3519 {"124 $", 0, 3, FALSE},
3520 {"$124", 4, -1, TRUE},
3521 {"$124 $124", 4, -1, TRUE},
3522 {"$124 ", 4, -1, TRUE},
3523 {"$ 124 ", 5, -1, TRUE},
3524 {"$\\u00A0124 ", 5, -1, TRUE},
3525 {" $ 124 ", 6, -1, TRUE},
3526 //{"124$", 4, -1, TRUE}, // TODO: need to handle trailing currency correctly
3527 {"124$", 3, -1, TRUE},
3528 //{"124 $", 5, -1, TRUE}, // TODO: OK or not, need currency spacing rule
3529 {"124 $", 4, -1, TRUE},
3531 UErrorCode status = U_ZERO_ERROR;
3532 Locale locale("en_US");
3533 NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status);
3535 if (U_FAILURE(status)) {
3539 for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
3540 ParsePosition parsePosition(0);
3541 UnicodeString stringToBeParsed = ctou(DATA[i].stringToParse);
3542 int parsedPosition = DATA[i].parsedPos;
3543 int errorIndex = DATA[i].errorIndex;
3544 foo->setLenient(DATA[i].lenient);
3546 foo->parse(stringToBeParsed, result, parsePosition);
3547 if (parsePosition.getIndex() != parsedPosition ||
3548 parsePosition.getErrorIndex() != errorIndex) {
3549 errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
3551 if (parsePosition.getErrorIndex() == -1 &&
3552 result.getType() == Formattable::kLong &&
3553 result.getLong() != 124) {
3554 errln("FAILED parse " + stringToBeParsed + "; wrong number, expect: 124, got " + result.getLong());
3561 * Test using various numbering systems and numbering system keyword.
3564 const char *localeName;
3567 const char *expectedResult;
3568 } TestNumberingSystemItem;
3570 void NumberFormatTest::TestNumberingSystems() {
3572 const TestNumberingSystemItem DATA[] = {
3573 { "en_US@numbers=thai", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
3574 { "en_US@numbers=hebr", 5678.0, TRUE, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
3575 { "en_US@numbers=arabext", 1234.567, FALSE, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
3576 { "ar_EG", 1234.567, FALSE, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
3577 { "th_TH@numbers=traditional", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
3578 { "ar_MA", 1234.567, FALSE, "1.234,567" },
3579 { "en_US@numbers=hanidec", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3580 { "ta_IN@numbers=native", 1234.567, FALSE, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
3581 { "ta_IN@numbers=traditional", 1235.0, TRUE, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
3582 { "ta_IN@numbers=finance", 1234.567, FALSE, "1,234.567" }, // fall back to default per TR35
3583 { "zh_TW@numbers=native", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3584 { "zh_TW@numbers=traditional", 1234.567, TRUE, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
3585 { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
3586 { NULL, 0, FALSE, NULL }
3591 const TestNumberingSystemItem *item;
3592 for (item = DATA; item->localeName != NULL; item++) {
3594 Locale loc = Locale::createFromName(item->localeName);
3596 NumberFormat *origFmt = NumberFormat::createInstance(loc,ec);
3597 if (U_FAILURE(ec)) {
3598 dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec));
3601 // Clone to test ticket #10682
3602 NumberFormat *fmt = (NumberFormat *) origFmt->clone();
3607 expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3609 expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3615 // Test bogus keyword value
3617 Locale loc4 = Locale::createFromName("en_US@numbers=foobar");
3618 NumberFormat* fmt4= NumberFormat::createInstance(loc4, ec);
3619 if ( ec != U_UNSUPPORTED_ERROR ) {
3620 errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
3625 NumberingSystem *ns = NumberingSystem::createInstance(ec);
3626 if (U_FAILURE(ec)) {
3627 dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec));
3631 ns->getDynamicClassID();
3632 ns->getStaticClassID();
3634 errln("FAIL: getInstance() returned NULL.");
3637 NumberingSystem *ns1 = new NumberingSystem(*ns);
3639 errln("FAIL: NumberSystem copy constructor returned NULL.");
3649 NumberFormatTest::TestMultiCurrencySign() {
3650 const char* DATA[][6] = {
3651 // the fields in the following test are:
3653 // currency pattern (with negative pattern),
3654 // currency number to be formatted,
3655 // currency format using currency symbol name, such as "$" for USD,
3656 // currency format using currency ISO name, such as "USD",
3657 // currency format using plural name, such as "US dollars".
3659 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
3660 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
3661 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollars1.00"},
3663 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\uFFE51,234.56", "CNY1,234.56", "\\u4EBA\\u6C11\\u5E011,234.56"},
3664 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\uFFE51,234.56)", "(CNY1,234.56)", "(\\u4EBA\\u6C11\\u5E011,234.56)"},
3665 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\uFFE51.00", "CNY1.00", "\\u4EBA\\u6C11\\u5E011.00"}
3668 const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0};
3669 UnicodeString doubleCurrencyStr(doubleCurrencySign);
3670 const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
3671 UnicodeString tripleCurrencyStr(tripleCurrencySign);
3673 for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
3674 const char* locale = DATA[i][0];
3675 UnicodeString pat = ctou(DATA[i][1]);
3676 double numberToBeFormat = atof(DATA[i][2]);
3677 UErrorCode status = U_ZERO_ERROR;
3678 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale(locale), status);
3679 if (U_FAILURE(status)) {
3683 for (int j=1; j<=3; ++j) {
3684 // j represents the number of currency sign in the pattern.
3686 pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr);
3687 } else if (j == 3) {
3688 pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr);
3691 DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status);
3692 if (U_FAILURE(status)) {
3693 errln("FAILED init DecimalFormat ");
3698 ((NumberFormat*) fmt)->format(numberToBeFormat, s);
3699 // DATA[i][3] is the currency format result using a
3700 // single currency sign.
3701 // DATA[i][4] is the currency format result using
3702 // double currency sign.
3703 // DATA[i][5] is the currency format result using
3704 // triple currency sign.
3705 // DATA[i][j+2] is the currency format result using
3706 // 'j' number of currency sign.
3707 UnicodeString currencyFormatResult = ctou(DATA[i][2+j]);
3708 if (s.compare(currencyFormatResult)) {
3709 errln("FAIL format: Expected " + currencyFormatResult + "; Got " + s);
3711 // mix style parsing
3712 for (int k=3; k<=5; ++k) {
3713 // DATA[i][3] is the currency format result using a
3714 // single currency sign.
3715 // DATA[i][4] is the currency format result using
3716 // double currency sign.
3717 // DATA[i][5] is the currency format result using
3718 // triple currency sign.
3719 UnicodeString oneCurrencyFormat = ctou(DATA[i][k]);
3720 UErrorCode status = U_ZERO_ERROR;
3721 Formattable parseRes;
3722 fmt->parse(oneCurrencyFormat, parseRes, status);
3723 if (U_FAILURE(status) ||
3724 (parseRes.getType() == Formattable::kDouble &&
3725 parseRes.getDouble() != numberToBeFormat) ||
3726 (parseRes.getType() == Formattable::kLong &&
3727 parseRes.getLong() != numberToBeFormat)) {
3728 errln("FAILED parse " + oneCurrencyFormat + "; (i, j, k): " +
3729 i + ", " + j + ", " + k);
3740 NumberFormatTest::TestCurrencyFormatForMixParsing() {
3741 UErrorCode status = U_ZERO_ERROR;
3742 MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status);
3743 if (U_FAILURE(status)) {
3747 const char* formats[] = {
3748 "$1,234.56", // string to be parsed
3750 "US dollars1,234.56",
3751 "1,234.56 US dollars"
3753 const CurrencyAmount* curramt = NULL;
3754 for (uint32_t i = 0; i < UPRV_LENGTHOF(formats); ++i) {
3755 UnicodeString stringToBeParsed = ctou(formats[i]);
3756 logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed);
3758 UErrorCode status = U_ZERO_ERROR;
3759 curFmt->parseObject(stringToBeParsed, result, status);
3760 if (U_FAILURE(status)) {
3761 errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status));
3762 } else if (result.getType() != Formattable::kObject ||
3763 (curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL ||
3764 curramt->getNumber().getDouble() != 1234.56 ||
3765 UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD)
3767 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
3768 if (curramt->getNumber().getDouble() != 1234.56) {
3769 errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble());
3771 if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
3772 errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
3781 NumberFormatTest::TestDecimalFormatCurrencyParse() {
3783 UErrorCode status = U_ZERO_ERROR;
3784 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status);
3785 if (U_FAILURE(status)) {
3790 UChar currency = 0x00A4;
3791 // "\xA4#,##0.00;-\xA4#,##0.00"
3792 pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
3793 DecimalFormat* fmt = new DecimalFormat(pat, sym, status);
3794 if (U_FAILURE(status)) {
3796 errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3799 const char* DATA[][2] = {
3801 // string to be parsed, the parsed result (number)
3804 {"1.00 US dollar", "1"},
3805 {"$1,234.56", "1234.56"},
3806 {"USD1,234.56", "1234.56"},
3807 {"1,234.56 US dollar", "1234.56"},
3809 for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
3810 UnicodeString stringToBeParsed = ctou(DATA[i][0]);
3811 double parsedResult = atof(DATA[i][1]);
3812 UErrorCode status = U_ZERO_ERROR;
3814 fmt->parse(stringToBeParsed, result, status);
3815 if (U_FAILURE(status) ||
3816 (result.getType() == Formattable::kDouble &&
3817 result.getDouble() != parsedResult) ||
3818 (result.getType() == Formattable::kLong &&
3819 result.getLong() != parsedResult)) {
3820 errln((UnicodeString)"FAIL parse: Expected " + parsedResult);
3828 NumberFormatTest::TestCurrencyIsoPluralFormat() {
3829 static const char* DATA[][6] = {
3832 // currency amount to be formatted,
3833 // currency ISO code to be formatted,
3834 // format result using CURRENCYSTYLE,
3835 // format result using ISOCURRENCYSTYLE,
3836 // format result using PLURALCURRENCYSTYLE,
3838 {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollars"},
3839 {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},
3840 {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD1,234.56", "-1,234.56 US dollars"},
3841 {"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00\\u7F8E\\u5143"},
3842 {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56\\u7F8E\\u5143"},
3843 {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY1.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3844 {"zh_CN", "1234.56", "CNY", "\\uFFE51,234.56", "CNY1,234.56", "1,234.56\\u4EBA\\u6C11\\u5E01"},
3845 {"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"},
3846 {"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"},
3847 {"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"},
3848 // test locale without currency information
3849 {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3850 // test choice format
3851 {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"},
3853 static const UNumberFormatStyle currencyStyles[] = {
3856 UNUM_CURRENCY_PLURAL
3859 for (int32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
3860 for (int32_t kIndex = 0; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
3861 UNumberFormatStyle k = currencyStyles[kIndex];
3862 const char* localeString = DATA[i][0];
3863 double numberToBeFormat = atof(DATA[i][1]);
3864 const char* currencyISOCode = DATA[i][2];
3865 Locale locale(localeString);
3866 UErrorCode status = U_ZERO_ERROR;
3867 NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3868 if (U_FAILURE(status)) {
3870 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3873 UChar currencyCode[4];
3874 u_charsToUChars(currencyISOCode, currencyCode, 4);
3875 numFmt->setCurrency(currencyCode, status);
3876 if (U_FAILURE(status)) {
3878 errln((UnicodeString)"can not set currency:" + currencyISOCode);
3882 UnicodeString strBuf;
3883 numFmt->format(numberToBeFormat, strBuf);
3884 int resultDataIndex = 3 + kIndex;
3885 // DATA[i][resultDataIndex] is the currency format result
3886 // using 'k' currency style.
3887 UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
3888 if (strBuf.compare(formatResult)) {
3889 errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
3891 // test parsing, and test parsing for all currency formats.
3892 for (int j = 3; j < 6; ++j) {
3893 // DATA[i][3] is the currency format result using
3894 // CURRENCYSTYLE formatter.
3895 // DATA[i][4] is the currency format result using
3896 // ISOCURRENCYSTYLE formatter.
3897 // DATA[i][5] is the currency format result using
3898 // PLURALCURRENCYSTYLE formatter.
3899 UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
3900 UErrorCode status = U_ZERO_ERROR;
3901 Formattable parseResult;
3902 numFmt->parse(oneCurrencyFormatResult, parseResult, status);
3903 if (U_FAILURE(status) ||
3904 (parseResult.getType() == Formattable::kDouble &&
3905 parseResult.getDouble() != numberToBeFormat) ||
3906 (parseResult.getType() == Formattable::kLong &&
3907 parseResult.getLong() != numberToBeFormat)) {
3908 errln((UnicodeString)"FAIL: getCurrencyFormat of locale " +
3909 localeString + " failed roundtripping the number");
3910 if (parseResult.getType() == Formattable::kDouble) {
3911 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble());
3913 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
3923 NumberFormatTest::TestCurrencyParsing() {
3924 static const char* DATA[][6] = {
3927 // currency amount to be formatted,
3928 // currency ISO code to be formatted,
3929 // format result using CURRENCYSTYLE,
3930 // format result using ISOCURRENCYSTYLE,
3931 // format result using PLURALCURRENCYSTYLE,
3932 {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
3933 {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
3934 {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
3935 {"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"},
3936 {"fa_CA", "1", "USD", "\\u06f1\\u066b\\u06f0\\u06f0\\u00a0\\u061c$", "\\u06f1\\u066b\\u06f0\\u06f0\\u00a0\\u061cUSD", "\\u06f1\\u066b\\u06f0\\u06f0 \\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627"},
3937 {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
3938 {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 Ameri\\u010dki dolar"},
3939 {"id_ID", "1", "USD", "US$1,00", "USD1,00", "1,00 Dolar Amerika Serikat"},
3940 {"it_IT", "1", "USD", "1,00\\u00a0US$", "1,00\\u00a0USD", "1,00 Dollaro Statunitense"},
3941 {"ko_KR", "1", "USD", "US$1.00", "USD1.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
3942 {"ja_JP", "1", "USD", "$1.00", "USD1.00", "1.00\\u7c73\\u30c9\\u30eb"},
3943 {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY01.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3944 {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3945 {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3946 {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00 \\u65e5\\u5713"},
3947 {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"},
3948 {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"},
3949 {"ru_RU", "1", "RUB", "1,00\\u00A0\\u20BD", "1,00\\u00A0RUB", "1,00 \\u0420\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"}
3951 static const UNumberFormatStyle currencyStyles[] = {
3954 UNUM_CURRENCY_PLURAL
3956 static const char* currencyStyleNames[] = {
3958 "UNUM_CURRENCY_ISO",
3959 "UNUM_CURRENCY_PLURAL"
3962 #ifdef NUMFMTST_CACHE_DEBUG
3965 printf("loop: %d\n", deadloop++);
3967 for (uint32_t i=0; i< UPRV_LENGTHOF(DATA); ++i) { /* i = test case # - should be i=0*/
3968 for (int32_t kIndex = 2; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
3969 UNumberFormatStyle k = currencyStyles[kIndex]; /* k = style */
3970 const char* localeString = DATA[i][0];
3971 double numberToBeFormat = atof(DATA[i][1]);
3972 const char* currencyISOCode = DATA[i][2];
3973 Locale locale(localeString);
3974 UErrorCode status = U_ZERO_ERROR;
3975 NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3976 logln("#%d NumberFormat(%s, %s) Currency=%s\n",
3977 i, localeString, currencyStyleNames[kIndex],
3980 if (U_FAILURE(status)) {
3982 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3985 UChar currencyCode[4];
3986 u_charsToUChars(currencyISOCode, currencyCode, 4);
3987 numFmt->setCurrency(currencyCode, status);
3988 if (U_FAILURE(status)) {
3990 errln((UnicodeString)"can not set currency:" + currencyISOCode);
3994 UnicodeString strBuf;
3995 numFmt->format(numberToBeFormat, strBuf);
3997 int resultDataIndex = 3 + kIndex;
3998 // DATA[i][resultDataIndex] is the currency format result
3999 // using 'k' currency style.
4000 UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
4001 if (strBuf.compare(formatResult)) {
4002 errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
4005 // test parsing, and test parsing for all currency formats.
4006 for (int j = 3; j < 6; ++j) {
4007 // DATA[i][3] is the currency format result using
4008 // CURRENCYSTYLE formatter.
4009 // DATA[i][4] is the currency format result using
4010 // ISOCURRENCYSTYLE formatter.
4011 // DATA[i][5] is the currency format result using
4012 // PLURALCURRENCYSTYLE formatter.
4013 UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
4014 UErrorCode status = U_ZERO_ERROR;
4015 Formattable parseResult;
4016 logln("parse(%s)", DATA[i][j]);
4017 numFmt->parse(oneCurrencyFormatResult, parseResult, status);
4018 if (U_FAILURE(status) ||
4019 (parseResult.getType() == Formattable::kDouble &&
4020 parseResult.getDouble() != numberToBeFormat) ||
4021 (parseResult.getType() == Formattable::kLong &&
4022 parseResult.getLong() != numberToBeFormat)) {
4023 errln((UnicodeString)"FAIL: NumberFormat(" + localeString +", " + currencyStyleNames[kIndex] +
4024 "), Currency="+currencyISOCode+", parse("+DATA[i][j]+") returned error " + (UnicodeString)u_errorName(status)+". Testcase: data[" + i + "][" + currencyStyleNames[j-3] +"="+j+"]");
4025 if (parseResult.getType() == Formattable::kDouble) {
4026 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (double): " +parseResult.getDouble());
4028 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (long): " +parseResult.getLong());
4030 errln((UnicodeString)" round-trip would be: " + strBuf);
4036 #ifdef NUMFMTST_CACHE_DEBUG
4043 NumberFormatTest::TestParseCurrencyInUCurr() {
4044 const char* DATA[] = {
4045 "1.00 US DOLLAR", // case in-sensitive
4082 "Afghan Afghani (1927\\u20132002)1.00",
4083 "Afghan afghani (1927\\u20132002)1.00",
4084 "Afghan Afghani1.00",
4085 "Afghan Afghanis1.00",
4088 "Albanian lek\\u00eb1.00",
4089 "Algerian Dinar1.00",
4090 "Algerian dinar1.00",
4091 "Algerian dinars1.00",
4092 "Andorran Peseta1.00",
4093 "Andorran peseta1.00",
4094 "Andorran pesetas1.00",
4095 "Angolan Kwanza (1977\\u20131991)1.00",
4096 "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
4097 "Angolan Kwanza1.00",
4098 "Angolan New Kwanza (1990\\u20132000)1.00",
4099 "Angolan kwanza (1977\\u20131991)1.00",
4100 "Angolan readjusted kwanza (1995\\u20131999)1.00",
4101 "Angolan kwanza1.00",
4102 "Angolan kwanzas (1977\\u20131991)1.00",
4103 "Angolan readjusted kwanzas (1995\\u20131999)1.00",
4104 "Angolan kwanzas1.00",
4105 "Angolan new kwanza (1990\\u20132000)1.00",
4106 "Angolan new kwanzas (1990\\u20132000)1.00",
4107 "Argentine Austral1.00",
4108 "Argentine Peso (1983\\u20131985)1.00",
4109 "Argentine Peso1.00",
4110 "Argentine austral1.00",
4111 "Argentine australs1.00",
4112 "Argentine peso (1983\\u20131985)1.00",
4113 "Argentine peso1.00",
4114 "Argentine pesos (1983\\u20131985)1.00",
4115 "Argentine pesos1.00",
4116 "Armenian Dram1.00",
4117 "Armenian dram1.00",
4118 "Armenian drams1.00",
4119 "Aruban Florin1.00",
4120 "Aruban florin1.00",
4121 "Australian Dollar1.00",
4122 "Australian dollar1.00",
4123 "Australian dollars1.00",
4124 "Austrian Schilling1.00",
4125 "Austrian schilling1.00",
4126 "Austrian schillings1.00",
4127 "Azerbaijani Manat (1993\\u20132006)1.00",
4128 "Azerbaijani Manat1.00",
4129 "Azerbaijani manat (1993\\u20132006)1.00",
4130 "Azerbaijani manat1.00",
4131 "Azerbaijani manats (1993\\u20132006)1.00",
4132 "Azerbaijani manats1.00",
4176 "Bahamian Dollar1.00",
4177 "Bahamian dollar1.00",
4178 "Bahamian dollars1.00",
4179 "Bahraini Dinar1.00",
4180 "Bahraini dinar1.00",
4181 "Bahraini dinars1.00",
4182 "Bangladeshi Taka1.00",
4183 "Bangladeshi taka1.00",
4184 "Bangladeshi takas1.00",
4185 "Barbadian Dollar1.00",
4186 "Barbadian dollar1.00",
4187 "Barbadian dollars1.00",
4188 "Belarusian Ruble (1994\\u20131999)1.00",
4189 "Belarusian Ruble1.00",
4190 "Belarusian ruble (1994\\u20131999)1.00",
4191 "Belarusian rubles (1994\\u20131999)1.00",
4192 "Belarusian ruble1.00",
4193 "Belarusian rubles1.00",
4194 "Belgian Franc (convertible)1.00",
4195 "Belgian Franc (financial)1.00",
4196 "Belgian Franc1.00",
4197 "Belgian franc (convertible)1.00",
4198 "Belgian franc (financial)1.00",
4199 "Belgian franc1.00",
4200 "Belgian francs (convertible)1.00",
4201 "Belgian francs (financial)1.00",
4202 "Belgian francs1.00",
4203 "Belize Dollar1.00",
4204 "Belize dollar1.00",
4205 "Belize dollars1.00",
4206 "Bermudan Dollar1.00",
4207 "Bermudan dollar1.00",
4208 "Bermudan dollars1.00",
4209 "Bhutanese Ngultrum1.00",
4210 "Bhutanese ngultrum1.00",
4211 "Bhutanese ngultrums1.00",
4212 "Bolivian Mvdol1.00",
4213 "Bolivian Peso1.00",
4214 "Bolivian mvdol1.00",
4215 "Bolivian mvdols1.00",
4216 "Bolivian peso1.00",
4217 "Bolivian pesos1.00",
4218 "Bolivian Boliviano1.00",
4219 "Bolivian Boliviano1.00",
4220 "Bolivian Bolivianos1.00",
4221 "Bosnia-Herzegovina Convertible Mark1.00",
4222 "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
4223 "Bosnia-Herzegovina convertible mark1.00",
4224 "Bosnia-Herzegovina convertible marks1.00",
4225 "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
4226 "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
4227 "Botswanan Pula1.00",
4228 "Botswanan pula1.00",
4229 "Botswanan pulas1.00",
4230 "Brazilian New Cruzado (1989\\u20131990)1.00",
4231 "Brazilian Cruzado (1986\\u20131989)1.00",
4232 "Brazilian Cruzeiro (1990\\u20131993)1.00",
4233 "Brazilian New Cruzeiro (1967\\u20131986)1.00",
4234 "Brazilian Cruzeiro (1993\\u20131994)1.00",
4235 "Brazilian Real1.00",
4236 "Brazilian new cruzado (1989\\u20131990)1.00",
4237 "Brazilian new cruzados (1989\\u20131990)1.00",
4238 "Brazilian cruzado (1986\\u20131989)1.00",
4239 "Brazilian cruzados (1986\\u20131989)1.00",
4240 "Brazilian cruzeiro (1990\\u20131993)1.00",
4241 "Brazilian new cruzeiro (1967\\u20131986)1.00",
4242 "Brazilian cruzeiro (1993\\u20131994)1.00",
4243 "Brazilian cruzeiros (1990\\u20131993)1.00",
4244 "Brazilian new cruzeiros (1967\\u20131986)1.00",
4245 "Brazilian cruzeiros (1993\\u20131994)1.00",
4246 "Brazilian real1.00",
4247 "Brazilian reals1.00",
4248 "British Pound1.00",
4249 "British pound1.00",
4250 "British pounds1.00",
4251 "Brunei Dollar1.00",
4252 "Brunei dollar1.00",
4253 "Brunei dollars1.00",
4254 "Bulgarian Hard Lev1.00",
4255 "Bulgarian Lev1.00",
4256 "Bulgarian Leva1.00",
4257 "Bulgarian hard lev1.00",
4258 "Bulgarian hard leva1.00",
4259 "Bulgarian lev1.00",
4262 "Burmese kyats1.00",
4263 "Burundian Franc1.00",
4264 "Burundian franc1.00",
4265 "Burundian francs1.00",
4270 "West African CFA Franc1.00",
4271 "Central African CFA Franc1.00",
4272 "West African CFA franc1.00",
4273 "Central African CFA franc1.00",
4274 "West African CFA francs1.00",
4275 "Central African CFA francs1.00",
4302 "Cambodian Riel1.00",
4303 "Cambodian riel1.00",
4304 "Cambodian riels1.00",
4305 "Canadian Dollar1.00",
4306 "Canadian dollar1.00",
4307 "Canadian dollars1.00",
4308 "Cape Verdean Escudo1.00",
4309 "Cape Verdean escudo1.00",
4310 "Cape Verdean escudos1.00",
4311 "Cayman Islands Dollar1.00",
4312 "Cayman Islands dollar1.00",
4313 "Cayman Islands dollars1.00",
4315 "Chilean Unit of Account (UF)1.00",
4317 "Chilean pesos1.00",
4318 "Chilean unit of account (UF)1.00",
4319 "Chilean units of account (UF)1.00",
4322 "Colombian Peso1.00",
4323 "Colombian peso1.00",
4324 "Colombian pesos1.00",
4325 "Comorian Franc1.00",
4326 "Comorian franc1.00",
4327 "Comorian francs1.00",
4328 "Congolese Franc1.00",
4329 "Congolese franc1.00",
4330 "Congolese francs1.00",
4331 "Costa Rican Col\\u00f3n1.00",
4332 "Costa Rican col\\u00f3n1.00",
4333 "Costa Rican col\\u00f3ns1.00",
4334 "Croatian Dinar1.00",
4335 "Croatian Kuna1.00",
4336 "Croatian dinar1.00",
4337 "Croatian dinars1.00",
4338 "Croatian kuna1.00",
4339 "Croatian kunas1.00",
4343 "Cypriot Pound1.00",
4344 "Cypriot pound1.00",
4345 "Cypriot pounds1.00",
4346 "Czech Republic Koruna1.00",
4347 "Czech Republic koruna1.00",
4348 "Czech Republic korunas1.00",
4349 "Czechoslovak Hard Koruna1.00",
4350 "Czechoslovak hard koruna1.00",
4351 "Czechoslovak hard korunas1.00",
4362 "Danish kroner1.00",
4366 "Djiboutian Franc1.00",
4367 "Djiboutian franc1.00",
4368 "Djiboutian francs1.00",
4369 "Dominican Peso1.00",
4370 "Dominican peso1.00",
4371 "Dominican pesos1.00",
4390 "East Caribbean Dollar1.00",
4391 "East Caribbean dollar1.00",
4392 "East Caribbean dollars1.00",
4393 "East German Mark1.00",
4394 "East German mark1.00",
4395 "East German marks1.00",
4396 "Ecuadorian Sucre1.00",
4397 "Ecuadorian Unit of Constant Value1.00",
4398 "Ecuadorian sucre1.00",
4399 "Ecuadorian sucres1.00",
4400 "Ecuadorian unit of constant value1.00",
4401 "Ecuadorian units of constant value1.00",
4402 "Egyptian Pound1.00",
4403 "Egyptian pound1.00",
4404 "Egyptian pounds1.00",
4405 "Salvadoran Col\\u00f3n1.00",
4406 "Salvadoran col\\u00f3n1.00",
4407 "Salvadoran colones1.00",
4408 "Equatorial Guinean Ekwele1.00",
4409 "Equatorial Guinean ekwele1.00",
4410 "Eritrean Nakfa1.00",
4411 "Eritrean nakfa1.00",
4412 "Eritrean nakfas1.00",
4413 "Estonian Kroon1.00",
4414 "Estonian kroon1.00",
4415 "Estonian kroons1.00",
4416 "Ethiopian Birr1.00",
4417 "Ethiopian birr1.00",
4418 "Ethiopian birrs1.00",
4420 "European Composite Unit1.00",
4421 "European Currency Unit1.00",
4422 "European Monetary Unit1.00",
4423 "European Unit of Account (XBC)1.00",
4424 "European Unit of Account (XBD)1.00",
4425 "European composite unit1.00",
4426 "European composite units1.00",
4427 "European currency unit1.00",
4428 "European currency units1.00",
4429 "European monetary unit1.00",
4430 "European monetary units1.00",
4431 "European unit of account (XBC)1.00",
4432 "European unit of account (XBD)1.00",
4433 "European units of account (XBC)1.00",
4434 "European units of account (XBD)1.00",
4442 "Falkland Islands Pound1.00",
4443 "Falkland Islands pound1.00",
4444 "Falkland Islands pounds1.00",
4445 "Fijian Dollar1.00",
4446 "Fijian dollar1.00",
4447 "Fijian dollars1.00",
4448 "Finnish Markka1.00",
4449 "Finnish markka1.00",
4450 "Finnish markkas1.00",
4453 "French Gold Franc1.00",
4454 "French UIC-Franc1.00",
4455 "French UIC-franc1.00",
4456 "French UIC-francs1.00",
4458 "French francs1.00",
4459 "French gold franc1.00",
4460 "French gold francs1.00",
4485 "Gambian Dalasi1.00",
4486 "Gambian dalasi1.00",
4487 "Gambian dalasis1.00",
4488 "Georgian Kupon Larit1.00",
4489 "Georgian Lari1.00",
4490 "Georgian kupon larit1.00",
4491 "Georgian kupon larits1.00",
4492 "Georgian lari1.00",
4493 "Georgian laris1.00",
4494 "Ghanaian Cedi (1979\\u20132007)1.00",
4495 "Ghanaian Cedi1.00",
4496 "Ghanaian cedi (1979\\u20132007)1.00",
4497 "Ghanaian cedi1.00",
4498 "Ghanaian cedis (1979\\u20132007)1.00",
4499 "Ghanaian cedis1.00",
4500 "Gibraltar Pound1.00",
4501 "Gibraltar pound1.00",
4502 "Gibraltar pounds1.00",
4505 "Greek Drachma1.00",
4506 "Greek drachma1.00",
4507 "Greek drachmas1.00",
4508 "Guatemalan Quetzal1.00",
4509 "Guatemalan quetzal1.00",
4510 "Guatemalan quetzals1.00",
4511 "Guinean Franc1.00",
4513 "Guinean franc1.00",
4514 "Guinean francs1.00",
4516 "Guinean sylis1.00",
4517 "Guinea-Bissau Peso1.00",
4518 "Guinea-Bissau peso1.00",
4519 "Guinea-Bissau pesos1.00",
4520 "Guyanaese Dollar1.00",
4521 "Guyanaese dollar1.00",
4522 "Guyanaese dollars1.00",
4533 "Haitian Gourde1.00",
4534 "Haitian gourde1.00",
4535 "Haitian gourdes1.00",
4536 "Honduran Lempira1.00",
4537 "Honduran lempira1.00",
4538 "Honduran lempiras1.00",
4539 "Hong Kong Dollar1.00",
4540 "Hong Kong dollar1.00",
4541 "Hong Kong dollars1.00",
4542 "Hungarian Forint1.00",
4543 "Hungarian forint1.00",
4544 "Hungarian forints1.00",
4556 "Icelandic Kr\\u00f3na1.00",
4557 "Icelandic kr\\u00f3na1.00",
4558 "Icelandic kr\\u00f3nur1.00",
4561 "Indian rupees1.00",
4562 "Indonesian Rupiah1.00",
4563 "Indonesian rupiah1.00",
4564 "Indonesian rupiahs1.00",
4567 "Iranian rials1.00",
4574 "Israeli Pound1.00",
4575 "Israeli new shekel1.00",
4576 "Israeli pound1.00",
4577 "Israeli pounds1.00",
4580 "Italian liras1.00",
4584 "Jamaican Dollar1.00",
4585 "Jamaican dollar1.00",
4586 "Jamaican dollars1.00",
4589 "Jordanian Dinar1.00",
4590 "Jordanian dinar1.00",
4591 "Jordanian dinars1.00",
4603 "Kazakhstani Tenge1.00",
4604 "Kazakhstani tenge1.00",
4605 "Kazakhstani tenges1.00",
4606 "Kenyan Shilling1.00",
4607 "Kenyan shilling1.00",
4608 "Kenyan shillings1.00",
4609 "Kuwaiti Dinar1.00",
4610 "Kuwaiti dinar1.00",
4611 "Kuwaiti dinars1.00",
4612 "Kyrgystani Som1.00",
4613 "Kyrgystani som1.00",
4614 "Kyrgystani soms1.00",
4642 "Latvian Ruble1.00",
4645 "Latvian ruble1.00",
4646 "Latvian rubles1.00",
4647 "Lebanese Pound1.00",
4648 "Lebanese pound1.00",
4649 "Lebanese pounds1.00",
4652 "Lesotho lotis1.00",
4653 "Liberian Dollar1.00",
4654 "Liberian dollar1.00",
4655 "Liberian dollars1.00",
4658 "Libyan dinars1.00",
4659 "Lithuanian Litas1.00",
4660 "Lithuanian Talonas1.00",
4661 "Lithuanian litas1.00",
4662 "Lithuanian litai1.00",
4663 "Lithuanian talonas1.00",
4664 "Lithuanian talonases1.00",
4665 "Luxembourgian Convertible Franc1.00",
4666 "Luxembourg Financial Franc1.00",
4667 "Luxembourgian Franc1.00",
4668 "Luxembourgian convertible franc1.00",
4669 "Luxembourgian convertible francs1.00",
4670 "Luxembourg financial franc1.00",
4671 "Luxembourg financial francs1.00",
4672 "Luxembourgian franc1.00",
4673 "Luxembourgian francs1.00",
4712 "Macanese Pataca1.00",
4713 "Macanese pataca1.00",
4714 "Macanese patacas1.00",
4715 "Macedonian Denar1.00",
4716 "Macedonian denar1.00",
4717 "Macedonian denari1.00",
4718 "Malagasy Ariaries1.00",
4719 "Malagasy Ariary1.00",
4720 "Malagasy Ariary1.00",
4721 "Malagasy Franc1.00",
4722 "Malagasy franc1.00",
4723 "Malagasy francs1.00",
4724 "Malawian Kwacha1.00",
4725 "Malawian Kwacha1.00",
4726 "Malawian Kwachas1.00",
4727 "Malaysian Ringgit1.00",
4728 "Malaysian ringgit1.00",
4729 "Malaysian ringgits1.00",
4730 "Maldivian Rufiyaa1.00",
4731 "Maldivian rufiyaa1.00",
4732 "Maldivian rufiyaas1.00",
4735 "Malian francs1.00",
4737 "Maltese Pound1.00",
4740 "Maltese pound1.00",
4741 "Maltese pounds1.00",
4742 "Mauritanian Ouguiya1.00",
4743 "Mauritanian ouguiya1.00",
4744 "Mauritanian ouguiyas1.00",
4745 "Mauritian Rupee1.00",
4746 "Mauritian rupee1.00",
4747 "Mauritian rupees1.00",
4749 "Mexican Silver Peso (1861\\u20131992)1.00",
4750 "Mexican Investment Unit1.00",
4752 "Mexican pesos1.00",
4753 "Mexican silver peso (1861\\u20131992)1.00",
4754 "Mexican silver pesos (1861\\u20131992)1.00",
4755 "Mexican investment unit1.00",
4756 "Mexican investment units1.00",
4760 "Mongolian Tugrik1.00",
4761 "Mongolian tugrik1.00",
4762 "Mongolian tugriks1.00",
4763 "Moroccan Dirham1.00",
4764 "Moroccan Franc1.00",
4765 "Moroccan dirham1.00",
4766 "Moroccan dirhams1.00",
4767 "Moroccan franc1.00",
4768 "Moroccan francs1.00",
4769 "Mozambican Escudo1.00",
4770 "Mozambican Metical1.00",
4771 "Mozambican escudo1.00",
4772 "Mozambican escudos1.00",
4773 "Mozambican metical1.00",
4774 "Mozambican meticals1.00",
4777 "Myanmar kyats1.00",
4790 "Namibian Dollar1.00",
4791 "Namibian dollar1.00",
4792 "Namibian dollars1.00",
4793 "Nepalese Rupee1.00",
4794 "Nepalese rupee1.00",
4795 "Nepalese rupees1.00",
4796 "Netherlands Antillean Guilder1.00",
4797 "Netherlands Antillean guilder1.00",
4798 "Netherlands Antillean guilders1.00",
4799 "Dutch Guilder1.00",
4800 "Dutch guilder1.00",
4801 "Dutch guilders1.00",
4802 "Israeli New Shekel1.00",
4803 "Israeli New Shekels1.00",
4804 "New Zealand Dollar1.00",
4805 "New Zealand dollar1.00",
4806 "New Zealand dollars1.00",
4807 "Nicaraguan C\\u00f3rdoba1.00",
4808 "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00",
4809 "Nicaraguan c\\u00f3rdoba1.00",
4810 "Nicaraguan c\\u00f3rdobas1.00",
4811 "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00",
4812 "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00",
4813 "Nigerian Naira1.00",
4814 "Nigerian naira1.00",
4815 "Nigerian nairas1.00",
4816 "North Korean Won1.00",
4817 "North Korean won1.00",
4818 "North Korean won1.00",
4819 "Norwegian Krone1.00",
4820 "Norwegian krone1.00",
4821 "Norwegian kroner1.00",
4823 "Mozambican Metical (1980\\u20132006)1.00",
4824 "Mozambican metical (1980\\u20132006)1.00",
4825 "Mozambican meticals (1980\\u20132006)1.00",
4826 "Romanian Lei (1952\\u20132006)1.00",
4827 "Romanian Leu (1952\\u20132006)1.00",
4828 "Romanian leu (1952\\u20132006)1.00",
4829 "Serbian Dinar (2002\\u20132006)1.00",
4830 "Serbian dinar (2002\\u20132006)1.00",
4831 "Serbian dinars (2002\\u20132006)1.00",
4832 "Sudanese Dinar (1992\\u20132007)1.00",
4833 "Sudanese Pound (1957\\u20131998)1.00",
4834 "Sudanese dinar (1992\\u20132007)1.00",
4835 "Sudanese dinars (1992\\u20132007)1.00",
4836 "Sudanese pound (1957\\u20131998)1.00",
4837 "Sudanese pounds (1957\\u20131998)1.00",
4838 "Turkish Lira (1922\\u20132005)1.00",
4839 "Turkish Lira (1922\\u20132005)1.00",
4861 "Pakistani Rupee1.00",
4862 "Pakistani rupee1.00",
4863 "Pakistani rupees1.00",
4866 "Panamanian Balboa1.00",
4867 "Panamanian balboa1.00",
4868 "Panamanian balboas1.00",
4869 "Papua New Guinean Kina1.00",
4870 "Papua New Guinean kina1.00",
4871 "Papua New Guinean kina1.00",
4872 "Paraguayan Guarani1.00",
4873 "Paraguayan guarani1.00",
4874 "Paraguayan guaranis1.00",
4875 "Peruvian Inti1.00",
4877 "Peruvian Sol (1863\\u20131965)1.00",
4878 "Peruvian inti1.00",
4879 "Peruvian intis1.00",
4881 "Peruvian soles1.00",
4882 "Peruvian sol (1863\\u20131965)1.00",
4883 "Peruvian soles (1863\\u20131965)1.00",
4884 "Philippine Peso1.00",
4885 "Philippine peso1.00",
4886 "Philippine pesos1.00",
4889 "Polish Zloty (1950\\u20131995)1.00",
4891 "Polish zlotys1.00",
4892 "Polish zloty (PLZ)1.00",
4894 "Polish zlotys (PLZ)1.00",
4895 "Portuguese Escudo1.00",
4896 "Portuguese Guinea Escudo1.00",
4897 "Portuguese Guinea escudo1.00",
4898 "Portuguese Guinea escudos1.00",
4899 "Portuguese escudo1.00",
4900 "Portuguese escudos1.00",
4922 "Rhodesian Dollar1.00",
4923 "Rhodesian dollar1.00",
4924 "Rhodesian dollars1.00",
4928 "Russian Ruble (1991\\u20131998)1.00",
4929 "Russian Ruble1.00",
4930 "Russian ruble (1991\\u20131998)1.00",
4931 "Russian ruble1.00",
4932 "Russian rubles (1991\\u20131998)1.00",
4933 "Russian rubles1.00",
4934 "Rwandan Franc1.00",
4935 "Rwandan franc1.00",
4936 "Rwandan francs1.00",
4966 "St. Helena Pound1.00",
4967 "St. Helena pound1.00",
4968 "St. Helena pounds1.00",
4969 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra1.00",
4970 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra1.00",
4971 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras1.00",
4975 "Serbian Dinar1.00",
4976 "Serbian dinar1.00",
4977 "Serbian dinars1.00",
4978 "Seychellois Rupee1.00",
4979 "Seychellois rupee1.00",
4980 "Seychellois rupees1.00",
4981 "Sierra Leonean Leone1.00",
4982 "Sierra Leonean leone1.00",
4983 "Sierra Leonean leones1.00",
4986 "Singapore Dollar1.00",
4987 "Singapore dollar1.00",
4988 "Singapore dollars1.00",
4989 "Slovak Koruna1.00",
4990 "Slovak koruna1.00",
4991 "Slovak korunas1.00",
4992 "Slovenian Tolar1.00",
4993 "Slovenian tolar1.00",
4994 "Slovenian tolars1.00",
4995 "Solomon Islands Dollar1.00",
4996 "Solomon Islands dollar1.00",
4997 "Solomon Islands dollars1.00",
4998 "Somali Shilling1.00",
4999 "Somali shilling1.00",
5000 "Somali shillings1.00",
5001 "South African Rand (financial)1.00",
5002 "South African Rand1.00",
5003 "South African rand (financial)1.00",
5004 "South African rand1.00",
5005 "South African rands (financial)1.00",
5006 "South African rand1.00",
5007 "South Korean Won1.00",
5008 "South Korean won1.00",
5009 "South Korean won1.00",
5010 "Soviet Rouble1.00",
5011 "Soviet rouble1.00",
5012 "Soviet roubles1.00",
5013 "Spanish Peseta (A account)1.00",
5014 "Spanish Peseta (convertible account)1.00",
5015 "Spanish Peseta1.00",
5016 "Spanish peseta (A account)1.00",
5017 "Spanish peseta (convertible account)1.00",
5018 "Spanish peseta1.00",
5019 "Spanish pesetas (A account)1.00",
5020 "Spanish pesetas (convertible account)1.00",
5021 "Spanish pesetas1.00",
5022 "Special Drawing Rights1.00",
5023 "Sri Lankan Rupee1.00",
5024 "Sri Lankan rupee1.00",
5025 "Sri Lankan rupees1.00",
5026 "Sudanese Pound1.00",
5027 "Sudanese pound1.00",
5028 "Sudanese pounds1.00",
5029 "Surinamese Dollar1.00",
5030 "Surinamese dollar1.00",
5031 "Surinamese dollars1.00",
5032 "Surinamese Guilder1.00",
5033 "Surinamese guilder1.00",
5034 "Surinamese guilders1.00",
5035 "Swazi Lilangeni1.00",
5036 "Swazi lilangeni1.00",
5037 "Swazi emalangeni1.00",
5038 "Swedish Krona1.00",
5039 "Swedish krona1.00",
5040 "Swedish kronor1.00",
5046 "Syrian pounds1.00",
5065 "New Taiwan Dollar1.00",
5066 "New Taiwan dollar1.00",
5067 "New Taiwan dollars1.00",
5068 "Tajikistani Ruble1.00",
5069 "Tajikistani Somoni1.00",
5070 "Tajikistani ruble1.00",
5071 "Tajikistani rubles1.00",
5072 "Tajikistani somoni1.00",
5073 "Tajikistani somonis1.00",
5074 "Tanzanian Shilling1.00",
5075 "Tanzanian shilling1.00",
5076 "Tanzanian shillings1.00",
5077 "Testing Currency Code1.00",
5078 "Testing Currency Code1.00",
5082 "Timorese Escudo1.00",
5083 "Timorese escudo1.00",
5084 "Timorese escudos1.00",
5085 "Tongan Pa\\u02bbanga1.00",
5086 "Tongan pa\\u02bbanga1.00",
5087 "Tongan pa\\u02bbanga1.00",
5088 "Trinidad & Tobago Dollar1.00",
5089 "Trinidad & Tobago dollar1.00",
5090 "Trinidad & Tobago dollars1.00",
5091 "Tunisian Dinar1.00",
5092 "Tunisian dinar1.00",
5093 "Tunisian dinars1.00",
5097 "Turkmenistani Manat1.00",
5098 "Turkmenistani manat1.00",
5099 "Turkmenistani manat1.00",
5108 "US Dollar (Next day)1.00",
5109 "US Dollar (Same day)1.00",
5111 "US dollar (next day)1.00",
5112 "US dollar (same day)1.00",
5114 "US dollars (next day)1.00",
5115 "US dollars (same day)1.00",
5129 "Ugandan Shilling (1966\\u20131987)1.00",
5130 "Ugandan Shilling1.00",
5131 "Ugandan shilling (1966\\u20131987)1.00",
5132 "Ugandan shilling1.00",
5133 "Ugandan shillings (1966\\u20131987)1.00",
5134 "Ugandan shillings1.00",
5135 "Ukrainian Hryvnia1.00",
5136 "Ukrainian Karbovanets1.00",
5137 "Ukrainian hryvnia1.00",
5138 "Ukrainian hryvnias1.00",
5139 "Ukrainian karbovanets1.00",
5140 "Ukrainian karbovantsiv1.00",
5141 "Colombian Real Value Unit1.00",
5142 "United Arab Emirates Dirham1.00",
5143 "Unknown Currency1.00",
5144 "Uruguayan Peso (1975\\u20131993)1.00",
5145 "Uruguayan Peso1.00",
5146 "Uruguayan Peso (Indexed Units)1.00",
5147 "Uruguayan peso (1975\\u20131993)1.00",
5148 "Uruguayan peso (indexed units)1.00",
5149 "Uruguayan peso1.00",
5150 "Uruguayan pesos (1975\\u20131993)1.00",
5151 "Uruguayan pesos (indexed units)1.00",
5152 "Uruguayan pesos1.00",
5153 "Uzbekistani Som1.00",
5154 "Uzbekistani som1.00",
5155 "Uzbekistani som1.00",
5162 "Vanuatu vatus1.00",
5163 "Venezuelan Bol\\u00edvar1.00",
5164 "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00",
5165 "Venezuelan bol\\u00edvar1.00",
5166 "Venezuelan bol\\u00edvars1.00",
5167 "Venezuelan bol\\u00edvar (1871\\u20132008)1.00",
5168 "Venezuelan bol\\u00edvars (1871\\u20132008)1.00",
5169 "Vietnamese Dong1.00",
5170 "Vietnamese dong1.00",
5171 "Vietnamese dong1.00",
5231 "Yemeni dinars1.00",
5234 "Yugoslavian Convertible Dinar (1990\\u20131992)1.00",
5235 "Yugoslavian Hard Dinar (1966\\u20131990)1.00",
5236 "Yugoslavian New Dinar (1994\\u20132002)1.00",
5237 "Yugoslavian convertible dinar (1990\\u20131992)1.00",
5238 "Yugoslavian convertible dinars (1990\\u20131992)1.00",
5239 "Yugoslavian hard dinar (1966\\u20131990)1.00",
5240 "Yugoslavian hard dinars (1966\\u20131990)1.00",
5241 "Yugoslavian new dinar (1994\\u20132002)1.00",
5242 "Yugoslavian new dinars (1994\\u20132002)1.00",
5253 "Zairean New Zaire (1993\\u20131998)1.00",
5254 "Zairean Zaire (1971\\u20131993)1.00",
5255 "Zairean new zaire (1993\\u20131998)1.00",
5256 "Zairean new zaires (1993\\u20131998)1.00",
5257 "Zairean zaire (1971\\u20131993)1.00",
5258 "Zairean zaires (1971\\u20131993)1.00",
5259 "Zambian Kwacha1.00",
5260 "Zambian kwacha1.00",
5261 "Zambian kwachas1.00",
5262 "Zimbabwean Dollar (1980\\u20132008)1.00",
5263 "Zimbabwean dollar (1980\\u20132008)1.00",
5264 "Zimbabwean dollars (1980\\u20132008)1.00",
5267 "Turkish lira (1922\\u20132005)1.00",
5268 "special drawing rights1.00",
5269 "Colombian real value unit1.00",
5270 "Colombian real value units1.00",
5271 "unknown currency1.00",
5279 // Following has extra text, should be parsed correctly too
5282 "1.00 US dollar random",
5283 "1.00 US dollars random",
5284 "1.00 Afghan Afghani random",
5285 "1.00 Afghan Afghani random",
5286 "1.00 Afghan Afghanis (1927\\u20131992) random",
5287 "1.00 Afghan Afghanis random",
5288 "1.00 Albanian Lek random",
5289 "1.00 Albanian lek random",
5290 "1.00 Albanian lek\\u00eb random",
5291 "1.00 Algerian Dinar random",
5292 "1.00 Algerian dinar random",
5293 "1.00 Algerian dinars random",
5294 "1.00 Andorran Peseta random",
5295 "1.00 Andorran peseta random",
5296 "1.00 Andorran pesetas random",
5297 "1.00 Angolan Kwanza (1977\\u20131990) random",
5298 "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random",
5299 "1.00 Angolan Kwanza random",
5300 "1.00 Angolan New Kwanza (1990\\u20132000) random",
5301 "1.00 Angolan kwanza (1977\\u20131991) random",
5302 "1.00 Angolan readjusted kwanza (1995\\u20131999) random",
5303 "1.00 Angolan kwanza random",
5304 "1.00 Angolan kwanzas (1977\\u20131991) random",
5305 "1.00 Angolan readjusted kwanzas (1995\\u20131999) random",
5306 "1.00 Angolan kwanzas random",
5307 "1.00 Angolan new kwanza (1990\\u20132000) random",
5308 "1.00 Angolan new kwanzas (1990\\u20132000) random",
5309 "1.00 Argentine Austral random",
5310 "1.00 Argentine Peso (1983\\u20131985) random",
5311 "1.00 Argentine Peso random",
5312 "1.00 Argentine austral random",
5313 "1.00 Argentine australs random",
5314 "1.00 Argentine peso (1983\\u20131985) random",
5315 "1.00 Argentine peso random",
5316 "1.00 Argentine pesos (1983\\u20131985) random",
5317 "1.00 Argentine pesos random",
5318 "1.00 Armenian Dram random",
5319 "1.00 Armenian dram random",
5320 "1.00 Armenian drams random",
5321 "1.00 Aruban Florin random",
5322 "1.00 Aruban florin random",
5323 "1.00 Australian Dollar random",
5324 "1.00 Australian dollar random",
5325 "1.00 Australian dollars random",
5326 "1.00 Austrian Schilling random",
5327 "1.00 Austrian schilling random",
5328 "1.00 Austrian schillings random",
5329 "1.00 Azerbaijani Manat (1993\\u20132006) random",
5330 "1.00 Azerbaijani Manat random",
5331 "1.00 Azerbaijani manat (1993\\u20132006) random",
5332 "1.00 Azerbaijani manat random",
5333 "1.00 Azerbaijani manats (1993\\u20132006) random",
5334 "1.00 Azerbaijani manats random",
5335 "1.00 Bahamian Dollar random",
5336 "1.00 Bahamian dollar random",
5337 "1.00 Bahamian dollars random",
5338 "1.00 Bahraini Dinar random",
5339 "1.00 Bahraini dinar random",
5340 "1.00 Bahraini dinars random",
5341 "1.00 Bangladeshi Taka random",
5342 "1.00 Bangladeshi taka random",
5343 "1.00 Bangladeshi takas random",
5344 "1.00 Barbadian Dollar random",
5345 "1.00 Barbadian dollar random",
5346 "1.00 Barbadian dollars random",
5347 "1.00 Belarusian Ruble (1994\\u20131999) random",
5348 "1.00 Belarusian Ruble random",
5349 "1.00 Belarusian ruble (1994\\u20131999) random",
5350 "1.00 Belarusian rubles (1994\\u20131999) random",
5351 "1.00 Belarusian ruble random",
5352 "1.00 Belarusian rubles random",
5353 "1.00 Belgian Franc (convertible) random",
5354 "1.00 Belgian Franc (financial) random",
5355 "1.00 Belgian Franc random",
5356 "1.00 Belgian franc (convertible) random",
5357 "1.00 Belgian franc (financial) random",
5358 "1.00 Belgian franc random",
5359 "1.00 Belgian francs (convertible) random",
5360 "1.00 Belgian francs (financial) random",
5361 "1.00 Belgian francs random",
5362 "1.00 Belize Dollar random",
5363 "1.00 Belize dollar random",
5364 "1.00 Belize dollars random",
5365 "1.00 Bermudan Dollar random",
5366 "1.00 Bermudan dollar random",
5367 "1.00 Bermudan dollars random",
5368 "1.00 Bhutanese Ngultrum random",
5369 "1.00 Bhutanese ngultrum random",
5370 "1.00 Bhutanese ngultrums random",
5371 "1.00 Bolivian Mvdol random",
5372 "1.00 Bolivian Peso random",
5373 "1.00 Bolivian mvdol random",
5374 "1.00 Bolivian mvdols random",
5375 "1.00 Bolivian peso random",
5376 "1.00 Bolivian pesos random",
5377 "1.00 Bolivian Boliviano random",
5378 "1.00 Bolivian Boliviano random",
5379 "1.00 Bolivian Bolivianos random",
5380 "1.00 Bosnia-Herzegovina Convertible Mark random",
5381 "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random",
5382 "1.00 Bosnia-Herzegovina convertible mark random",
5383 "1.00 Bosnia-Herzegovina convertible marks random",
5384 "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random",
5385 "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random",
5386 "1.00 Botswanan Pula random",
5387 "1.00 Botswanan pula random",
5388 "1.00 Botswanan pulas random",
5389 "1.00 Brazilian New Cruzado (1989\\u20131990) random",
5390 "1.00 Brazilian Cruzado (1986\\u20131989) random",
5391 "1.00 Brazilian Cruzeiro (1990\\u20131993) random",
5392 "1.00 Brazilian New Cruzeiro (1967\\u20131986) random",
5393 "1.00 Brazilian Cruzeiro (1993\\u20131994) random",
5394 "1.00 Brazilian Real random",
5395 "1.00 Brazilian new cruzado (1989\\u20131990) random",
5396 "1.00 Brazilian new cruzados (1989\\u20131990) random",
5397 "1.00 Brazilian cruzado (1986\\u20131989) random",
5398 "1.00 Brazilian cruzados (1986\\u20131989) random",
5399 "1.00 Brazilian cruzeiro (1990\\u20131993) random",
5400 "1.00 Brazilian new cruzeiro (1967\\u20131986) random",
5401 "1.00 Brazilian cruzeiro (1993\\u20131994) random",
5402 "1.00 Brazilian cruzeiros (1990\\u20131993) random",
5403 "1.00 Brazilian new cruzeiros (1967\\u20131986) random",
5404 "1.00 Brazilian cruzeiros (1993\\u20131994) random",
5405 "1.00 Brazilian real random",
5406 "1.00 Brazilian reals random",
5407 "1.00 British Pound random",
5408 "1.00 British pound random",
5409 "1.00 British pounds random",
5410 "1.00 Brunei Dollar random",
5411 "1.00 Brunei dollar random",
5412 "1.00 Brunei dollars random",
5413 "1.00 Bulgarian Hard Lev random",
5414 "1.00 Bulgarian Lev random",
5415 "1.00 Bulgarian Leva random",
5416 "1.00 Bulgarian hard lev random",
5417 "1.00 Bulgarian hard leva random",
5418 "1.00 Bulgarian lev random",
5419 "1.00 Burmese Kyat random",
5420 "1.00 Burmese kyat random",
5421 "1.00 Burmese kyats random",
5422 "1.00 Burundian Franc random",
5423 "1.00 Burundian franc random",
5424 "1.00 Burundian francs random",
5425 "1.00 Cambodian Riel random",
5426 "1.00 Cambodian riel random",
5427 "1.00 Cambodian riels random",
5428 "1.00 Canadian Dollar random",
5429 "1.00 Canadian dollar random",
5430 "1.00 Canadian dollars random",
5431 "1.00 Cape Verdean Escudo random",
5432 "1.00 Cape Verdean escudo random",
5433 "1.00 Cape Verdean escudos random",
5434 "1.00 Cayman Islands Dollar random",
5435 "1.00 Cayman Islands dollar random",
5436 "1.00 Cayman Islands dollars random",
5437 "1.00 Chilean Peso random",
5438 "1.00 Chilean Unit of Account (UF) random",
5439 "1.00 Chilean peso random",
5440 "1.00 Chilean pesos random",
5441 "1.00 Chilean unit of account (UF) random",
5442 "1.00 Chilean units of account (UF) random",
5443 "1.00 Chinese Yuan random",
5444 "1.00 Chinese yuan random",
5445 "1.00 Colombian Peso random",
5446 "1.00 Colombian peso random",
5447 "1.00 Colombian pesos random",
5448 "1.00 Comorian Franc random",
5449 "1.00 Comorian franc random",
5450 "1.00 Comorian francs random",
5451 "1.00 Congolese Franc Congolais random",
5452 "1.00 Congolese franc Congolais random",
5453 "1.00 Congolese francs Congolais random",
5454 "1.00 Costa Rican Col\\u00f3n random",
5455 "1.00 Costa Rican col\\u00f3n random",
5456 "1.00 Costa Rican col\\u00f3ns random",
5457 "1.00 Croatian Dinar random",
5458 "1.00 Croatian Kuna random",
5459 "1.00 Croatian dinar random",
5460 "1.00 Croatian dinars random",
5461 "1.00 Croatian kuna random",
5462 "1.00 Croatian kunas random",
5463 "1.00 Cuban Peso random",
5464 "1.00 Cuban peso random",
5465 "1.00 Cuban pesos random",
5466 "1.00 Cypriot Pound random",
5467 "1.00 Cypriot pound random",
5468 "1.00 Cypriot pounds random",
5469 "1.00 Czech Republic Koruna random",
5470 "1.00 Czech Republic koruna random",
5471 "1.00 Czech Republic korunas random",
5472 "1.00 Czechoslovak Hard Koruna random",
5473 "1.00 Czechoslovak hard koruna random",
5474 "1.00 Czechoslovak hard korunas random",
5475 "1.00 Danish Krone random",
5476 "1.00 Danish krone random",
5477 "1.00 Danish kroner random",
5478 "1.00 German Mark random",
5479 "1.00 German mark random",
5480 "1.00 German marks random",
5481 "1.00 Djiboutian Franc random",
5482 "1.00 Djiboutian franc random",
5483 "1.00 Djiboutian francs random",
5484 "1.00 Dominican Peso random",
5485 "1.00 Dominican peso random",
5486 "1.00 Dominican pesos random",
5487 "1.00 East Caribbean Dollar random",
5488 "1.00 East Caribbean dollar random",
5489 "1.00 East Caribbean dollars random",
5490 "1.00 East German Mark random",
5491 "1.00 East German mark random",
5492 "1.00 East German marks random",
5493 "1.00 Ecuadorian Sucre random",
5494 "1.00 Ecuadorian Unit of Constant Value random",
5495 "1.00 Ecuadorian sucre random",
5496 "1.00 Ecuadorian sucres random",
5497 "1.00 Ecuadorian unit of constant value random",
5498 "1.00 Ecuadorian units of constant value random",
5499 "1.00 Egyptian Pound random",
5500 "1.00 Egyptian pound random",
5501 "1.00 Egyptian pounds random",
5502 "1.00 Salvadoran Col\\u00f3n random",
5503 "1.00 Salvadoran col\\u00f3n random",
5504 "1.00 Salvadoran colones random",
5505 "1.00 Equatorial Guinean Ekwele random",
5506 "1.00 Equatorial Guinean ekwele random",
5507 "1.00 Eritrean Nakfa random",
5508 "1.00 Eritrean nakfa random",
5509 "1.00 Eritrean nakfas random",
5510 "1.00 Estonian Kroon random",
5511 "1.00 Estonian kroon random",
5512 "1.00 Estonian kroons random",
5513 "1.00 Ethiopian Birr random",
5514 "1.00 Ethiopian birr random",
5515 "1.00 Ethiopian birrs random",
5516 "1.00 European Composite Unit random",
5517 "1.00 European Currency Unit random",
5518 "1.00 European Monetary Unit random",
5519 "1.00 European Unit of Account (XBC) random",
5520 "1.00 European Unit of Account (XBD) random",
5521 "1.00 European composite unit random",
5522 "1.00 European composite units random",
5523 "1.00 European currency unit random",
5524 "1.00 European currency units random",
5525 "1.00 European monetary unit random",
5526 "1.00 European monetary units random",
5527 "1.00 European unit of account (XBC) random",
5528 "1.00 European unit of account (XBD) random",
5529 "1.00 European units of account (XBC) random",
5530 "1.00 European units of account (XBD) random",
5531 "1.00 Falkland Islands Pound random",
5532 "1.00 Falkland Islands pound random",
5533 "1.00 Falkland Islands pounds random",
5534 "1.00 Fijian Dollar random",
5535 "1.00 Fijian dollar random",
5536 "1.00 Fijian dollars random",
5537 "1.00 Finnish Markka random",
5538 "1.00 Finnish markka random",
5539 "1.00 Finnish markkas random",
5540 "1.00 French Franc random",
5541 "1.00 French Gold Franc random",
5542 "1.00 French UIC-Franc random",
5543 "1.00 French UIC-franc random",
5544 "1.00 French UIC-francs random",
5545 "1.00 French franc random",
5546 "1.00 French francs random",
5547 "1.00 French gold franc random",
5548 "1.00 French gold francs random",
5549 "1.00 Gambian Dalasi random",
5550 "1.00 Gambian dalasi random",
5551 "1.00 Gambian dalasis random",
5552 "1.00 Georgian Kupon Larit random",
5553 "1.00 Georgian Lari random",
5554 "1.00 Georgian kupon larit random",
5555 "1.00 Georgian kupon larits random",
5556 "1.00 Georgian lari random",
5557 "1.00 Georgian laris random",
5558 "1.00 Ghanaian Cedi (1979\\u20132007) random",
5559 "1.00 Ghanaian Cedi random",
5560 "1.00 Ghanaian cedi (1979\\u20132007) random",
5561 "1.00 Ghanaian cedi random",
5562 "1.00 Ghanaian cedis (1979\\u20132007) random",
5563 "1.00 Ghanaian cedis random",
5564 "1.00 Gibraltar Pound random",
5565 "1.00 Gibraltar pound random",
5566 "1.00 Gibraltar pounds random",
5569 "1.00 Greek Drachma random",
5570 "1.00 Greek drachma random",
5571 "1.00 Greek drachmas random",
5572 "1.00 Guatemalan Quetzal random",
5573 "1.00 Guatemalan quetzal random",
5574 "1.00 Guatemalan quetzals random",
5575 "1.00 Guinean Franc random",
5576 "1.00 Guinean Syli random",
5577 "1.00 Guinean franc random",
5578 "1.00 Guinean francs random",
5579 "1.00 Guinean syli random",
5580 "1.00 Guinean sylis random",
5581 "1.00 Guinea-Bissau Peso random",
5582 "1.00 Guinea-Bissau peso random",
5583 "1.00 Guinea-Bissau pesos random",
5584 "1.00 Guyanaese Dollar random",
5585 "1.00 Guyanaese dollar random",
5586 "1.00 Guyanaese dollars random",
5587 "1.00 Haitian Gourde random",
5588 "1.00 Haitian gourde random",
5589 "1.00 Haitian gourdes random",
5590 "1.00 Honduran Lempira random",
5591 "1.00 Honduran lempira random",
5592 "1.00 Honduran lempiras random",
5593 "1.00 Hong Kong Dollar random",
5594 "1.00 Hong Kong dollar random",
5595 "1.00 Hong Kong dollars random",
5596 "1.00 Hungarian Forint random",
5597 "1.00 Hungarian forint random",
5598 "1.00 Hungarian forints random",
5599 "1.00 Icelandic Kr\\u00f3na random",
5600 "1.00 Icelandic kr\\u00f3na random",
5601 "1.00 Icelandic kr\\u00f3nur random",
5602 "1.00 Indian Rupee random",
5603 "1.00 Indian rupee random",
5604 "1.00 Indian rupees random",
5605 "1.00 Indonesian Rupiah random",
5606 "1.00 Indonesian rupiah random",
5607 "1.00 Indonesian rupiahs random",
5608 "1.00 Iranian Rial random",
5609 "1.00 Iranian rial random",
5610 "1.00 Iranian rials random",
5611 "1.00 Iraqi Dinar random",
5612 "1.00 Iraqi dinar random",
5613 "1.00 Iraqi dinars random",
5614 "1.00 Irish Pound random",
5615 "1.00 Irish pound random",
5616 "1.00 Irish pounds random",
5617 "1.00 Israeli Pound random",
5618 "1.00 Israeli new shekel random",
5619 "1.00 Israeli pound random",
5620 "1.00 Israeli pounds random",
5621 "1.00 Italian Lira random",
5622 "1.00 Italian lira random",
5623 "1.00 Italian liras random",
5624 "1.00 Jamaican Dollar random",
5625 "1.00 Jamaican dollar random",
5626 "1.00 Jamaican dollars random",
5627 "1.00 Japanese Yen random",
5628 "1.00 Japanese yen random",
5629 "1.00 Jordanian Dinar random",
5630 "1.00 Jordanian dinar random",
5631 "1.00 Jordanian dinars random",
5632 "1.00 Kazakhstani Tenge random",
5633 "1.00 Kazakhstani tenge random",
5634 "1.00 Kazakhstani tenges random",
5635 "1.00 Kenyan Shilling random",
5636 "1.00 Kenyan shilling random",
5637 "1.00 Kenyan shillings random",
5638 "1.00 Kuwaiti Dinar random",
5639 "1.00 Kuwaiti dinar random",
5640 "1.00 Kuwaiti dinars random",
5641 "1.00 Kyrgystani Som random",
5642 "1.00 Kyrgystani som random",
5643 "1.00 Kyrgystani soms random",
5644 "1.00 Laotian Kip random",
5645 "1.00 Laotian kip random",
5646 "1.00 Laotian kips random",
5647 "1.00 Latvian Lats random",
5648 "1.00 Latvian Ruble random",
5649 "1.00 Latvian lats random",
5650 "1.00 Latvian lati random",
5651 "1.00 Latvian ruble random",
5652 "1.00 Latvian rubles random",
5653 "1.00 Lebanese Pound random",
5654 "1.00 Lebanese pound random",
5655 "1.00 Lebanese pounds random",
5656 "1.00 Lesotho Loti random",
5657 "1.00 Lesotho loti random",
5658 "1.00 Lesotho lotis random",
5659 "1.00 Liberian Dollar random",
5660 "1.00 Liberian dollar random",
5661 "1.00 Liberian dollars random",
5662 "1.00 Libyan Dinar random",
5663 "1.00 Libyan dinar random",
5664 "1.00 Libyan dinars random",
5665 "1.00 Lithuanian Litas random",
5666 "1.00 Lithuanian Talonas random",
5667 "1.00 Lithuanian litas random",
5668 "1.00 Lithuanian litai random",
5669 "1.00 Lithuanian talonas random",
5670 "1.00 Lithuanian talonases random",
5671 "1.00 Luxembourgian Convertible Franc random",
5672 "1.00 Luxembourg Financial Franc random",
5673 "1.00 Luxembourgian Franc random",
5674 "1.00 Luxembourgian convertible franc random",
5675 "1.00 Luxembourgian convertible francs random",
5676 "1.00 Luxembourg financial franc random",
5677 "1.00 Luxembourg financial francs random",
5678 "1.00 Luxembourgian franc random",
5679 "1.00 Luxembourgian francs random",
5680 "1.00 Macanese Pataca random",
5681 "1.00 Macanese pataca random",
5682 "1.00 Macanese patacas random",
5683 "1.00 Macedonian Denar random",
5684 "1.00 Macedonian denar random",
5685 "1.00 Macedonian denari random",
5686 "1.00 Malagasy Ariaries random",
5687 "1.00 Malagasy Ariary random",
5688 "1.00 Malagasy Ariary random",
5689 "1.00 Malagasy Franc random",
5690 "1.00 Malagasy franc random",
5691 "1.00 Malagasy francs random",
5692 "1.00 Malawian Kwacha random",
5693 "1.00 Malawian Kwacha random",
5694 "1.00 Malawian Kwachas random",
5695 "1.00 Malaysian Ringgit random",
5696 "1.00 Malaysian ringgit random",
5697 "1.00 Malaysian ringgits random",
5698 "1.00 Maldivian Rufiyaa random",
5699 "1.00 Maldivian rufiyaa random",
5700 "1.00 Maldivian rufiyaas random",
5701 "1.00 Malian Franc random",
5702 "1.00 Malian franc random",
5703 "1.00 Malian francs random",
5704 "1.00 Maltese Lira random",
5705 "1.00 Maltese Pound random",
5706 "1.00 Maltese lira random",
5707 "1.00 Maltese liras random",
5708 "1.00 Maltese pound random",
5709 "1.00 Maltese pounds random",
5710 "1.00 Mauritanian Ouguiya random",
5711 "1.00 Mauritanian ouguiya random",
5712 "1.00 Mauritanian ouguiyas random",
5713 "1.00 Mauritian Rupee random",
5714 "1.00 Mauritian rupee random",
5715 "1.00 Mauritian rupees random",
5716 "1.00 Mexican Peso random",
5717 "1.00 Mexican Silver Peso (1861\\u20131992) random",
5718 "1.00 Mexican Investment Unit random",
5719 "1.00 Mexican peso random",
5720 "1.00 Mexican pesos random",
5721 "1.00 Mexican silver peso (1861\\u20131992) random",
5722 "1.00 Mexican silver pesos (1861\\u20131992) random",
5723 "1.00 Mexican investment unit random",
5724 "1.00 Mexican investment units random",
5725 "1.00 Moldovan Leu random",
5726 "1.00 Moldovan leu random",
5727 "1.00 Moldovan lei random",
5728 "1.00 Mongolian Tugrik random",
5729 "1.00 Mongolian tugrik random",
5730 "1.00 Mongolian tugriks random",
5731 "1.00 Moroccan Dirham random",
5732 "1.00 Moroccan Franc random",
5733 "1.00 Moroccan dirham random",
5734 "1.00 Moroccan dirhams random",
5735 "1.00 Moroccan franc random",
5736 "1.00 Moroccan francs random",
5737 "1.00 Mozambican Escudo random",
5738 "1.00 Mozambican Metical random",
5739 "1.00 Mozambican escudo random",
5740 "1.00 Mozambican escudos random",
5741 "1.00 Mozambican metical random",
5742 "1.00 Mozambican meticals random",
5743 "1.00 Myanmar Kyat random",
5744 "1.00 Myanmar kyat random",
5745 "1.00 Myanmar kyats random",
5746 "1.00 Namibian Dollar random",
5747 "1.00 Namibian dollar random",
5748 "1.00 Namibian dollars random",
5749 "1.00 Nepalese Rupee random",
5750 "1.00 Nepalese rupee random",
5751 "1.00 Nepalese rupees random",
5752 "1.00 Netherlands Antillean Guilder random",
5753 "1.00 Netherlands Antillean guilder random",
5754 "1.00 Netherlands Antillean guilders random",
5755 "1.00 Dutch Guilder random",
5756 "1.00 Dutch guilder random",
5757 "1.00 Dutch guilders random",
5758 "1.00 Israeli New Shekel random",
5759 "1.00 Israeli new shekels random",
5760 "1.00 New Zealand Dollar random",
5761 "1.00 New Zealand dollar random",
5762 "1.00 New Zealand dollars random",
5763 "1.00 Nicaraguan C\\u00f3rdoba random",
5764 "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random",
5765 "1.00 Nicaraguan c\\u00f3rdoba random",
5766 "1.00 Nicaraguan c\\u00f3rdoba random",
5767 "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random",
5768 "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random",
5769 "1.00 Nigerian Naira random",
5770 "1.00 Nigerian naira random",
5771 "1.00 Nigerian nairas random",
5772 "1.00 North Korean Won random",
5773 "1.00 North Korean won random",
5774 "1.00 North Korean won random",
5775 "1.00 Norwegian Krone random",
5776 "1.00 Norwegian krone random",
5777 "1.00 Norwegian kroner random",
5778 "1.00 Mozambican Metical (1980\\u20132006) random",
5779 "1.00 Mozambican metical (1980\\u20132006) random",
5780 "1.00 Mozambican meticals (1980\\u20132006) random",
5781 "1.00 Romanian Lei (1952\\u20132006) random",
5782 "1.00 Romanian Leu (1952\\u20132006) random",
5783 "1.00 Romanian leu (1952\\u20132006) random",
5784 "1.00 Serbian Dinar (2002\\u20132006) random",
5785 "1.00 Serbian dinar (2002\\u20132006) random",
5786 "1.00 Serbian dinars (2002\\u20132006) random",
5787 "1.00 Sudanese Dinar (1992\\u20132007) random",
5788 "1.00 Sudanese Pound (1957\\u20131998) random",
5789 "1.00 Sudanese dinar (1992\\u20132007) random",
5790 "1.00 Sudanese dinars (1992\\u20132007) random",
5791 "1.00 Sudanese pound (1957\\u20131998) random",
5792 "1.00 Sudanese pounds (1957\\u20131998) random",
5793 "1.00 Turkish Lira (1922\\u20132005) random",
5794 "1.00 Turkish Lira (1922\\u20132005) random",
5795 "1.00 Omani Rial random",
5796 "1.00 Omani rial random",
5797 "1.00 Omani rials random",
5798 "1.00 Pakistani Rupee random",
5799 "1.00 Pakistani rupee random",
5800 "1.00 Pakistani rupees random",
5801 "1.00 Palladium random",
5802 "1.00 Palladium random",
5803 "1.00 Panamanian Balboa random",
5804 "1.00 Panamanian balboa random",
5805 "1.00 Panamanian balboas random",
5806 "1.00 Papua New Guinean Kina random",
5807 "1.00 Papua New Guinean kina random",
5808 "1.00 Papua New Guinean kina random",
5809 "1.00 Paraguayan Guarani random",
5810 "1.00 Paraguayan guarani random",
5811 "1.00 Paraguayan guaranis random",
5812 "1.00 Peruvian Inti random",
5813 "1.00 Peruvian Sol random",
5814 "1.00 Peruvian Sol (1863\\u20131965) random",
5815 "1.00 Peruvian inti random",
5816 "1.00 Peruvian intis random",
5817 "1.00 Peruvian sol random",
5818 "1.00 Peruvian soles random",
5819 "1.00 Peruvian sol (1863\\u20131965) random",
5820 "1.00 Peruvian soles (1863\\u20131965) random",
5821 "1.00 Philippine Peso random",
5822 "1.00 Philippine peso random",
5823 "1.00 Philippine pesos random",
5824 "1.00 Platinum random",
5825 "1.00 Platinum random",
5826 "1.00 Polish Zloty (1950\\u20131995) random",
5827 "1.00 Polish Zloty random",
5828 "1.00 Polish zlotys random",
5829 "1.00 Polish zloty (PLZ) random",
5830 "1.00 Polish zloty random",
5831 "1.00 Polish zlotys (PLZ) random",
5832 "1.00 Portuguese Escudo random",
5833 "1.00 Portuguese Guinea Escudo random",
5834 "1.00 Portuguese Guinea escudo random",
5835 "1.00 Portuguese Guinea escudos random",
5836 "1.00 Portuguese escudo random",
5837 "1.00 Portuguese escudos random",
5838 "1.00 Qatari Rial random",
5839 "1.00 Qatari rial random",
5840 "1.00 Qatari rials random",
5841 "1.00 RINET Funds random",
5842 "1.00 RINET Funds random",
5843 "1.00 Rhodesian Dollar random",
5844 "1.00 Rhodesian dollar random",
5845 "1.00 Rhodesian dollars random",
5846 "1.00 Romanian Leu random",
5847 "1.00 Romanian lei random",
5848 "1.00 Romanian leu random",
5849 "1.00 Russian Ruble (1991\\u20131998) random",
5850 "1.00 Russian Ruble random",
5851 "1.00 Russian ruble (1991\\u20131998) random",
5852 "1.00 Russian ruble random",
5853 "1.00 Russian rubles (1991\\u20131998) random",
5854 "1.00 Russian rubles random",
5855 "1.00 Rwandan Franc random",
5856 "1.00 Rwandan franc random",
5857 "1.00 Rwandan francs random",
5858 "1.00 St. Helena Pound random",
5859 "1.00 St. Helena pound random",
5860 "1.00 St. Helena pounds random",
5861 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra random",
5862 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra random",
5863 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras random",
5864 "1.00 Saudi Riyal random",
5865 "1.00 Saudi riyal random",
5866 "1.00 Saudi riyals random",
5867 "1.00 Serbian Dinar random",
5868 "1.00 Serbian dinar random",
5869 "1.00 Serbian dinars random",
5870 "1.00 Seychellois Rupee random",
5871 "1.00 Seychellois rupee random",
5872 "1.00 Seychellois rupees random",
5873 "1.00 Sierra Leonean Leone random",
5874 "1.00 Sierra Leonean leone random",
5875 "1.00 Sierra Leonean leones random",
5876 "1.00 Singapore Dollar random",
5877 "1.00 Singapore dollar random",
5878 "1.00 Singapore dollars random",
5879 "1.00 Slovak Koruna random",
5880 "1.00 Slovak koruna random",
5881 "1.00 Slovak korunas random",
5882 "1.00 Slovenian Tolar random",
5883 "1.00 Slovenian tolar random",
5884 "1.00 Slovenian tolars random",
5885 "1.00 Solomon Islands Dollar random",
5886 "1.00 Solomon Islands dollar random",
5887 "1.00 Solomon Islands dollars random",
5888 "1.00 Somali Shilling random",
5889 "1.00 Somali shilling random",
5890 "1.00 Somali shillings random",
5891 "1.00 South African Rand (financial) random",
5892 "1.00 South African Rand random",
5893 "1.00 South African rand (financial) random",
5894 "1.00 South African rand random",
5895 "1.00 South African rands (financial) random",
5896 "1.00 South African rand random",
5897 "1.00 South Korean Won random",
5898 "1.00 South Korean won random",
5899 "1.00 South Korean won random",
5900 "1.00 Soviet Rouble random",
5901 "1.00 Soviet rouble random",
5902 "1.00 Soviet roubles random",
5903 "1.00 Spanish Peseta (A account) random",
5904 "1.00 Spanish Peseta (convertible account) random",
5905 "1.00 Spanish Peseta random",
5906 "1.00 Spanish peseta (A account) random",
5907 "1.00 Spanish peseta (convertible account) random",
5908 "1.00 Spanish peseta random",
5909 "1.00 Spanish pesetas (A account) random",
5910 "1.00 Spanish pesetas (convertible account) random",
5911 "1.00 Spanish pesetas random",
5912 "1.00 Special Drawing Rights random",
5913 "1.00 Sri Lankan Rupee random",
5914 "1.00 Sri Lankan rupee random",
5915 "1.00 Sri Lankan rupees random",
5916 "1.00 Sudanese Pound random",
5917 "1.00 Sudanese pound random",
5918 "1.00 Sudanese pounds random",
5919 "1.00 Surinamese Dollar random",
5920 "1.00 Surinamese dollar random",
5921 "1.00 Surinamese dollars random",
5922 "1.00 Surinamese Guilder random",
5923 "1.00 Surinamese guilder random",
5924 "1.00 Surinamese guilders random",
5925 "1.00 Swazi Lilangeni random",
5926 "1.00 Swazi lilangeni random",
5927 "1.00 Swazi emalangeni random",
5928 "1.00 Swedish Krona random",
5929 "1.00 Swedish krona random",
5930 "1.00 Swedish kronor random",
5931 "1.00 Swiss Franc random",
5932 "1.00 Swiss franc random",
5933 "1.00 Swiss francs random",
5934 "1.00 Syrian Pound random",
5935 "1.00 Syrian pound random",
5936 "1.00 Syrian pounds random",
5937 "1.00 New Taiwan Dollar random",
5938 "1.00 New Taiwan dollar random",
5939 "1.00 New Taiwan dollars random",
5940 "1.00 Tajikistani Ruble random",
5941 "1.00 Tajikistani Somoni random",
5942 "1.00 Tajikistani ruble random",
5943 "1.00 Tajikistani rubles random",
5944 "1.00 Tajikistani somoni random",
5945 "1.00 Tajikistani somonis random",
5946 "1.00 Tanzanian Shilling random",
5947 "1.00 Tanzanian shilling random",
5948 "1.00 Tanzanian shillings random",
5949 "1.00 Testing Currency Code random",
5950 "1.00 Testing Currency Code random",
5951 "1.00 Thai Baht random",
5952 "1.00 Thai baht random",
5953 "1.00 Thai baht random",
5954 "1.00 Timorese Escudo random",
5955 "1.00 Timorese escudo random",
5956 "1.00 Timorese escudos random",
5957 "1.00 Trinidad & Tobago Dollar random",
5958 "1.00 Trinidad & Tobago dollar random",
5959 "1.00 Trinidad & Tobago dollars random",
5960 "1.00 Tunisian Dinar random",
5961 "1.00 Tunisian dinar random",
5962 "1.00 Tunisian dinars random",
5963 "1.00 Turkish Lira random",
5964 "1.00 Turkish Lira random",
5965 "1.00 Turkish lira random",
5966 "1.00 Turkmenistani Manat random",
5967 "1.00 Turkmenistani manat random",
5968 "1.00 Turkmenistani manat random",
5969 "1.00 US Dollar (Next day) random",
5970 "1.00 US Dollar (Same day) random",
5971 "1.00 US Dollar random",
5972 "1.00 US dollar (next day) random",
5973 "1.00 US dollar (same day) random",
5974 "1.00 US dollar random",
5975 "1.00 US dollars (next day) random",
5976 "1.00 US dollars (same day) random",
5977 "1.00 US dollars random",
5978 "1.00 Ugandan Shilling (1966\\u20131987) random",
5979 "1.00 Ugandan Shilling random",
5980 "1.00 Ugandan shilling (1966\\u20131987) random",
5981 "1.00 Ugandan shilling random",
5982 "1.00 Ugandan shillings (1966\\u20131987) random",
5983 "1.00 Ugandan shillings random",
5984 "1.00 Ukrainian Hryvnia random",
5985 "1.00 Ukrainian Karbovanets random",
5986 "1.00 Ukrainian hryvnia random",
5987 "1.00 Ukrainian hryvnias random",
5988 "1.00 Ukrainian karbovanets random",
5989 "1.00 Ukrainian karbovantsiv random",
5990 "1.00 Colombian Real Value Unit random",
5991 "1.00 United Arab Emirates Dirham random",
5992 "1.00 Unknown Currency random",
5993 "1.00 Uruguayan Peso (1975\\u20131993) random",
5994 "1.00 Uruguayan Peso random",
5995 "1.00 Uruguayan Peso (Indexed Units) random",
5996 "1.00 Uruguayan peso (1975\\u20131993) random",
5997 "1.00 Uruguayan peso (indexed units) random",
5998 "1.00 Uruguayan peso random",
5999 "1.00 Uruguayan pesos (1975\\u20131993) random",
6000 "1.00 Uruguayan pesos (indexed units) random",
6001 "1.00 Uzbekistani Som random",
6002 "1.00 Uzbekistani som random",
6003 "1.00 Uzbekistani som random",
6004 "1.00 Vanuatu Vatu random",
6005 "1.00 Vanuatu vatu random",
6006 "1.00 Vanuatu vatus random",
6007 "1.00 Venezuelan Bol\\u00edvar random",
6008 "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random",
6009 "1.00 Venezuelan bol\\u00edvar random",
6010 "1.00 Venezuelan bol\\u00edvars random",
6011 "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random",
6012 "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random",
6013 "1.00 Vietnamese Dong random",
6014 "1.00 Vietnamese dong random",
6015 "1.00 Vietnamese dong random",
6016 "1.00 WIR Euro random",
6017 "1.00 WIR Franc random",
6018 "1.00 WIR euro random",
6019 "1.00 WIR euros random",
6020 "1.00 WIR franc random",
6021 "1.00 WIR francs random",
6022 "1.00 Samoan Tala random",
6023 "1.00 Samoan tala random",
6024 "1.00 Samoan tala random",
6025 "1.00 Yemeni Dinar random",
6026 "1.00 Yemeni Rial random",
6027 "1.00 Yemeni dinar random",
6028 "1.00 Yemeni dinars random",
6029 "1.00 Yemeni rial random",
6030 "1.00 Yemeni rials random",
6031 "1.00 Yugoslavian Convertible Dinar (1990\\u20131992) random",
6032 "1.00 Yugoslavian Hard Dinar (1966\\u20131990) random",
6033 "1.00 Yugoslavian New Dinar (1994\\u20132002) random",
6034 "1.00 Yugoslavian convertible dinar (1990\\u20131992) random",
6035 "1.00 Yugoslavian convertible dinars (1990\\u20131992) random",
6036 "1.00 Yugoslavian hard dinar (1966\\u20131990) random",
6037 "1.00 Yugoslavian hard dinars (1966\\u20131990) random",
6038 "1.00 Yugoslavian new dinar (1994\\u20132002) random",
6039 "1.00 Yugoslavian new dinars (1994\\u20132002) random",
6040 "1.00 Zairean New Zaire (1993\\u20131998) random",
6041 "1.00 Zairean Zaire (1971\\u20131993) random",
6042 "1.00 Zairean new zaire (1993\\u20131998) random",
6043 "1.00 Zairean new zaires (1993\\u20131998) random",
6044 "1.00 Zairean zaire (1971\\u20131993) random",
6045 "1.00 Zairean zaires (1971\\u20131993) random",
6046 "1.00 Zambian Kwacha random",
6047 "1.00 Zambian kwacha random",
6048 "1.00 Zambian kwachas random",
6049 "1.00 Zimbabwean Dollar (1980\\u20132008) random",
6050 "1.00 Zimbabwean dollar (1980\\u20132008) random",
6051 "1.00 Zimbabwean dollars (1980\\u20132008) random",
6053 "1.00 euros random",
6054 "1.00 Turkish lira (1922\\u20132005) random",
6055 "1.00 special drawing rights random",
6056 "1.00 Colombian real value unit random",
6057 "1.00 Colombian real value units random",
6058 "1.00 unknown currency random",
6061 const char* WRONG_DATA[] = {
6062 // Following are missing one last char in the currency name
6063 "usd1.00", // case sensitive
6064 "1.00 Nicaraguan Cordob",
6065 "1.00 Namibian Dolla",
6066 "1.00 Namibian dolla",
6067 "1.00 Nepalese Rupe",
6068 "1.00 Nepalese rupe",
6069 "1.00 Netherlands Antillean Guilde",
6070 "1.00 Netherlands Antillean guilde",
6071 "1.00 Dutch Guilde",
6072 "1.00 Dutch guilde",
6073 "1.00 Israeli New Sheqe",
6074 "1.00 New Zealand Dolla",
6075 "1.00 New Zealand dolla",
6076 "1.00 Nicaraguan cordob",
6077 "1.00 Nigerian Nair",
6078 "1.00 Nigerian nair",
6079 "1.00 North Korean Wo",
6080 "1.00 North Korean wo",
6081 "1.00 Norwegian Kron",
6082 "1.00 Norwegian kron",
6098 "Afghan Afghan1.00",
6099 "Afghan Afghani (1927\\u201320021.00",
6102 "Algerian Dina1.00",
6103 "Andorran Peset1.00",
6104 "Angolan Kwanz1.00",
6105 "Angolan Kwanza (1977\\u201319901.00",
6106 "Angolan Readjusted Kwanza (1995\\u201319991.00",
6107 "Angolan New Kwanza (1990\\u201320001.00",
6108 "Argentine Austra1.00",
6109 "Argentine Pes1.00",
6110 "Argentine Peso (1983\\u201319851.00",
6113 "Australian Dolla1.00",
6114 "Austrian Schillin1.00",
6115 "Azerbaijani Mana1.00",
6116 "Azerbaijani Manat (1993\\u201320061.00",
6134 "Bahamian Dolla1.00",
6135 "Bahraini Dina1.00",
6136 "Bangladeshi Tak1.00",
6137 "Barbadian Dolla1.00",
6139 "Belarusian Ruble (1994\\u201319991.00",
6140 "Belarusian Rubl1.00",
6142 "Belgian Franc (convertible1.00",
6143 "Belgian Franc (financial1.00",
6145 "Bermudan Dolla1.00",
6146 "Bhutanese Ngultru1.00",
6147 "Bolivian Mvdo1.00",
6149 "Bolivian Bolivian1.00",
6150 "Bosnia-Herzegovina Convertible Mar1.00",
6151 "Bosnia-Herzegovina Dina1.00",
6152 "Botswanan Pul1.00",
6153 "Brazilian Cruzad1.00",
6154 "Brazilian Cruzado Nov1.00",
6155 "Brazilian Cruzeir1.00",
6156 "Brazilian Cruzeiro (1990\\u201319931.00",
6157 "Brazilian New Cruzeiro (1967\\u201319861.00",
6158 "Brazilian Rea1.00",
6159 "British Pound Sterlin1.00",
6161 "Bulgarian Hard Le1.00",
6164 "Burundian Fran1.00",
6179 "Cambodian Rie1.00",
6180 "Canadian Dolla1.00",
6181 "Cape Verdean Escud1.00",
6182 "Cayman Islands Dolla1.00",
6184 "Chilean Unit of Accoun1.00",
6186 "Colombian Pes1.00",
6188 "Congolese Fran1.00",
6189 "Costa Rican Col\\u00f31.00",
6190 "Croatian Dina1.00",
6194 "Czech Republic Korun1.00",
6195 "Czechoslovak Hard Korun1.00",
6205 "Djiboutian Fran1.00",
6207 "Dominican Pes1.00",
6216 "East Caribbean Dolla1.00",
6217 "East German Ostmar1.00",
6218 "Ecuadorian Sucr1.00",
6219 "Ecuadorian Unit of Constant Valu1.00",
6220 "Egyptian Poun1.00",
6222 "Salvadoran Col\\u00f31.00",
6223 "Equatorial Guinean Ekwel1.00",
6224 "Eritrean Nakf1.00",
6226 "Estonian Kroo1.00",
6227 "Ethiopian Bir1.00",
6229 "European Composite Uni1.00",
6230 "European Currency Uni1.00",
6231 "European Monetary Uni1.00",
6232 "European Unit of Account (XBC1.00",
6233 "European Unit of Account (XBD1.00",
6240 "Falkland Islands Poun1.00",
6243 "Finnish Markk1.00",
6246 "French Gold Fran1.00",
6247 "French UIC-Fran1.00",
6260 "Gambian Dalas1.00",
6261 "Georgian Kupon Lari1.00",
6264 "Ghanaian Cedi (1979\\u201320071.00",
6265 "Gibraltar Poun1.00",
6268 "Guatemalan Quetza1.00",
6271 "Guinea-Bissau Pes1.00",
6272 "Guyanaese Dolla1.00",
6278 "Haitian Gourd1.00",
6279 "Honduran Lempir1.00",
6280 "Hong Kong Dolla1.00",
6281 "Hungarian Forin1.00",
6290 "Icelandic Kron1.00",
6292 "Indonesian Rupia1.00",
6302 "Jamaican Dolla1.00",
6304 "Jordanian Dina1.00",
6315 "Kazakhstani Teng1.00",
6316 "Kenyan Shillin1.00",
6318 "Kyrgystani So1.00",
6330 "Lebanese Poun1.00",
6332 "Liberian Dolla1.00",
6334 "Lithuanian Lit1.00",
6335 "Lithuanian Talona1.00",
6336 "Luxembourgian Convertible Fran1.00",
6337 "Luxembourg Financial Fran1.00",
6338 "Luxembourgian Fran1.00",
6356 "Macanese Patac1.00",
6357 "Macedonian Dena1.00",
6358 "Malagasy Ariar1.00",
6359 "Malagasy Fran1.00",
6360 "Malawian Kwach1.00",
6361 "Malaysian Ringgi1.00",
6362 "Maldivian Rufiya1.00",
6367 "Mauritanian Ouguiy1.00",
6368 "Mauritian Rupe1.00",
6370 "Mexican Silver Peso (1861\\u201319921.00",
6371 "Mexican Investment Uni1.00",
6373 "Mongolian Tugri1.00",
6374 "Moroccan Dirha1.00",
6375 "Moroccan Fran1.00",
6376 "Mozambican Escud1.00",
6377 "Mozambican Metica1.00",
6389 "Namibian Dolla1.00",
6390 "Nepalese Rupe1.00",
6391 "Netherlands Antillean Guilde1.00",
6393 "Israeli New Sheqe1.00",
6394 "New Zealand Dolla1.00",
6395 "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00",
6396 "Nicaraguan C\\u00f3rdob1.00",
6397 "Nigerian Nair1.00",
6398 "North Korean Wo1.00",
6399 "Norwegian Kron1.00",
6402 "Old Mozambican Metica1.00",
6403 "Romanian Leu (1952\\u201320061.00",
6404 "Serbian Dinar (2002\\u201320061.00",
6405 "Sudanese Dinar (1992\\u201320071.00",
6406 "Sudanese Pound (1957\\u201319981.00",
6407 "Turkish Lira (1922\\u201320051.00",
6417 "Pakistani Rupe1.00",
6419 "Panamanian Balbo1.00",
6420 "Papua New Guinean Kin1.00",
6421 "Paraguayan Guaran1.00",
6423 "Peruvian Sol (1863\\u201319651.00",
6424 "Peruvian Sol Nuev1.00",
6425 "Philippine Pes1.00",
6428 "Polish Zloty (1950\\u201319951.00",
6429 "Portuguese Escud1.00",
6430 "Portuguese Guinea Escud1.00",
6441 "Rhodesian Dolla1.00",
6444 "Russian Ruble (1991\\u201319981.00",
6464 "St. Helena Poun1.00",
6465 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobr1.00",
6468 "Seychellois Rupe1.00",
6470 "Sierra Leonean Leon1.00",
6472 "Singapore Dolla1.00",
6474 "Slovenian Tola1.00",
6475 "Solomon Islands Dolla1.00",
6476 "Somali Shillin1.00",
6477 "South African Ran1.00",
6478 "South African Rand (financial1.00",
6479 "South Korean Wo1.00",
6481 "Spanish Peset1.00",
6482 "Spanish Peseta (A account1.00",
6483 "Spanish Peseta (convertible account1.00",
6484 "Special Drawing Right1.00",
6485 "Sri Lankan Rupe1.00",
6486 "Sudanese Poun1.00",
6487 "Surinamese Dolla1.00",
6488 "Surinamese Guilde1.00",
6489 "Swazi Lilangen1.00",
6504 "New Taiwan Dolla1.00",
6505 "Tajikistani Rubl1.00",
6506 "Tajikistani Somon1.00",
6507 "Tanzanian Shillin1.00",
6508 "Testing Currency Cod1.00",
6510 "Timorese Escud1.00",
6511 "Tongan Pa\\u20bbang1.00",
6512 "Trinidad & Tobago Dolla1.00",
6513 "Tunisian Dina1.00",
6515 "Turkmenistani Mana1.00",
6521 "US Dollar (Next day1.00",
6522 "US Dollar (Same day1.00",
6526 "Ugandan Shillin1.00",
6527 "Ugandan Shilling (1966\\u201319871.00",
6528 "Ukrainian Hryvni1.00",
6529 "Ukrainian Karbovanet1.00",
6530 "Colombian Real Value Uni1.00",
6531 "United Arab Emirates Dirha1.00",
6532 "Unknown Currenc1.00",
6534 "Uruguay Peso (1975\\u201319931.00",
6535 "Uruguay Peso Uruguay1.00",
6536 "Uruguay Peso (Indexed Units1.00",
6537 "Uzbekistani So1.00",
6543 "Venezuelan Bol\\u00edva1.00",
6544 "Venezuelan Bol\\u00edvar Fuert1.00",
6545 "Vietnamese Don1.00",
6546 "West African CFA Fran1.00",
6547 "Central African CFA Fran1.00",
6568 "Yugoslavian Convertible Dina1.00",
6569 "Yugoslavian Hard Dinar (1966\\u201319901.00",
6570 "Yugoslavian New Dina1.00",
6576 "Zairean New Zaire (1993\\u201319981.00",
6578 "Zambian Kwach1.00",
6579 "Zimbabwean Dollar (1980\\u201320081.00",
6587 Locale locale("en_US");
6588 for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
6589 UnicodeString formatted = ctou(DATA[i]);
6590 UErrorCode status = U_ZERO_ERROR;
6591 NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6592 if (numFmt != NULL && U_SUCCESS(status)) {
6593 ParsePosition parsePos;
6594 LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6595 if (parsePos.getIndex() > 0) {
6596 double doubleVal = currAmt->getNumber().getDouble(status);
6597 if ( doubleVal != 1.0 ) {
6598 errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal);
6601 errln("Failed to parse as currency: " + formatted);
6604 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6611 for (uint32_t i=0; i<UPRV_LENGTHOF(WRONG_DATA); ++i) {
6612 UnicodeString formatted = ctou(WRONG_DATA[i]);
6613 UErrorCode status = U_ZERO_ERROR;
6614 NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6615 if (numFmt != NULL && U_SUCCESS(status)) {
6616 ParsePosition parsePos;
6617 LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6618 if (parsePos.getIndex() > 0) {
6619 double doubleVal = currAmt->getNumber().getDouble(status);
6620 errln("Parsed as currency, should not have: " + formatted + " -> " + doubleVal);
6623 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6631 const char* attrString(int32_t);
6635 // std::cout << s.toUTF8String(ss)
6636 void NumberFormatTest::expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount,
6637 const UnicodeString& str) {
6641 if (tupleCount > 10) {
6642 assertTrue("internal error, tupleCount too large", FALSE);
6644 for (int i = 0; i < tupleCount; ++i) {
6650 while (iter.next(fp)) {
6652 int32_t id = fp.getField();
6653 int32_t start = fp.getBeginIndex();
6654 int32_t limit = fp.getEndIndex();
6656 // is there a logln using printf?
6658 sprintf(buf, "%24s %3d %3d %3d", attrString(id), id, start, limit);
6661 for (int i = 0; i < tupleCount; ++i) {
6665 if (values[i*3] == id &&
6666 values[i*3+1] == start &&
6667 values[i*3+2] == limit) {
6668 found[i] = ok = TRUE;
6673 assertTrue((UnicodeString)"found [" + id + "," + start + "," + limit + "]", ok);
6676 // check that all were found
6678 for (int i = 0; i < tupleCount; ++i) {
6681 assertTrue((UnicodeString) "missing [" + values[i*3] + "," + values[i*3+1] + "," + values[i*3+2] + "]", found[i]);
6684 assertTrue("no expected values were missing", ok);
6687 void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit,
6688 const UnicodeString& str) {
6690 assertTrue((UnicodeString)"id " + id + " == " + pos.getField(), id == pos.getField());
6691 assertTrue((UnicodeString)"begin " + start + " == " + pos.getBeginIndex(), start == pos.getBeginIndex());
6692 assertTrue((UnicodeString)"end " + limit + " == " + pos.getEndIndex(), limit == pos.getEndIndex());
6695 void NumberFormatTest::TestFieldPositionIterator() {
6697 UErrorCode status = U_ZERO_ERROR;
6698 FieldPositionIterator iter1;
6699 FieldPositionIterator iter2;
6702 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(status);
6703 if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6705 double num = 1234.56;
6709 assertTrue((UnicodeString)"self==", iter1 == iter1);
6710 assertTrue((UnicodeString)"iter1==iter2", iter1 == iter2);
6712 decFmt->format(num, str1, &iter1, status);
6713 assertTrue((UnicodeString)"iter1 != iter2", iter1 != iter2);
6714 decFmt->format(num, str2, &iter2, status);
6715 assertTrue((UnicodeString)"iter1 == iter2 (2)", iter1 == iter2);
6717 assertTrue((UnicodeString)"iter1 != iter2 (2)", iter1 != iter2);
6719 assertTrue((UnicodeString)"iter1 == iter2 (3)", iter1 == iter2);
6721 // should format ok with no iterator
6723 decFmt->format(num, str2, NULL, status);
6724 assertEquals("null fpiter", str1, str2);
6729 void NumberFormatTest::TestFormatAttributes() {
6730 Locale locale("en_US");
6731 UErrorCode status = U_ZERO_ERROR;
6732 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6733 if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6734 double val = 12345.67;
6737 int32_t expected[] = {
6738 UNUM_CURRENCY_FIELD, 0, 1,
6739 UNUM_GROUPING_SEPARATOR_FIELD, 3, 4,
6740 UNUM_INTEGER_FIELD, 1, 7,
6741 UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8,
6742 UNUM_FRACTION_FIELD, 8, 10,
6744 int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
6746 FieldPositionIterator posIter;
6747 UnicodeString result;
6748 decFmt->format(val, result, &posIter, status);
6749 expectPositions(posIter, expected, tupleCount, result);
6752 FieldPosition fp(UNUM_INTEGER_FIELD);
6753 UnicodeString result;
6754 decFmt->format(val, result, fp);
6755 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 7, result);
6758 FieldPosition fp(UNUM_FRACTION_FIELD);
6759 UnicodeString result;
6760 decFmt->format(val, result, fp);
6761 expectPosition(fp, UNUM_FRACTION_FIELD, 8, 10, result);
6765 decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_SCIENTIFIC, status);
6768 int32_t expected[] = {
6769 UNUM_SIGN_FIELD, 0, 1,
6770 UNUM_INTEGER_FIELD, 1, 2,
6771 UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3,
6772 UNUM_FRACTION_FIELD, 3, 5,
6773 UNUM_EXPONENT_SYMBOL_FIELD, 5, 6,
6774 UNUM_EXPONENT_SIGN_FIELD, 6, 7,
6775 UNUM_EXPONENT_FIELD, 7, 8
6777 int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
6779 FieldPositionIterator posIter;
6780 UnicodeString result;
6781 decFmt->format(val, result, &posIter, status);
6782 expectPositions(posIter, expected, tupleCount, result);
6785 FieldPosition fp(UNUM_INTEGER_FIELD);
6786 UnicodeString result;
6787 decFmt->format(val, result, fp);
6788 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 2, result);
6791 FieldPosition fp(UNUM_FRACTION_FIELD);
6792 UnicodeString result;
6793 decFmt->format(val, result, fp);
6794 expectPosition(fp, UNUM_FRACTION_FIELD, 3, 5, result);
6801 const char* attrString(int32_t attrId) {
6803 case UNUM_INTEGER_FIELD: return "integer";
6804 case UNUM_FRACTION_FIELD: return "fraction";
6805 case UNUM_DECIMAL_SEPARATOR_FIELD: return "decimal separator";
6806 case UNUM_EXPONENT_SYMBOL_FIELD: return "exponent symbol";
6807 case UNUM_EXPONENT_SIGN_FIELD: return "exponent sign";
6808 case UNUM_EXPONENT_FIELD: return "exponent";
6809 case UNUM_GROUPING_SEPARATOR_FIELD: return "grouping separator";
6810 case UNUM_CURRENCY_FIELD: return "currency";
6811 case UNUM_PERCENT_FIELD: return "percent";
6812 case UNUM_PERMILL_FIELD: return "permille";
6813 case UNUM_SIGN_FIELD: return "sign";
6819 // Test formatting & parsing of big decimals.
6820 // API test, not a comprehensive test.
6821 // See DecimalFormatTest/DataDrivenTests
6823 #define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \
6824 __FILE__, __LINE__, u_errorName(status));}
6825 #define ASSERT_EQUALS(expected, actual) {if ((expected) != (actual)) \
6826 errln("file %s, line %d: %s != %s", __FILE__, __LINE__, #expected, #actual);}
6828 static UBool operator != (const char *s1, UnicodeString &s2) {
6829 // This function lets ASSERT_EQUALS("literal", UnicodeString) work.
6830 UnicodeString us1(s1);
6834 void NumberFormatTest::TestDecimal() {
6836 UErrorCode status = U_ZERO_ERROR;
6837 Formattable f("12.345678999987654321E666", status);
6838 ASSERT_SUCCESS(status);
6839 StringPiece s = f.getDecimalNumber(status);
6840 ASSERT_SUCCESS(status);
6841 ASSERT_EQUALS("1.2345678999987654321E+667", s);
6842 //printf("%s\n", s.data());
6846 UErrorCode status = U_ZERO_ERROR;
6847 Formattable f1("this is not a number", status);
6848 ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR, status);
6852 UErrorCode status = U_ZERO_ERROR;
6854 f.setDecimalNumber("123.45", status);
6855 ASSERT_SUCCESS(status);
6856 ASSERT_EQUALS( Formattable::kDouble, f.getType());
6857 ASSERT_EQUALS(123.45, f.getDouble());
6858 ASSERT_EQUALS(123.45, f.getDouble(status));
6859 ASSERT_SUCCESS(status);
6860 ASSERT_EQUALS("123.45", f.getDecimalNumber(status));
6861 ASSERT_SUCCESS(status);
6863 f.setDecimalNumber("4.5678E7", status);
6866 ASSERT_EQUALS(45678000, n);
6868 status = U_ZERO_ERROR;
6869 f.setDecimalNumber("-123", status);
6870 ASSERT_SUCCESS(status);
6871 ASSERT_EQUALS( Formattable::kLong, f.getType());
6872 ASSERT_EQUALS(-123, f.getLong());
6873 ASSERT_EQUALS(-123, f.getLong(status));
6874 ASSERT_SUCCESS(status);
6875 ASSERT_EQUALS("-123", f.getDecimalNumber(status));
6876 ASSERT_SUCCESS(status);
6878 status = U_ZERO_ERROR;
6879 f.setDecimalNumber("1234567890123", status); // Number too big for 32 bits
6880 ASSERT_SUCCESS(status);
6881 ASSERT_EQUALS( Formattable::kInt64, f.getType());
6882 ASSERT_EQUALS(1234567890123LL, f.getInt64());
6883 ASSERT_EQUALS(1234567890123LL, f.getInt64(status));
6884 ASSERT_SUCCESS(status);
6885 ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status));
6886 ASSERT_SUCCESS(status);
6890 UErrorCode status = U_ZERO_ERROR;
6891 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6892 if (U_FAILURE(status) || fmtr == NULL) {
6893 dataerrln("Unable to create NumberFormat");
6895 UnicodeString formattedResult;
6896 StringPiece num("244444444444444444444444444444444444446.4");
6897 fmtr->format(num, formattedResult, NULL, status);
6898 ASSERT_SUCCESS(status);
6899 ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult);
6900 //std::string ss; std::cout << formattedResult.toUTF8String(ss);
6906 // Check formatting a DigitList. DigitList is internal, but this is
6907 // a critical interface that must work.
6908 UErrorCode status = U_ZERO_ERROR;
6909 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6910 if (U_FAILURE(status) || fmtr == NULL) {
6911 dataerrln("Unable to create NumberFormat");
6913 UnicodeString formattedResult;
6915 StringPiece num("123.4566666666666666666666666666666666621E+40");
6916 dl.set(num, status);
6917 ASSERT_SUCCESS(status);
6918 fmtr->format(dl, formattedResult, NULL, status);
6919 ASSERT_SUCCESS(status);
6920 ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult);
6922 status = U_ZERO_ERROR;
6924 dl.set(num, status);
6925 FieldPosition pos(NumberFormat::FRACTION_FIELD);
6926 ASSERT_SUCCESS(status);
6927 formattedResult.remove();
6928 fmtr->format(dl, formattedResult, pos, status);
6929 ASSERT_SUCCESS(status);
6930 ASSERT_EQUALS("666.666", formattedResult);
6931 ASSERT_EQUALS(4, pos.getBeginIndex());
6932 ASSERT_EQUALS(7, pos.getEndIndex());
6938 // Check a parse with a formatter with a multiplier.
6939 UErrorCode status = U_ZERO_ERROR;
6940 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT, status);
6941 if (U_FAILURE(status) || fmtr == NULL) {
6942 dataerrln("Unable to create NumberFormat");
6944 UnicodeString input = "1.84%";
6946 fmtr->parse(input, result, status);
6947 ASSERT_SUCCESS(status);
6948 ASSERT_EQUALS(0, strcmp("0.0184", result.getDecimalNumber(status).data()));
6949 //std::cout << result.getDecimalNumber(status).data();
6954 #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6956 * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6960 // Check that a parse returns a decimal number with full accuracy
6961 UErrorCode status = U_ZERO_ERROR;
6962 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6963 if (U_FAILURE(status) || fmtr == NULL) {
6964 dataerrln("Unable to create NumberFormat");
6966 UnicodeString input = "1.002200044400088880000070000";
6968 fmtr->parse(input, result, status);
6969 ASSERT_SUCCESS(status);
6970 ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result.getDecimalNumber(status).data()));
6971 ASSERT_EQUALS(1.00220004440008888, result.getDouble());
6972 //std::cout << result.getDecimalNumber(status).data();
6980 void NumberFormatTest::TestCurrencyFractionDigits() {
6981 UErrorCode status = U_ZERO_ERROR;
6982 UnicodeString text1, text2;
6983 double value = 99.12345;
6985 // Create currenct instance
6986 NumberFormat* fmt = NumberFormat::createCurrencyInstance("ja_JP", status);
6987 if (U_FAILURE(status) || fmt == NULL) {
6988 dataerrln("Unable to create NumberFormat");
6990 fmt->format(value, text1);
6992 // Reset the same currency and format the test value again
6993 fmt->setCurrency(fmt->getCurrency(), status);
6994 ASSERT_SUCCESS(status);
6995 fmt->format(value, text2);
6997 if (text1 != text2) {
6998 errln((UnicodeString)"NumberFormat::format() should return the same result - text1="
6999 + text1 + " text2=" + text2);
7005 void NumberFormatTest::TestExponentParse() {
7007 UErrorCode status = U_ZERO_ERROR;
7009 ParsePosition parsePos(0);
7011 // set the exponent symbol
7012 status = U_ZERO_ERROR;
7013 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status);
7014 if(U_FAILURE(status)) {
7015 dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)");
7019 // create format instance
7020 status = U_ZERO_ERROR;
7021 DecimalFormat fmt("#####", symbols, status);
7022 if(U_FAILURE(status)) {
7023 errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
7027 fmt.parse("5.06e-27", result, parsePos);
7028 if(result.getType() != Formattable::kDouble &&
7029 result.getDouble() != 5.06E-27 &&
7030 parsePos.getIndex() != 8
7033 errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i",
7034 result.getDouble(), parsePos.getIndex());
7038 void NumberFormatTest::TestExplicitParents() {
7040 /* Test that number formats are properly inherited from es_419 */
7041 /* These could be subject to change if the CLDR data changes */
7042 static const char* parentLocaleTests[][2]= {
7043 /* locale ID */ /* expected */
7044 {"es_CO", "1.250,75" },
7045 {"es_ES", "1.250,75" },
7046 {"es_GQ", "1.250,75" },
7047 {"es_MX", "1,250.75" },
7048 {"es_US", "1,250.75" },
7049 {"es_VE", "1.250,75" },
7054 for(int i=0; i < UPRV_LENGTHOF(parentLocaleTests); i++){
7055 UErrorCode status = U_ZERO_ERROR;
7056 const char *localeID = parentLocaleTests[i][0];
7057 UnicodeString expected(parentLocaleTests[i][1], -1, US_INV);
7058 expected = expected.unescape();
7060 uloc_canonicalize(localeID, loc, 256, &status);
7061 NumberFormat *fmt= NumberFormat::createInstance(Locale(loc), status);
7062 if(U_FAILURE(status)){
7063 dataerrln("Could not create number formatter for locale %s - %s",localeID, u_errorName(status));
7067 fmt->format(1250.75, s);
7069 errln(UnicodeString("FAIL: Expected: ")+expected
7070 + UnicodeString(" Got: ") + s
7071 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
7073 if (U_FAILURE(status)){
7074 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
7082 * Test available numbering systems API.
7084 void NumberFormatTest::TestAvailableNumberingSystems() {
7085 UErrorCode status = U_ZERO_ERROR;
7086 StringEnumeration *availableNumberingSystems = NumberingSystem::getAvailableNames(status);
7087 CHECK_DATA(status, "NumberingSystem::getAvailableNames()")
7089 int32_t nsCount = availableNumberingSystems->count(status);
7090 if ( nsCount < 74 ) {
7091 errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 74, got %d",nsCount);
7094 /* A relatively simple test of the API. We call getAvailableNames() and cycle through */
7095 /* each name returned, attempting to create a numbering system based on that name and */
7096 /* verifying that the name returned from the resulting numbering system is the same */
7097 /* one that we initially thought. */
7100 for ( int32_t i = 0 ; i < nsCount ; i++ ) {
7101 const char *nsname = availableNumberingSystems->next(&len,status);
7102 NumberingSystem* ns = NumberingSystem::createInstanceByName(nsname,status);
7103 logln("OK for ns = %s",nsname);
7104 if ( uprv_strcmp(nsname,ns->getName()) ) {
7105 errln("FAIL: Numbering system name didn't match for name = %s\n",nsname);
7111 delete availableNumberingSystems;
7115 NumberFormatTest::Test9087(void)
7117 U_STRING_DECL(pattern,"#",1);
7118 U_STRING_INIT(pattern,"#",1);
7120 U_STRING_DECL(infstr,"INF",3);
7121 U_STRING_INIT(infstr,"INF",3);
7123 U_STRING_DECL(nanstr,"NAN",3);
7124 U_STRING_INIT(nanstr,"NAN",3);
7126 UChar outputbuf[50] = {0};
7127 UErrorCode status = U_ZERO_ERROR;
7128 UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status);
7129 if ( U_FAILURE(status) ) {
7130 dataerrln("FAIL: error in unum_open() - %s", u_errorName(status));
7134 unum_setSymbol(fmt,UNUM_INFINITY_SYMBOL,infstr,3,&status);
7135 unum_setSymbol(fmt,UNUM_NAN_SYMBOL,nanstr,3,&status);
7136 if ( U_FAILURE(status) ) {
7137 errln("FAIL: error setting symbols");
7140 double inf = uprv_getInfinity();
7142 unum_setAttribute(fmt,UNUM_ROUNDING_MODE,UNUM_ROUND_HALFEVEN);
7143 unum_setDoubleAttribute(fmt,UNUM_ROUNDING_INCREMENT,0);
7145 UFieldPosition position = { 0, 0, 0};
7146 unum_formatDouble(fmt,inf,outputbuf,50,&position,&status);
7148 if ( u_strcmp(infstr, outputbuf)) {
7149 errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf);
7155 #include "dcfmtimp.h"
7157 void NumberFormatTest::TestFormatFastpaths() {
7158 #if UCONFIG_FORMAT_FASTPATHS_49
7159 logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
7160 sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
7161 if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
7162 errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
7163 } else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
7164 infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat));
7167 infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
7170 // get some additional case
7172 UErrorCode status=U_ZERO_ERROR;
7173 DecimalFormat df(UnicodeString("0000",""),status);
7174 if (U_FAILURE(status)) {
7175 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
7177 int64_t long_number = 1;
7178 UnicodeString expect = "0001";
7179 UnicodeString result;
7181 df.format(long_number, result, pos);
7182 if(U_FAILURE(status)||expect!=result) {
7183 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
7185 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
7190 UErrorCode status=U_ZERO_ERROR;
7191 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
7192 if (U_FAILURE(status)) {
7193 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
7195 int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
7197 // memcpy(bits,&long_number,8);
7198 // for(int i=0;i<8;i++) {
7199 // logln("bits: %02X", (unsigned int)bits[i]);
7201 UnicodeString expect = "-9223372036854775808";
7202 UnicodeString result;
7204 df.format(long_number, result, pos);
7205 if(U_FAILURE(status)||expect!=result) {
7206 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
7208 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
7213 UErrorCode status=U_ZERO_ERROR;
7214 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
7215 if (U_FAILURE(status)) {
7216 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
7218 int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
7220 // memcpy(bits,&long_number,8);
7221 // for(int i=0;i<8;i++) {
7222 // logln("bits: %02X", (unsigned int)bits[i]);
7224 UnicodeString expect = "9223372036854775807";
7225 UnicodeString result;
7227 df.format(long_number, result, pos);
7228 if(U_FAILURE(status)||expect!=result) {
7229 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
7231 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
7236 UErrorCode status=U_ZERO_ERROR;
7237 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
7238 if (U_FAILURE(status)) {
7239 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
7241 int64_t long_number = 0;
7243 // memcpy(bits,&long_number,8);
7244 // for(int i=0;i<8;i++) {
7245 // logln("bits: %02X", (unsigned int)bits[i]);
7247 UnicodeString expect = "0000000000000000000";
7248 UnicodeString result;
7250 df.format(long_number, result, pos);
7251 if(U_FAILURE(status)||expect!=result) {
7252 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
7254 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
7259 UErrorCode status=U_ZERO_ERROR;
7260 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
7261 if (U_FAILURE(status)) {
7262 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
7264 int64_t long_number = U_INT64_MIN + 1;
7265 UnicodeString expect = "-9223372036854775807";
7266 UnicodeString result;
7268 df.format(long_number, result, pos);
7269 if(U_FAILURE(status)||expect!=result) {
7270 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
7272 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
7279 void NumberFormatTest::TestFormattableSize(void) {
7280 if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) {
7281 errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
7282 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
7283 } else if(sizeof(FmtStackData) < UNUM_INTERNAL_STACKARRAY_SIZE) {
7284 logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
7285 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
7287 logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
7288 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
7292 UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line, Formattable &f) {
7293 UnicodeString fileLine = UnicodeString(file)+UnicodeString(":")+line+UnicodeString(": ");
7295 UFormattable *u = f.toUFormattable();
7298 errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
7301 logln("%s:%d: comparing Formattable with UFormattable", file, line);
7302 logln(fileLine + toString(f));
7304 UErrorCode status = U_ZERO_ERROR;
7305 UErrorCode valueStatus = U_ZERO_ERROR;
7306 UFormattableType expectUType = UFMT_COUNT; // invalid
7308 UBool triedExact = FALSE; // did we attempt an exact comparison?
7309 UBool exactMatch = FALSE; // was the exact comparison true?
7311 switch( f.getType() ) {
7312 case Formattable::kDate:
7313 expectUType = UFMT_DATE;
7314 exactMatch = (f.getDate()==ufmt_getDate(u, &valueStatus));
7317 case Formattable::kDouble:
7318 expectUType = UFMT_DOUBLE;
7319 exactMatch = (f.getDouble()==ufmt_getDouble(u, &valueStatus));
7322 case Formattable::kLong:
7323 expectUType = UFMT_LONG;
7324 exactMatch = (f.getLong()==ufmt_getLong(u, &valueStatus));
7327 case Formattable::kString:
7328 expectUType = UFMT_STRING;
7333 const UChar* uch = ufmt_getUChars(u, &len, &valueStatus);
7334 if(U_SUCCESS(valueStatus)) {
7335 UnicodeString str2(uch, len);
7336 assertTrue("UChar* NULL-terminated", uch[len]==0);
7337 exactMatch = (str == str2);
7342 case Formattable::kArray:
7343 expectUType = UFMT_ARRAY;
7346 int32_t count = ufmt_getArrayLength(u, &valueStatus);
7348 const Formattable *array2 = f.getArray(count2);
7349 exactMatch = assertEquals(fileLine + " array count", count, count2);
7352 for(int i=0;U_SUCCESS(valueStatus) && i<count;i++) {
7353 UFormattable *uu = ufmt_getArrayItemByIndex(u, i, &valueStatus);
7354 if(*Formattable::fromUFormattable(uu) != (array2[i])) {
7355 errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file, line, i,
7356 (const void*)Formattable::fromUFormattable(uu), (const void*)&(array2[i]));
7359 if(!testFormattableAsUFormattable("(sub item)",i,*Formattable::fromUFormattable(uu))) {
7367 case Formattable::kInt64:
7368 expectUType = UFMT_INT64;
7369 exactMatch = (f.getInt64()==ufmt_getInt64(u, &valueStatus));
7372 case Formattable::kObject:
7373 expectUType = UFMT_OBJECT;
7374 exactMatch = (f.getObject()==ufmt_getObject(u, &valueStatus));
7378 UFormattableType uType = ufmt_getType(u, &status);
7380 if(U_FAILURE(status)) {
7381 errln("%s:%d: Error calling ufmt_getType - %s", file, line, u_errorName(status));
7385 if(uType != expectUType) {
7386 errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file, line, (int) uType, (int) expectUType);
7390 if(U_FAILURE(valueStatus)) {
7391 errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file, line, u_errorName(valueStatus));
7392 } else if(!exactMatch) {
7393 errln("%s:%d: failed exact match for the Formattable type", file, line);
7395 logln("%s:%d: exact match OK", file, line);
7398 logln("%s:%d: note, did not attempt exact match for this formattable type", file, line);
7401 if( assertEquals(fileLine + " isNumeric()", f.isNumeric(), ufmt_isNumeric(u))
7403 UErrorCode convStatus = U_ZERO_ERROR;
7405 if(uType != UFMT_INT64) { // may fail to compare
7406 assertTrue(fileLine + " as doubles ==", f.getDouble(convStatus)==ufmt_getDouble(u, &convStatus));
7409 if( assertSuccess(fileLine + " (numeric conversion status)", convStatus) ) {
7410 StringPiece fDecNum = f.getDecimalNumber(convStatus);
7413 const char *decNumChars = ufmt_getDecNumChars(u, &len, &convStatus);
7416 char decNumChars[200];
7417 int32_t len = ufmt_getDecNumChars(u, decNumChars, 200, &convStatus);
7420 if( assertSuccess(fileLine + " (decNumbers conversion)", convStatus) ) {
7421 logln(fileLine + decNumChars);
7422 assertEquals(fileLine + " decNumChars length==", len, fDecNum.length());
7423 assertEquals(fileLine + " decNumChars digits", decNumChars, fDecNum.data());
7426 UErrorCode int64ConversionF = U_ZERO_ERROR;
7427 int64_t l = f.getInt64(int64ConversionF);
7428 UErrorCode int64ConversionU = U_ZERO_ERROR;
7429 int64_t r = ufmt_getInt64(u, &int64ConversionU);
7432 && ( uType != UFMT_INT64 ) // int64 better not overflow
7433 && (U_INVALID_FORMAT_ERROR==int64ConversionU)
7434 && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) {
7435 logln("%s:%d: OK: 64 bit overflow", file, line);
7437 assertEquals(fileLine + " as int64 ==", l, r);
7438 assertSuccess(fileLine + " Formattable.getnt64()", int64ConversionF);
7439 assertSuccess(fileLine + " ufmt_getInt64()", int64ConversionU);
7443 return exactMatch || !triedExact;
7446 void NumberFormatTest::TestUFormattable(void) {
7448 // test that a default formattable is equal to Formattable()
7449 UErrorCode status = U_ZERO_ERROR;
7450 LocalUFormattablePointer defaultUFormattable(ufmt_open(&status));
7451 assertSuccess("calling umt_open", status);
7452 Formattable defaultFormattable;
7453 assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
7455 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
7456 assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
7458 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
7459 assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable",
7461 == *(Formattable::fromUFormattable(defaultFormattable.toUFormattable()))));
7462 assertTrue((UnicodeString)"comparing &Formattable() round tripped through UFormattable",
7463 ((&defaultFormattable)
7464 == Formattable::fromUFormattable(defaultFormattable.toUFormattable())));
7465 assertFalse((UnicodeString)"comparing &Formattable() with ufmt_open()",
7466 ((&defaultFormattable)
7467 == Formattable::fromUFormattable(defaultUFormattable.getAlias())));
7468 testFormattableAsUFormattable(__FILE__, __LINE__, defaultFormattable);
7470 // test some random Formattables
7472 Formattable f(ucal_getNow(), Formattable::kIsDate);
7473 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7476 Formattable f((double)1.61803398874989484820); // golden ratio
7477 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7480 Formattable f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
7481 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7484 Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/
7485 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7488 Formattable f("Hello world."); // should be invariant?
7489 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7492 UErrorCode status2 = U_ZERO_ERROR;
7493 Formattable f(StringPiece("73476730924573500000000.0"), status2); // weight of the moon, kg
7494 assertSuccess("Constructing a StringPiece", status2);
7495 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7498 UErrorCode status2 = U_ZERO_ERROR;
7499 UObject *obj = new Locale();
7501 assertSuccess("Constructing a Formattable from a default constructed Locale()", status2);
7502 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7505 const Formattable array[] = {
7506 Formattable(ucal_getNow(), Formattable::kIsDate),
7507 Formattable((int32_t)4),
7508 Formattable((double)1.234),
7511 Formattable fa(array, 3);
7512 testFormattableAsUFormattable(__FILE__, __LINE__, fa);
7516 void NumberFormatTest::TestSignificantDigits(void) {
7523 123.44501, -123.44501,
7524 0.001234, -0.001234,
7525 0.00000000123, -0.00000000123,
7526 0.0000000000000000000123, -0.0000000000000000000123,
7528 0.0000000012344501, -0.0000000012344501,
7529 123445.01, -123445.01,
7530 12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
7532 const char* expected[] = {
7537 "123.45", "-123.45",
7538 "123.45", "-123.45",
7539 "0.001234", "-0.001234",
7540 "0.00000000123", "-0.00000000123",
7541 "0.0000000000000000000123", "-0.0000000000000000000123",
7543 "0.0000000012345", "-0.0000000012345",
7544 "123450", "-123450",
7545 "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
7548 UErrorCode status = U_ZERO_ERROR;
7549 Locale locale("en_US");
7550 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7551 NumberFormat::createInstance(locale, status)));
7552 CHECK_DATA(status,"NumberFormat::createInstance")
7554 numberFormat->setSignificantDigitsUsed(TRUE);
7555 numberFormat->setMinimumSignificantDigits(3);
7556 numberFormat->setMaximumSignificantDigits(5);
7557 numberFormat->setGroupingUsed(false);
7559 UnicodeString result;
7560 UnicodeString expectedResult;
7561 for (unsigned int i = 0; i < UPRV_LENGTHOF(input); ++i) {
7562 numberFormat->format(input[i], result);
7563 UnicodeString expectedResult(expected[i]);
7564 if (result != expectedResult) {
7565 errln((UnicodeString)"Expected: '" + expectedResult + "' got '" + result);
7571 void NumberFormatTest::TestShowZero() {
7572 UErrorCode status = U_ZERO_ERROR;
7573 Locale locale("en_US");
7574 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7575 NumberFormat::createInstance(locale, status)));
7576 CHECK_DATA(status, "NumberFormat::createInstance")
7578 numberFormat->setSignificantDigitsUsed(TRUE);
7579 numberFormat->setMaximumSignificantDigits(3);
7581 UnicodeString result;
7582 numberFormat->format(0.0, result);
7583 if (result != "0") {
7584 errln((UnicodeString)"Expected: 0, got " + result);
7588 void NumberFormatTest::TestBug9936() {
7589 UErrorCode status = U_ZERO_ERROR;
7590 Locale locale("en_US");
7591 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7592 NumberFormat::createInstance(locale, status)));
7593 if (U_FAILURE(status)) {
7594 dataerrln("File %s, Line %d: status = %s.\n", __FILE__, __LINE__, u_errorName(status));
7598 if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7599 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7601 numberFormat->setSignificantDigitsUsed(TRUE);
7602 if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7603 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7606 numberFormat->setSignificantDigitsUsed(FALSE);
7607 if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7608 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7611 numberFormat->setMinimumSignificantDigits(3);
7612 if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7613 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7616 numberFormat->setSignificantDigitsUsed(FALSE);
7617 numberFormat->setMaximumSignificantDigits(6);
7618 if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7619 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7624 void NumberFormatTest::TestParseNegativeWithFaLocale() {
7625 UErrorCode status = U_ZERO_ERROR;
7626 DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("fa", status);
7627 CHECK_DATA(status, "NumberFormat::createInstance")
7628 test->setLenient(TRUE);
7631 UnicodeString value("\\u200e-0,5");
7632 value = value.unescape();
7633 test->parse(value, af, ppos);
7634 if (ppos.getIndex() == 0) {
7635 errln("Expected -0,5 to parse for Farsi.");
7640 void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() {
7641 UErrorCode status = U_ZERO_ERROR;
7642 DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("en", status);
7643 CHECK_DATA(status, "NumberFormat::createInstance")
7644 test->setLenient(TRUE);
7647 UnicodeString value("\\u208B0.5");
7648 value = value.unescape();
7649 test->parse(value, af, ppos);
7650 if (ppos.getIndex() == 0) {
7651 errln(UnicodeString("Expected ") + value + UnicodeString(" to parse."));
7656 void NumberFormatTest::TestCustomCurrencySignAndSeparator() {
7657 UErrorCode status = U_ZERO_ERROR;
7658 DecimalFormatSymbols custom(Locale::getUS(), status);
7659 CHECK(status, "DecimalFormatSymbols constructor");
7661 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "*");
7662 custom.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, "^");
7663 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, ":");
7665 UnicodeString pat(" #,##0.00");
7666 pat.insert(0, (UChar)0x00A4);
7668 DecimalFormat fmt(pat, custom, status);
7669 CHECK(status, "DecimalFormat constructor");
7671 UnicodeString numstr("* 1^234:56");
7672 expect2(fmt, (Formattable)((double)1234.56), numstr);
7676 const char * locale;
7678 UnicodeString numString;
7680 } SignsAndMarksItem;
7683 void NumberFormatTest::TestParseSignsAndMarks() {
7684 const SignsAndMarksItem items[] = {
7685 // locale lenient numString value
7686 { "en", FALSE, CharsToUnicodeString("12"), 12 },
7687 { "en", TRUE, CharsToUnicodeString("12"), 12 },
7688 { "en", FALSE, CharsToUnicodeString("-23"), -23 },
7689 { "en", TRUE, CharsToUnicodeString("-23"), -23 },
7690 { "en", TRUE, CharsToUnicodeString("- 23"), -23 },
7691 { "en", FALSE, CharsToUnicodeString("\\u200E-23"), -23 },
7692 { "en", TRUE, CharsToUnicodeString("\\u200E-23"), -23 },
7693 { "en", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 },
7695 { "en@numbers=arab", FALSE, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7696 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7697 { "en@numbers=arab", FALSE, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7698 { "en@numbers=arab", TRUE, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7699 { "en@numbers=arab", TRUE, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7700 { "en@numbers=arab", FALSE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7701 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7702 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7704 { "en@numbers=arabext", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7705 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7706 { "en@numbers=arabext", FALSE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7707 { "en@numbers=arabext", TRUE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7708 { "en@numbers=arabext", TRUE, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7709 { "en@numbers=arabext", FALSE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7710 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7711 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7713 { "he", FALSE, CharsToUnicodeString("12"), 12 },
7714 { "he", TRUE, CharsToUnicodeString("12"), 12 },
7715 { "he", FALSE, CharsToUnicodeString("-23"), -23 },
7716 { "he", TRUE, CharsToUnicodeString("-23"), -23 },
7717 { "he", TRUE, CharsToUnicodeString("- 23"), -23 },
7718 { "he", FALSE, CharsToUnicodeString("\\u200E-23"), -23 },
7719 { "he", TRUE, CharsToUnicodeString("\\u200E-23"), -23 },
7720 { "he", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 },
7722 { "ar", FALSE, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7723 { "ar", TRUE, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7724 { "ar", FALSE, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7725 { "ar", TRUE, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7726 { "ar", TRUE, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7727 { "ar", FALSE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7728 { "ar", TRUE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7729 { "ar", TRUE, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7731 { "ar_MA", FALSE, CharsToUnicodeString("12"), 12 },
7732 { "ar_MA", TRUE, CharsToUnicodeString("12"), 12 },
7733 { "ar_MA", FALSE, CharsToUnicodeString("-23"), -23 },
7734 { "ar_MA", TRUE, CharsToUnicodeString("-23"), -23 },
7735 { "ar_MA", TRUE, CharsToUnicodeString("- 23"), -23 },
7736 { "ar_MA", FALSE, CharsToUnicodeString("\\u200E-23"), -23 },
7737 { "ar_MA", TRUE, CharsToUnicodeString("\\u200E-23"), -23 },
7738 { "ar_MA", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 },
7740 { "fa", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7741 { "fa", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7742 { "fa", FALSE, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7743 { "fa", TRUE, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7744 { "fa", TRUE, CharsToUnicodeString("\\u2212 \\u06F6\\u06F7"), -67 },
7745 { "fa", FALSE, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7746 { "fa", TRUE, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7747 { "fa", TRUE, CharsToUnicodeString("\\u200E\\u2212\\u200E \\u06F6\\u06F7"), -67 },
7749 { "ps", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7750 { "ps", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7751 { "ps", FALSE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7752 { "ps", TRUE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7753 { "ps", TRUE, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7754 { "ps", FALSE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7755 { "ps", TRUE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7756 { "ps", TRUE, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7757 { "ps", FALSE, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7758 { "ps", TRUE, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7759 { "ps", TRUE, CharsToUnicodeString("-\\u200E \\u06F6\\u06F7"), -67 },
7761 { NULL, 0, UnicodeString(""), 0 },
7764 const SignsAndMarksItem * itemPtr;
7765 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
7766 UErrorCode status = U_ZERO_ERROR;
7767 NumberFormat *numfmt = NumberFormat::createInstance(Locale(itemPtr->locale), status);
7768 if (U_SUCCESS(status)) {
7769 numfmt->setLenient(itemPtr->lenient);
7772 numfmt->parse(itemPtr->numString, fmtobj, ppos);
7773 if (ppos.getIndex() == itemPtr->numString.length()) {
7774 double parsedValue = fmtobj.getDouble(status);
7775 if (U_FAILURE(status) || parsedValue != itemPtr->value) {
7776 errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives value " + parsedValue);
7779 errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives position " + ppos.getIndex());
7782 dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr->locale, u_errorName(status));
7789 DecimalFormat::ERoundingMode mode;
7791 UnicodeString expected;
7795 // Tests that rounding works right when fractional digits is set to 0.
7796 void NumberFormatTest::Test10419RoundingWith0FractionDigits() {
7797 const Test10419Data items[] = {
7798 { DecimalFormat::kRoundCeiling, 1.488, "2"},
7799 { DecimalFormat::kRoundDown, 1.588, "1"},
7800 { DecimalFormat::kRoundFloor, 1.888, "1"},
7801 { DecimalFormat::kRoundHalfDown, 1.5, "1"},
7802 { DecimalFormat::kRoundHalfEven, 2.5, "2"},
7803 { DecimalFormat::kRoundHalfUp, 2.5, "3"},
7804 { DecimalFormat::kRoundUp, 1.5, "2"},
7806 UErrorCode status = U_ZERO_ERROR;
7807 LocalPointer<DecimalFormat> decfmt((DecimalFormat *) NumberFormat::createInstance(Locale("en_US"), status));
7808 if (U_FAILURE(status)) {
7809 dataerrln("Failure creating DecimalFormat %s", u_errorName(status));
7812 for (int32_t i = 0; i < UPRV_LENGTHOF(items); ++i) {
7813 decfmt->setRoundingMode(items[i].mode);
7814 decfmt->setMaximumFractionDigits(0);
7815 UnicodeString actual;
7816 if (items[i].expected != decfmt->format(items[i].value, actual)) {
7817 errln("Expected " + items[i].expected + ", got " + actual);
7822 void NumberFormatTest::Test10468ApplyPattern() {
7823 // Padding char of fmt is now 'a'
7824 UErrorCode status = U_ZERO_ERROR;
7825 DecimalFormat fmt("'I''ll'*a###.##", status);
7827 if (U_FAILURE(status)) {
7828 errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
7832 if (fmt.getPadCharacterString() != UnicodeString("a")) {
7833 errln("Padding character should be 'a'.");
7837 // Padding char of fmt ought to be '*' since that is the default and no
7838 // explicit padding char is specified in the new pattern.
7839 fmt.applyPattern("AA#,##0.00ZZ", status);
7841 // Oops this still prints 'a' even though we changed the pattern.
7842 if (fmt.getPadCharacterString() != UnicodeString(" ")) {
7843 errln("applyPattern did not clear padding character.");
7847 void NumberFormatTest::TestRoundingScientific10542() {
7848 UErrorCode status = U_ZERO_ERROR;
7849 DecimalFormat format("0.00E0", status);
7850 if (U_FAILURE(status)) {
7851 errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
7855 DecimalFormat::ERoundingMode roundingModes[] = {
7856 DecimalFormat::kRoundCeiling,
7857 DecimalFormat::kRoundDown,
7858 DecimalFormat::kRoundFloor,
7859 DecimalFormat::kRoundHalfDown,
7860 DecimalFormat::kRoundHalfEven,
7861 DecimalFormat::kRoundHalfUp,
7862 DecimalFormat::kRoundUp};
7863 const char *descriptions[] = {
7873 double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
7874 // The order of these expected values correspond to the order of roundingModes and the order of values.
7875 const char *expected[] = {
7876 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3",
7877 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7878 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7879 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3",
7880 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7881 "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7882 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"};
7889 UPRV_LENGTHOF(values),
7890 UPRV_LENGTHOF(roundingModes));
7893 double values[] = {-3006.0, -3005, -3004, 3014, 3015, 3016};
7894 // The order of these expected values correspond to the order of roundingModes and the order of values.
7895 const char *expected[] = {
7896 "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3",
7897 "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3",
7898 "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3",
7899 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3",
7900 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7901 "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7902 "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"};
7909 UPRV_LENGTHOF(values),
7910 UPRV_LENGTHOF(roundingModes));
7912 /* Commented out for now until we decide how rounding to zero should work, +0 vs. -0
7914 double values[] = {0.0, -0.0};
7915 // The order of these expected values correspond to the order of roundingModes and the order of values.
7916 const char *expected[] = {
7917 "0.00E0", "-0.00E0",
7918 "0.00E0", "-0.00E0",
7919 "0.00E0", "-0.00E0",
7920 "0.00E0", "-0.00E0",
7921 "0.00E0", "-0.00E0",
7922 "0.00E0", "-0.00E0",
7923 "0.00E0", "-0.00E0"};
7930 UPRV_LENGTHOF(values),
7931 UPRV_LENGTHOF(roundingModes));
7936 double values[] = {1e25, 1e25 + 1e15, 1e25 - 1e15};
7937 // The order of these expected values correspond to the order of roundingModes and the order of values.
7938 const char *expected[] = {
7939 "1.00E25", "1.01E25", "1.00E25",
7940 "1.00E25", "1.00E25", "9.99E24",
7941 "1.00E25", "1.00E25", "9.99E24",
7942 "1.00E25", "1.00E25", "1.00E25",
7943 "1.00E25", "1.00E25", "1.00E25",
7944 "1.00E25", "1.00E25", "1.00E25",
7945 "1.00E25", "1.01E25", "1.00E25"};
7952 UPRV_LENGTHOF(values),
7953 UPRV_LENGTHOF(roundingModes));
7956 double values[] = {-1e25, -1e25 + 1e15, -1e25 - 1e15};
7957 // The order of these expected values correspond to the order of roundingModes and the order of values.
7958 const char *expected[] = {
7959 "-1.00E25", "-9.99E24", "-1.00E25",
7960 "-1.00E25", "-9.99E24", "-1.00E25",
7961 "-1.00E25", "-1.00E25", "-1.01E25",
7962 "-1.00E25", "-1.00E25", "-1.00E25",
7963 "-1.00E25", "-1.00E25", "-1.00E25",
7964 "-1.00E25", "-1.00E25", "-1.00E25",
7965 "-1.00E25", "-1.00E25", "-1.01E25"};
7972 UPRV_LENGTHOF(values),
7973 UPRV_LENGTHOF(roundingModes));
7976 double values[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35};
7977 // The order of these expected values correspond to the order of roundingModes and the order of values.
7978 const char *expected[] = {
7979 "1.00E-25", "1.01E-25", "1.00E-25",
7980 "1.00E-25", "1.00E-25", "9.99E-26",
7981 "1.00E-25", "1.00E-25", "9.99E-26",
7982 "1.00E-25", "1.00E-25", "1.00E-25",
7983 "1.00E-25", "1.00E-25", "1.00E-25",
7984 "1.00E-25", "1.00E-25", "1.00E-25",
7985 "1.00E-25", "1.01E-25", "1.00E-25"};
7992 UPRV_LENGTHOF(values),
7993 UPRV_LENGTHOF(roundingModes));
7996 double values[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35};
7997 // The order of these expected values correspond to the order of roundingModes and the order of values.
7998 const char *expected[] = {
7999 "-1.00E-25", "-9.99E-26", "-1.00E-25",
8000 "-1.00E-25", "-9.99E-26", "-1.00E-25",
8001 "-1.00E-25", "-1.00E-25", "-1.01E-25",
8002 "-1.00E-25", "-1.00E-25", "-1.00E-25",
8003 "-1.00E-25", "-1.00E-25", "-1.00E-25",
8004 "-1.00E-25", "-1.00E-25", "-1.00E-25",
8005 "-1.00E-25", "-1.00E-25", "-1.01E-25"};
8012 UPRV_LENGTHOF(values),
8013 UPRV_LENGTHOF(roundingModes));
8017 void NumberFormatTest::TestZeroScientific10547() {
8018 UErrorCode status = U_ZERO_ERROR;
8019 DecimalFormat fmt("0.00E0", status);
8020 if (!assertSuccess("Formt creation", status)) {
8024 fmt.format(-0.0, out);
8025 assertEquals("format", "-0.00E0", out);
8028 void NumberFormatTest::verifyRounding(
8029 DecimalFormat& format,
8030 const double *values,
8031 const char * const *expected,
8032 const DecimalFormat::ERoundingMode *roundingModes,
8033 const char * const *descriptions,
8035 int32_t roundingModeSize) {
8036 for (int32_t i = 0; i < roundingModeSize; ++i) {
8037 format.setRoundingMode(roundingModes[i]);
8038 for (int32_t j = 0; j < valueSize; j++) {
8039 UnicodeString currentExpected(expected[i * valueSize + j]);
8040 currentExpected = currentExpected.unescape();
8041 UnicodeString actual;
8042 format.format(values[j], actual);
8043 if (currentExpected != actual) {
8047 "For %s value %f, expected ",
8050 errln(UnicodeString(buffer) + currentExpected + ", got " + actual);
8056 void NumberFormatTest::TestAccountingCurrency() {
8057 UErrorCode status = U_ZERO_ERROR;
8058 UNumberFormatStyle style = UNUM_CURRENCY_ACCOUNTING;
8060 expect(NumberFormat::createInstance("en_US", style, status),
8061 (Formattable)(double)1234.5, "$1,234.50", TRUE, status);
8062 expect(NumberFormat::createInstance("en_US", style, status),
8063 (Formattable)(double)-1234.5, "($1,234.50)", TRUE, status);
8064 expect(NumberFormat::createInstance("en_US", style, status),
8065 (Formattable)(double)0, "$0.00", TRUE, status);
8066 expect(NumberFormat::createInstance("en_US", style, status),
8067 (Formattable)(double)-0.2, "($0.20)", TRUE, status);
8068 expect(NumberFormat::createInstance("ja_JP", style, status),
8069 (Formattable)(double)10000, UnicodeString("\\uFFE510,000").unescape(), TRUE, status);
8070 expect(NumberFormat::createInstance("ja_JP", style, status),
8071 (Formattable)(double)-1000.5, UnicodeString("(\\uFFE51,000)").unescape(), FALSE, status);
8072 expect(NumberFormat::createInstance("de_DE", style, status),
8073 (Formattable)(double)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE, status);
8077 void NumberFormatTest::TestEquality() {
8078 UErrorCode status = U_ZERO_ERROR;
8079 DecimalFormatSymbols* symbols = new DecimalFormatSymbols(Locale("root"), status);
8080 if (U_FAILURE(status)) {
8081 dataerrln("Fail: can't create DecimalFormatSymbols for root");
8084 UnicodeString pattern("#,##0.###");
8085 DecimalFormat* fmtBase = new DecimalFormat(pattern, symbols, status);
8086 if (U_FAILURE(status)) {
8087 dataerrln("Fail: can't create DecimalFormat using root symbols");
8091 DecimalFormat* fmtClone = (DecimalFormat*)fmtBase->clone();
8092 fmtClone->setFormatWidth(fmtBase->getFormatWidth() + 32);
8093 if (*fmtClone == *fmtBase) {
8094 errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
8101 void NumberFormatTest::TestCurrencyUsage() {
8102 double agent = 123.567;
8107 // compare the Currency and Currency Cash Digits
8108 // Note that as of CLDR 26:
8109 // * TWD switches from 0 decimals to 2; PKR still has 0, so change test to that
8110 // * CAD rounds to .05 in cash mode only
8111 // 1st time for getter/setter, 2nd time for factory method
8112 Locale enUS_PKR("en_US@currency=PKR");
8114 for(int i=0; i<2; i++){
8115 status = U_ZERO_ERROR;
8117 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_PKR, UNUM_CURRENCY, status);
8118 if (assertSuccess("en_US@currency=PKR/CURRENCY", status, TRUE) == FALSE) {
8122 UnicodeString original;
8123 fmt->format(agent,original);
8124 assertEquals("Test Currency Usage 1", UnicodeString("PKR124"), original);
8126 // test the getter here
8127 UCurrencyUsage curUsage = fmt->getCurrencyUsage();
8128 assertEquals("Test usage getter - standard", (int32_t)curUsage, (int32_t)UCURR_USAGE_STANDARD);
8130 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8132 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_PKR, UNUM_CASH_CURRENCY, status);
8133 if (assertSuccess("en_US@currency=PKR/CASH", status, TRUE) == FALSE) {
8138 // must be usage = cash
8139 UCurrencyUsage curUsage = fmt->getCurrencyUsage();
8140 assertEquals("Test usage getter - cash", (int32_t)curUsage, (int32_t)UCURR_USAGE_CASH);
8142 UnicodeString cash_currency;
8143 fmt->format(agent,cash_currency);
8144 assertEquals("Test Currency Usage 2", UnicodeString("PKR124"), cash_currency);
8148 // compare the Currency and Currency Cash Rounding
8149 // 1st time for getter/setter, 2nd time for factory method
8150 Locale enUS_CAD("en_US@currency=CAD");
8151 for(int i=0; i<2; i++){
8152 status = U_ZERO_ERROR;
8154 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status);
8155 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) {
8159 UnicodeString original_rounding;
8160 fmt->format(agent, original_rounding);
8161 assertEquals("Test Currency Usage 3", UnicodeString("CA$123.57"), original_rounding);
8162 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8164 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status);
8165 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) {
8170 UnicodeString cash_rounding_currency;
8171 fmt->format(agent, cash_rounding_currency);
8172 assertEquals("Test Currency Usage 4", UnicodeString("CA$123.55"), cash_rounding_currency);
8176 // Test the currency change
8177 // 1st time for getter/setter, 2nd time for factory method
8178 const UChar CUR_PKR[] = {0x50, 0x4B, 0x52, 0};
8179 for(int i=0; i<2; i++){
8180 status = U_ZERO_ERROR;
8182 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status);
8183 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) {
8186 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8188 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status);
8189 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) {
8194 UnicodeString cur_original;
8195 fmt->setCurrencyUsage(UCURR_USAGE_STANDARD, &status);
8196 fmt->format(agent, cur_original);
8197 assertEquals("Test Currency Usage 5", UnicodeString("CA$123.57"), cur_original);
8199 fmt->setCurrency(CUR_PKR, status);
8200 assertSuccess("Set currency to PKR", status);
8202 UnicodeString PKR_changed;
8203 fmt->format(agent, PKR_changed);
8204 assertEquals("Test Currency Usage 6", UnicodeString("PKR124"), PKR_changed);
8209 void NumberFormatTest::TestNumberFormatTestTuple() {
8210 NumberFormatTestTuple tuple;
8211 UErrorCode status = U_ZERO_ERROR;
8214 NumberFormatTestTuple::getFieldByName("locale"),
8218 NumberFormatTestTuple::getFieldByName("pattern"),
8222 NumberFormatTestTuple::getFieldByName("minIntegerDigits"),
8225 if (!assertSuccess("", status)) {
8229 // only what we set should be set.
8230 assertEquals("", "en", tuple.locale.getName());
8231 assertEquals("", "#,##0.00", tuple.pattern);
8232 assertEquals("", -10, tuple.minIntegerDigits);
8233 assertTrue("", tuple.localeFlag);
8234 assertTrue("", tuple.patternFlag);
8235 assertTrue("", tuple.minIntegerDigitsFlag);
8236 assertFalse("", tuple.formatFlag);
8238 UnicodeString appendTo;
8241 "{locale: en, pattern: #,##0.00, minIntegerDigits: -10}",
8242 tuple.toString(appendTo));
8249 tuple.toString(appendTo));
8251 NumberFormatTestTuple::getFieldByName("aBadFieldName"),
8254 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
8255 errln("Expected U_ILLEGAL_ARGUMENT_ERROR");
8257 status = U_ZERO_ERROR;
8259 NumberFormatTestTuple::getFieldByName("minIntegerDigits"),
8262 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
8263 errln("Expected U_ILLEGAL_ARGUMENT_ERROR");
8268 NumberFormatTest::TestDataDriven() {
8269 NumberFormatTestDataDriven dd;
8271 dd.run("numberformattestspecification.txt", FALSE);
8275 // Check the constant MAX_INT64_IN_DOUBLE.
8276 // The value should convert to a double with no loss of precision.
8277 // A failure may indicate a platform with a different double format, requiring
8278 // a revision to the constant.
8280 // Note that this is actually hard to test, because the language standard gives
8281 // compilers considerable flexibility to do unexpected things with rounding and
8282 // with overflow in simple int to/from float conversions. Some compilers will completely optimize
8283 // away a simple round-trip conversion from int64_t -> double -> int64_t.
8285 void NumberFormatTest::TestDoubleLimit11439() {
8287 for (int64_t num = MAX_INT64_IN_DOUBLE-10; num<=MAX_INT64_IN_DOUBLE; num++) {
8288 sprintf(buf, "%lld", (long long)num);
8290 sscanf(buf, "%lf", &fNum);
8291 int64_t rtNum = fNum;
8293 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
8297 for (int64_t num = -MAX_INT64_IN_DOUBLE+10; num>=-MAX_INT64_IN_DOUBLE; num--) {
8298 sprintf(buf, "%lld", (long long)num);
8300 sscanf(buf, "%lf", &fNum);
8301 int64_t rtNum = fNum;
8303 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
8309 void NumberFormatTest::TestFastPathConsistent11524() {
8310 UErrorCode status = U_ZERO_ERROR;
8311 NumberFormat *fmt = NumberFormat::createInstance("en", status);
8312 if (U_FAILURE(status) || fmt == NULL) {
8313 dataerrln("Failed call to NumberFormat::createInstance() - %s", u_errorName(status));
8316 fmt->setMaximumIntegerDigits(INT32_MIN);
8317 UnicodeString appendTo;
8318 assertEquals("", "0", fmt->format((int32_t)123, appendTo));
8320 assertEquals("", "0", fmt->format((int32_t)12345, appendTo));
8324 void NumberFormatTest::TestGetAffixes() {
8325 UErrorCode status = U_ZERO_ERROR;
8326 DecimalFormatSymbols sym("en_US", status);
8327 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8328 pattern = pattern.unescape();
8329 DecimalFormat fmt(pattern, sym, status);
8330 if (U_FAILURE(status)) {
8331 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
8334 UnicodeString affixStr;
8335 assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr));
8336 assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr));
8337 assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr));
8338 assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr));
8340 // Test equality with affixes. set affix methods can't capture special
8341 // characters which is why equality should fail.
8343 DecimalFormat fmtCopy(fmt);
8344 assertTrue("", fmt == fmtCopy);
8345 UnicodeString someAffix;
8346 fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(someAffix));
8347 assertTrue("", fmt != fmtCopy);
8350 DecimalFormat fmtCopy(fmt);
8351 assertTrue("", fmt == fmtCopy);
8352 UnicodeString someAffix;
8353 fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(someAffix));
8354 assertTrue("", fmt != fmtCopy);
8357 DecimalFormat fmtCopy(fmt);
8358 assertTrue("", fmt == fmtCopy);
8359 UnicodeString someAffix;
8360 fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(someAffix));
8361 assertTrue("", fmt != fmtCopy);
8364 DecimalFormat fmtCopy(fmt);
8365 assertTrue("", fmt == fmtCopy);
8366 UnicodeString someAffix;
8367 fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(someAffix));
8368 assertTrue("", fmt != fmtCopy);
8370 fmt.setPositivePrefix("Don't");
8371 fmt.setPositiveSuffix("do");
8372 UnicodeString someAffix("be''eet\\u00a4\\u00a4\\u00a4 it.");
8373 someAffix = someAffix.unescape();
8374 fmt.setNegativePrefix(someAffix);
8375 fmt.setNegativeSuffix("%");
8376 assertEquals("", "Don't", fmt.getPositivePrefix(affixStr));
8377 assertEquals("", "do", fmt.getPositiveSuffix(affixStr));
8378 assertEquals("", someAffix, fmt.getNegativePrefix(affixStr));
8379 assertEquals("", "%", fmt.getNegativeSuffix(affixStr));
8382 void NumberFormatTest::TestToPatternScientific11648() {
8383 UErrorCode status = U_ZERO_ERROR;
8385 DecimalFormatSymbols sym(en, status);
8386 DecimalFormat fmt("0.00", sym, status);
8387 if (U_FAILURE(status)) {
8388 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
8391 fmt.setScientificNotation(TRUE);
8392 UnicodeString pattern;
8393 assertEquals("", "0.00E0", fmt.toPattern(pattern));
8394 DecimalFormat fmt2(pattern, sym, status);
8395 assertSuccess("", status);
8398 void NumberFormatTest::TestBenchmark() {
8400 UErrorCode status = U_ZERO_ERROR;
8402 DecimalFormatSymbols sym(en, status);
8403 DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(sym), status);
8404 // DecimalFormat fmt("0.00000E0", new DecimalFormatSymbols(sym), status);
8405 // DecimalFormat fmt("0", new DecimalFormatSymbols(sym), status);
8406 FieldPosition fpos(FieldPosition::DONT_CARE);
8407 clock_t start = clock();
8408 for (int32_t i = 0; i < 1000000; ++i) {
8409 UnicodeString append;
8410 fmt.format(3.0, append, fpos, status);
8411 // fmt.format(4.6692016, append, fpos, status);
8412 // fmt.format(1234567.8901, append, fpos, status);
8413 // fmt.format(2.99792458E8, append, fpos, status);
8414 // fmt.format(31, append);
8416 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8417 assertSuccess("", status);
8419 UErrorCode status = U_ZERO_ERROR;
8420 MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status);
8421 FieldPosition fpos(FieldPosition::DONT_CARE);
8422 Formattable one(1.0);
8423 Formattable three(3.0);
8424 clock_t start = clock();
8425 for (int32_t i = 0; i < 500000; ++i) {
8426 UnicodeString append;
8427 fmt.format(&one, 1, append, fpos, status);
8428 UnicodeString append2;
8429 fmt.format(&three, 1, append2, fpos, status);
8431 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8432 assertSuccess("", status);
8434 UErrorCode status = U_ZERO_ERROR;
8436 Measure measureC(23, MeasureUnit::createCelsius(status), status);
8437 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
8438 FieldPosition fpos(FieldPosition::DONT_CARE);
8439 clock_t start = clock();
8440 for (int32_t i = 0; i < 1000000; ++i) {
8441 UnicodeString appendTo;
8443 &measureC, 1, appendTo, fpos, status);
8445 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8446 assertSuccess("", status);
8450 void NumberFormatTest::TestFractionalDigitsForCurrency() {
8451 UErrorCode status = U_ZERO_ERROR;
8452 LocalPointer<NumberFormat> fmt(NumberFormat::createCurrencyInstance("en", status));
8453 if (U_FAILURE(status)) {
8454 dataerrln("Error creating NumberFormat - %s", u_errorName(status));
8457 UChar JPY[] = {0x4A, 0x50, 0x59, 0x0};
8458 fmt->setCurrency(JPY, status);
8459 if (!assertSuccess("", status)) {
8462 assertEquals("", 0, fmt->getMaximumFractionDigits());
8466 void NumberFormatTest::TestFormatCurrencyPlural() {
8467 UErrorCode status = U_ZERO_ERROR;
8468 Locale locale = Locale::createCanonical("en_US");
8469 NumberFormat *fmt = NumberFormat::createInstance(locale, UNUM_CURRENCY_PLURAL, status);
8470 if (U_FAILURE(status)) {
8471 dataerrln("Error creating NumberFormat - %s", u_errorName(status));
8474 UnicodeString formattedNum;
8475 fmt->format(11234.567, formattedNum, NULL, status);
8476 assertEquals("", "11,234.57 US dollars", formattedNum);
8480 void NumberFormatTest::TestCtorApplyPatternDifference() {
8481 UErrorCode status = U_ZERO_ERROR;
8482 DecimalFormatSymbols sym("en_US", status);
8483 UnicodeString pattern("\\u00a40");
8484 DecimalFormat fmt(pattern.unescape(), sym, status);
8485 if (U_FAILURE(status)) {
8486 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
8489 UnicodeString result;
8491 "ctor favors precision of currency",
8493 fmt.format((double)5, result));
8495 fmt.applyPattern(pattern.unescape(), status);
8497 "applyPattern favors precision of pattern",
8499 fmt.format((double)5, result));
8502 void NumberFormatTest::Test11868() {
8503 double posAmt = 34.567;
8504 double negAmt = -9876.543;
8506 Locale selectedLocale("en_US");
8507 UErrorCode status = U_ZERO_ERROR;
8509 UnicodeString result;
8510 FieldPosition fpCurr(UNUM_CURRENCY_FIELD);
8511 LocalPointer<NumberFormat> fmt(
8512 NumberFormat::createInstance(
8513 selectedLocale, UNUM_CURRENCY_PLURAL, status));
8514 if (!assertSuccess("Format creation", status)) {
8517 fmt->format(posAmt, result, fpCurr, status);
8518 assertEquals("", "34.57 US dollars", result);
8519 assertEquals("begin index", 6, fpCurr.getBeginIndex());
8520 assertEquals("end index", 16, fpCurr.getEndIndex());
8522 // Test field position iterator
8524 NumberFormatTest_Attributes attributes[] = {
8525 {UNUM_INTEGER_FIELD, 0, 2},
8526 {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
8527 {UNUM_FRACTION_FIELD, 3, 5},
8528 {UNUM_CURRENCY_FIELD, 6, 16},
8530 UnicodeString result;
8531 FieldPositionIterator iter;
8532 fmt->format(posAmt, result, &iter, status);
8533 assertEquals("", "34.57 US dollars", result);
8534 verifyFieldPositionIterator(attributes, iter);
8538 fmt->format(negAmt, result, fpCurr, status);
8539 assertEquals("", "-9,876.54 US dollars", result);
8540 assertEquals("begin index", 10, fpCurr.getBeginIndex());
8541 assertEquals("end index", 20, fpCurr.getEndIndex());
8543 // Test field position iterator
8545 NumberFormatTest_Attributes attributes[] = {
8546 {UNUM_SIGN_FIELD, 0, 1},
8547 {UNUM_GROUPING_SEPARATOR_FIELD, 2, 3},
8548 {UNUM_INTEGER_FIELD, 1, 6},
8549 {UNUM_DECIMAL_SEPARATOR_FIELD, 6, 7},
8550 {UNUM_FRACTION_FIELD, 7, 9},
8551 {UNUM_CURRENCY_FIELD, 10, 20},
8553 UnicodeString result;
8554 FieldPositionIterator iter;
8555 fmt->format(negAmt, result, &iter, status);
8556 assertEquals("", "-9,876.54 US dollars", result);
8557 verifyFieldPositionIterator(attributes, iter);
8561 void NumberFormatTest::Test10727_RoundingZero() {
8564 assertFalse("", d.isPositive());
8566 assertFalse("", d.isPositive());
8569 void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
8571 const UChar USD[] = {0x55, 0x53, 0x44, 0x0};
8572 UErrorCode status = U_ZERO_ERROR;
8573 LocalPointer<NumberFormat> fmt(
8574 NumberFormat::createCurrencyInstance("en", status));
8575 if (!assertSuccess("", status)) {
8578 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
8579 dfmt->setCurrency(USD);
8580 UnicodeString result;
8582 // This line should be a no-op. I am setting the positive prefix
8583 // to be the same thing it was before.
8584 dfmt->setPositivePrefix(dfmt->getPositivePrefix(result));
8586 UnicodeString appendTo;
8587 assertEquals("", "$3.78", dfmt->format(3.78, appendTo, status));
8588 assertSuccess("", status);
8591 const UChar USD[] = {0x55, 0x53, 0x44, 0x0};
8592 UErrorCode status = U_ZERO_ERROR;
8593 LocalPointer<NumberFormat> fmt(
8594 NumberFormat::createInstance("en", UNUM_CURRENCY_PLURAL, status));
8595 if (!assertSuccess("", status)) {
8598 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
8599 UnicodeString result;
8600 UnicodeString tripleIntlCurrency(" \\u00a4\\u00a4\\u00a4");
8601 tripleIntlCurrency = tripleIntlCurrency.unescape();
8602 assertEquals("", tripleIntlCurrency, dfmt->getPositiveSuffix(result));
8603 dfmt->setCurrency(USD);
8605 // getPositiveSuffix() always returns the suffix for the
8606 // "other" plural category
8607 assertEquals("", " US dollars", dfmt->getPositiveSuffix(result));
8608 UnicodeString appendTo;
8609 assertEquals("", "3.78 US dollars", dfmt->format(3.78, appendTo, status));
8610 assertEquals("", " US dollars", dfmt->getPositiveSuffix(result));
8611 dfmt->setPositiveSuffix("booya");
8613 assertEquals("", "3.78booya", dfmt->format(3.78, appendTo, status));
8614 assertEquals("", "booya", dfmt->getPositiveSuffix(result));
8618 void NumberFormatTest::Test11475_signRecognition() {
8619 UErrorCode status = U_ZERO_ERROR;
8620 DecimalFormatSymbols sym("en", status);
8621 UnicodeString result;
8623 DecimalFormat fmt("+0.00", sym, status);
8624 if (!assertSuccess("", status)) {
8627 NumberFormatTest_Attributes attributes[] = {
8628 {UNUM_SIGN_FIELD, 0, 1},
8629 {UNUM_INTEGER_FIELD, 1, 2},
8630 {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
8631 {UNUM_FRACTION_FIELD, 3, 5},
8633 UnicodeString result;
8634 FieldPositionIterator iter;
8635 fmt.format(2.3, result, &iter, status);
8636 assertEquals("", "+2.30", result);
8637 verifyFieldPositionIterator(attributes, iter);
8640 DecimalFormat fmt("++0.00+;-(#)--", sym, status);
8641 if (!assertSuccess("", status)) {
8645 NumberFormatTest_Attributes attributes[] = {
8646 {UNUM_SIGN_FIELD, 0, 2},
8647 {UNUM_INTEGER_FIELD, 2, 3},
8648 {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
8649 {UNUM_FRACTION_FIELD, 4, 6},
8650 {UNUM_SIGN_FIELD, 6, 7},
8652 UnicodeString result;
8653 FieldPositionIterator iter;
8654 fmt.format(2.3, result, &iter, status);
8655 assertEquals("", "++2.30+", result);
8656 verifyFieldPositionIterator(attributes, iter);
8659 NumberFormatTest_Attributes attributes[] = {
8660 {UNUM_SIGN_FIELD, 0, 1},
8661 {UNUM_INTEGER_FIELD, 2, 3},
8662 {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
8663 {UNUM_FRACTION_FIELD, 4, 6},
8664 {UNUM_SIGN_FIELD, 7, 9},
8666 UnicodeString result;
8667 FieldPositionIterator iter;
8668 fmt.format(-2.3, result, &iter, status);
8669 assertEquals("", "-(2.30)--", result);
8670 verifyFieldPositionIterator(attributes, iter);
8675 void NumberFormatTest::Test11640_getAffixes() {
8676 UErrorCode status = U_ZERO_ERROR;
8677 DecimalFormatSymbols symbols("en_US", status);
8678 if (!assertSuccess("", status)) {
8681 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8682 pattern = pattern.unescape();
8683 DecimalFormat fmt(pattern, symbols, status);
8684 if (!assertSuccess("", status)) {
8687 UnicodeString affixStr;
8688 assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr));
8689 assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr));
8690 assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr));
8691 assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr));
8694 void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
8695 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00");
8696 pattern = pattern.unescape();
8697 UErrorCode status = U_ZERO_ERROR;
8698 DecimalFormat fmt(pattern, status);
8699 if (!assertSuccess("", status)) {
8702 static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
8703 fmt.setCurrency(USD);
8704 UnicodeString appendTo;
8706 assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
8708 UnicodeString topattern;
8709 fmt.toPattern(topattern);
8710 DecimalFormat fmt2(topattern, status);
8711 if (!assertSuccess("", status)) {
8714 fmt2.setCurrency(USD);
8717 assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
8721 void NumberFormatTest::verifyFieldPositionIterator(
8722 NumberFormatTest_Attributes *expected, FieldPositionIterator &iter) {
8725 while (iter.next(fp)) {
8726 if (expected[idx].spos == -1) {
8727 errln("Iterator should have ended. got %d", fp.getField());
8730 assertEquals("id", expected[idx].id, fp.getField());
8731 assertEquals("start", expected[idx].spos, fp.getBeginIndex());
8732 assertEquals("end", expected[idx].epos, fp.getEndIndex());
8735 if (expected[idx].spos != -1) {
8736 errln("Premature end of iterator. expected %d", expected[idx].id);
8740 void NumberFormatTest::checkExceptionIssue11735() {
8742 Locale enLocale("en");
8743 DecimalFormatSymbols symbols(enLocale, status);
8745 if (U_FAILURE(status)) {
8746 errln((UnicodeString)
8747 "Fail: Construct DecimalFormatSymbols");
8750 DecimalFormat fmt("0", symbols, status);
8751 if (U_FAILURE(status)) {
8752 errln((UnicodeString)
8753 "Fail: Construct DecimalFormat formatter");
8756 ParsePosition ppos(0);
8757 fmt.parseCurrency("53.45", ppos); // NPE thrown here in ICU4J.
8758 assertEquals("Issue11735 ppos", 0, ppos.getIndex());
8761 #endif /* #if !UCONFIG_NO_FORMATTING */