numfmtst.cpp revision c73f511526464f8e56c242df80552e9b0d94ae3d
1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/* Modification History:
7*   Date        Name        Description
8*   07/15/99    helena      Ported to HPUX 10/11 CC.
9*/
10
11#include "unicode/utypes.h"
12
13#if !UCONFIG_NO_FORMATTING
14
15#include "numfmtst.h"
16#include "unicode/dcfmtsym.h"
17#include "unicode/decimfmt.h"
18#include "unicode/localpointer.h"
19#include "unicode/ucurr.h"
20#include "unicode/ustring.h"
21#include "unicode/measfmt.h"
22#include "unicode/curramt.h"
23#include "digitlst.h"
24#include "textfile.h"
25#include "tokiter.h"
26#include "charstr.h"
27#include "putilimp.h"
28#include "winnmtst.h"
29#include <float.h>
30#include <string.h>
31#include <stdlib.h>
32#include "cstring.h"
33#include "unicode/numsys.h"
34#include "fmtableimp.h"
35
36//#define NUMFMTST_CACHE_DEBUG 1
37#include "stdio.h" /* for sprintf */
38// #include "iostream"   // for cout
39
40//#define NUMFMTST_DEBUG 1
41
42#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof(array[0]))
43
44static const UChar EUR[] = {69,85,82,0}; // "EUR"
45static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD"
46
47
48// *****************************************************************************
49// class NumberFormatTest
50// *****************************************************************************
51
52#define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
53#define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
54
55void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
56{
57  TESTCASE_AUTO_BEGIN;
58  TESTCASE_AUTO(TestCurrencySign);
59  TESTCASE_AUTO(TestCurrency);
60  TESTCASE_AUTO(TestParse);
61  TESTCASE_AUTO(TestRounding487);
62  TESTCASE_AUTO(TestQuotes);
63  TESTCASE_AUTO(TestExponential);
64  TESTCASE_AUTO(TestPatterns);
65
66  // Upgrade to alphaWorks - liu 5/99
67  TESTCASE_AUTO(TestExponent);
68  TESTCASE_AUTO(TestScientific);
69  TESTCASE_AUTO(TestPad);
70  TESTCASE_AUTO(TestPatterns2);
71  TESTCASE_AUTO(TestSecondaryGrouping);
72  TESTCASE_AUTO(TestSurrogateSupport);
73  TESTCASE_AUTO(TestAPI);
74
75  TESTCASE_AUTO(TestCurrencyObject);
76  TESTCASE_AUTO(TestCurrencyPatterns);
77  //TESTCASE_AUTO(TestDigitList);
78  TESTCASE_AUTO(TestWhiteSpaceParsing);
79  TESTCASE_AUTO(TestComplexCurrency);  // This test removed because CLDR no longer uses choice formats in currency symbols.
80  TESTCASE_AUTO(TestRegCurrency);
81  TESTCASE_AUTO(TestSymbolsWithBadLocale);
82  TESTCASE_AUTO(TestAdoptDecimalFormatSymbols);
83
84  TESTCASE_AUTO(TestScientific2);
85  TESTCASE_AUTO(TestScientificGrouping);
86  TESTCASE_AUTO(TestInt64);
87
88  TESTCASE_AUTO(TestPerMill);
89  TESTCASE_AUTO(TestIllegalPatterns);
90  TESTCASE_AUTO(TestCases);
91
92  TESTCASE_AUTO(TestCurrencyNames);
93  TESTCASE_AUTO(TestCurrencyAmount);
94  TESTCASE_AUTO(TestCurrencyUnit);
95  TESTCASE_AUTO(TestCoverage);
96  TESTCASE_AUTO(TestJB3832);
97  TESTCASE_AUTO(TestHost);
98  TESTCASE_AUTO(TestHostClone);
99  TESTCASE_AUTO(TestCurrencyFormat);
100  TESTCASE_AUTO(TestRounding);
101  TESTCASE_AUTO(TestNonpositiveMultiplier);
102  TESTCASE_AUTO(TestNumberingSystems);
103  TESTCASE_AUTO(TestSpaceParsing);
104  TESTCASE_AUTO(TestMultiCurrencySign);
105  TESTCASE_AUTO(TestCurrencyFormatForMixParsing);
106  TESTCASE_AUTO(TestDecimalFormatCurrencyParse);
107  TESTCASE_AUTO(TestCurrencyIsoPluralFormat);
108  TESTCASE_AUTO(TestCurrencyParsing);
109  TESTCASE_AUTO(TestParseCurrencyInUCurr);
110  TESTCASE_AUTO(TestFormatAttributes);
111  TESTCASE_AUTO(TestFieldPositionIterator);
112  TESTCASE_AUTO(TestDecimal);
113  TESTCASE_AUTO(TestCurrencyFractionDigits);
114  TESTCASE_AUTO(TestExponentParse);
115  TESTCASE_AUTO(TestExplicitParents);
116  TESTCASE_AUTO(TestLenientParse);
117  TESTCASE_AUTO(TestAvailableNumberingSystems);
118  TESTCASE_AUTO(TestRoundingPattern);
119  TESTCASE_AUTO(Test9087);
120  TESTCASE_AUTO(TestFormatFastpaths);
121  TESTCASE_AUTO(TestFormattableSize);
122  TESTCASE_AUTO(TestUFormattable);
123  TESTCASE_AUTO(TestSignificantDigits);
124  TESTCASE_AUTO(TestShowZero);
125  TESTCASE_AUTO(TestCompatibleCurrencies);
126  TESTCASE_AUTO(TestBug9936);
127  TESTCASE_AUTO(TestParseNegativeWithFaLocale);
128  TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign);
129  TESTCASE_AUTO(TestCustomCurrencySignAndSeparator);
130  TESTCASE_AUTO(TestParseSignsAndMarks);
131  TESTCASE_AUTO(Test10419RoundingWith0FractionDigits);
132  TESTCASE_AUTO(Test10468ApplyPattern);
133  TESTCASE_AUTO(TestRoundingScientific10542);
134  TESTCASE_AUTO(TestZeroScientific10547);
135  TESTCASE_AUTO(TestAccountingCurrency);
136  TESTCASE_AUTO(TestEquality);
137  TESTCASE_AUTO_END;
138}
139
140// -------------------------------------
141
142// Test API (increase code coverage)
143void
144NumberFormatTest::TestAPI(void)
145{
146  logln("Test API");
147  UErrorCode status = U_ZERO_ERROR;
148  NumberFormat *test = NumberFormat::createInstance("root", status);
149  if(U_FAILURE(status)) {
150    dataerrln("unable to create format object - %s", u_errorName(status));
151  }
152  if(test != NULL) {
153    test->setMinimumIntegerDigits(10);
154    test->setMaximumIntegerDigits(2);
155
156    test->setMinimumFractionDigits(10);
157    test->setMaximumFractionDigits(2);
158
159    UnicodeString result;
160    FieldPosition pos;
161    Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers
162    test->format(bla, result, pos, status);
163    if(U_SUCCESS(status)) {
164      errln("Yuck... Formatted a duck... As a number!");
165    } else {
166      status = U_ZERO_ERROR;
167    }
168
169    result.remove();
170    int64_t ll = 12;
171    test->format(ll, result);
172    if (result != "12.00"){
173        errln("format int64_t error");
174    }
175
176    ParsePosition ppos;
177    LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos));
178    // old test for (U_FAILURE(status)) was bogus here, method does not set status!
179    if (ppos.getIndex()) {
180        errln("Parsed empty string as currency");
181    }
182
183    delete test;
184  }
185}
186
187class StubNumberFormat :public NumberFormat{
188public:
189    StubNumberFormat(){};
190    virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
191        return appendTo;
192    }
193    virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
194        return appendTo.append((UChar)0x0033);
195    }
196    virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
197        return NumberFormat::format(number, appendTo, pos);
198    }
199    virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
200        return appendTo;
201    }
202    virtual void parse(const UnicodeString& ,
203                    Formattable& ,
204                    ParsePosition& ) const {}
205    virtual void parse( const UnicodeString& ,
206                        Formattable& ,
207                        UErrorCode& ) const {}
208    virtual UClassID getDynamicClassID(void) const {
209        static char classID = 0;
210        return (UClassID)&classID;
211    }
212    virtual Format* clone() const {return NULL;}
213};
214
215void
216NumberFormatTest::TestCoverage(void){
217    StubNumberFormat stub;
218    UnicodeString agent("agent");
219    FieldPosition pos;
220    int64_t num = 4;
221    if (stub.format(num, agent, pos) != UnicodeString("agent3")){
222        errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
223    };
224}
225
226// Test various patterns
227void
228NumberFormatTest::TestPatterns(void)
229{
230    UErrorCode status = U_ZERO_ERROR;
231    DecimalFormatSymbols sym(Locale::getUS(), status);
232    if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; }
233
234    const char* pat[]    = { "#.#", "#.", ".#", "#" };
235    int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
236    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
237    const char* num[]    = { "0",   "0.", ".0", "0" };
238    for (int32_t i=0; i<pat_length; ++i)
239    {
240        status = U_ZERO_ERROR;
241        DecimalFormat fmt(pat[i], sym, status);
242        if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; }
243        UnicodeString newp; fmt.toPattern(newp);
244        if (!(newp == newpat[i]))
245            errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
246                  "; " + newp + " seen instead");
247
248        UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
249        if (!(s == num[i]))
250        {
251            errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
252                  "; " + s + " seen instead");
253            logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits());
254        }
255    }
256}
257
258/*
259icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
260icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
261icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
262*/
263/*
264void
265NumberFormatTest::TestDigitList(void)
266{
267  // API coverage for DigitList
268  DigitList list1;
269  list1.append('1');
270  list1.fDecimalAt = 1;
271  DigitList list2;
272  list2.set((int32_t)1);
273  if (list1 != list2) {
274    errln("digitlist append, operator!= or set failed ");
275  }
276  if (!(list1 == list2)) {
277    errln("digitlist append, operator== or set failed ");
278  }
279}
280*/
281
282// -------------------------------------
283
284// Test exponential pattern
285void
286NumberFormatTest::TestExponential(void)
287{
288    UErrorCode status = U_ZERO_ERROR;
289    DecimalFormatSymbols sym(Locale::getUS(), status);
290    if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
291    const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]"  };
292    int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
293
294// The following #if statements allow this test to be built and run on
295// platforms that do not have standard IEEE numerics.  For example,
296// S/390 doubles have an exponent range of -78 to +75.  For the
297// following #if statements to work, float.h must define
298// DBL_MAX_10_EXP to be a compile-time constant.
299
300// This section may be expanded as needed.
301
302#if DBL_MAX_10_EXP > 300
303    double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
304    int32_t val_length = (int32_t)(sizeof(val) / sizeof(val[0]));
305    const char* valFormat[] =
306    {
307        // 0.####E0
308        "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
309        // 00.000E00
310        "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
311        // ##0.######E000
312        "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
313        // 0.###E0;[0.###E0]
314        "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
315    };
316    double valParse[] =
317    {
318        0.01234, 123460000, 1.23E300, -3.1416E-271,
319        0.01234, 123460000, 1.23E300, -3.1416E-271,
320        0.01234, 123456800, 1.23E300, -3.141593E-271,
321        0.01234, 123500000, 1.23E300, -3.142E-271,
322    };
323#elif DBL_MAX_10_EXP > 70
324    double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
325    int32_t val_length = sizeof(val) / sizeof(val[0]);
326    char* valFormat[] =
327    {
328        // 0.####E0
329        "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
330        // 00.000E00
331        "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
332        // ##0.######E000
333        "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
334        // 0.###E0;[0.###E0]
335        "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
336    };
337    double valParse[] =
338    {
339        0.01234, 123460000, 1.23E70, -3.1416E-71,
340        0.01234, 123460000, 1.23E70, -3.1416E-71,
341        0.01234, 123456800, 1.23E70, -3.141593E-71,
342        0.01234, 123500000, 1.23E70, -3.142E-71,
343    };
344#else
345    // Don't test double conversion
346    double* val = 0;
347    int32_t val_length = 0;
348    char** valFormat = 0;
349    double* valParse = 0;
350    logln("Warning: Skipping double conversion tests");
351#endif
352
353    int32_t lval[] = { 0, -1, 1, 123456789 };
354    int32_t lval_length = (int32_t)(sizeof(lval) / sizeof(lval[0]));
355    const char* lvalFormat[] =
356    {
357        // 0.####E0
358        "0E0", "-1E0", "1E0", "1.2346E8",
359        // 00.000E00
360        "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
361        // ##0.######E000
362        "0E000", "-1E000", "1E000", "123.4568E006",
363        // 0.###E0;[0.###E0]
364        "0E0", "[1E0]", "1E0", "1.235E8"
365    };
366    int32_t lvalParse[] =
367    {
368        0, -1, 1, 123460000,
369        0, -1, 1, 123460000,
370        0, -1, 1, 123456800,
371        0, -1, 1, 123500000,
372    };
373    int32_t ival = 0, ilval = 0;
374    for (int32_t p=0; p<pat_length; ++p)
375    {
376        DecimalFormat fmt(pat[p], sym, status);
377        if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
378        UnicodeString pattern;
379        logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" +
380          fmt.toPattern(pattern) + "\"");
381        int32_t v;
382        for (v=0; v<val_length; ++v)
383        {
384            UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s);
385            logln((UnicodeString)" " + val[v] + " -format-> " + s);
386            if (s != valFormat[v+ival])
387                errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]);
388
389            ParsePosition pos(0);
390            Formattable af;
391            fmt.parse(s, af, pos);
392            double a;
393            UBool useEpsilon = FALSE;
394            if (af.getType() == Formattable::kLong)
395                a = af.getLong();
396            else if (af.getType() == Formattable::kDouble) {
397                a = af.getDouble();
398#if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
399                // S/390 will show a failure like this:
400                //| -3.141592652999999e-271 -format-> -3.1416E-271
401                //|                          -parse-> -3.1416e-271
402                //| FAIL: Expected -3.141599999999999e-271
403                // To compensate, we use an epsilon-based equality
404                // test on S/390 only.  We don't want to do this in
405                // general because it's less exacting.
406                useEpsilon = TRUE;
407#endif
408            }
409            else {
410                errln((UnicodeString)"FAIL: Non-numeric Formattable returned");
411                continue;
412            }
413            if (pos.getIndex() == s.length())
414            {
415                logln((UnicodeString)"  -parse-> " + a);
416                // Use epsilon comparison as necessary
417                if ((useEpsilon &&
418                    (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
419                    (!useEpsilon && a != valParse[v+ival]))
420                {
421                    errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]);
422                }
423            }
424            else {
425                errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
426                errln((UnicodeString)"  should be (" + s.length() + " chars) -> " + valParse[v+ival]);
427            }
428        }
429        for (v=0; v<lval_length; ++v)
430        {
431            UnicodeString s;
432            (*(NumberFormat*)&fmt).format(lval[v], s);
433            logln((UnicodeString)" " + lval[v] + "L -format-> " + s);
434            if (s != lvalFormat[v+ilval])
435                errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s);
436
437            ParsePosition pos(0);
438            Formattable af;
439            fmt.parse(s, af, pos);
440            if (af.getType() == Formattable::kLong ||
441                af.getType() == Formattable::kInt64) {
442                UErrorCode status = U_ZERO_ERROR;
443                int32_t a = af.getLong(status);
444                if (pos.getIndex() == s.length())
445                {
446                    logln((UnicodeString)"  -parse-> " + a);
447                    if (a != lvalParse[v+ilval])
448                        errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]);
449                }
450                else
451                    errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
452            }
453            else
454                errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
455                    + " Double: " + af.getDouble()
456                    + ", Long: " + af.getLong());
457        }
458        ival += val_length;
459        ilval += lval_length;
460    }
461}
462
463void
464NumberFormatTest::TestScientific2() {
465    // jb 2552
466    UErrorCode status = U_ZERO_ERROR;
467    DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
468    if (U_SUCCESS(status)) {
469        double num = 12.34;
470        expect(*fmt, num, "$12.34");
471        fmt->setScientificNotation(TRUE);
472        expect(*fmt, num, "$1.23E1");
473        fmt->setScientificNotation(FALSE);
474        expect(*fmt, num, "$12.34");
475    }
476    delete fmt;
477}
478
479void
480NumberFormatTest::TestScientificGrouping() {
481    // jb 2552
482    UErrorCode status = U_ZERO_ERROR;
483    DecimalFormat fmt("##0.00E0",status);
484    if (U_SUCCESS(status)) {
485        expect(fmt, .01234, "12.3E-3");
486        expect(fmt, .1234, "123E-3");
487        expect(fmt, 1.234, "1.23E0");
488        expect(fmt, 12.34, "12.3E0");
489        expect(fmt, 123.4, "123E0");
490        expect(fmt, 1234., "1.23E3");
491    }
492}
493
494/*static void setFromString(DigitList& dl, const char* str) {
495    char c;
496    UBool decimalSet = FALSE;
497    dl.clear();
498    while ((c = *str++)) {
499        if (c == '-') {
500            dl.fIsPositive = FALSE;
501        } else if (c == '+') {
502            dl.fIsPositive = TRUE;
503        } else if (c == '.') {
504            dl.fDecimalAt = dl.fCount;
505            decimalSet = TRUE;
506        } else {
507            dl.append(c);
508        }
509    }
510    if (!decimalSet) {
511        dl.fDecimalAt = dl.fCount;
512    }
513}*/
514
515void
516NumberFormatTest::TestInt64() {
517    UErrorCode status = U_ZERO_ERROR;
518    DecimalFormat fmt("#.#E0",status);
519    fmt.setMaximumFractionDigits(20);
520    if (U_SUCCESS(status)) {
521        expect(fmt, (Formattable)(int64_t)0, "0E0");
522        expect(fmt, (Formattable)(int64_t)-1, "-1E0");
523        expect(fmt, (Formattable)(int64_t)1, "1E0");
524        expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9");
525        expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9");
526        expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18");
527        expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18");
528    }
529
530    // also test digitlist
531/*    int64_t int64max = U_INT64_MAX;
532    int64_t int64min = U_INT64_MIN;
533    const char* int64maxstr = "9223372036854775807";
534    const char* int64minstr = "-9223372036854775808";
535    UnicodeString fail("fail: ");
536
537    // test max int64 value
538    DigitList dl;
539    setFromString(dl, int64maxstr);
540    {
541        if (!dl.fitsIntoInt64(FALSE)) {
542            errln(fail + int64maxstr + " didn't fit");
543        }
544        int64_t int64Value = dl.getInt64();
545        if (int64Value != int64max) {
546            errln(fail + int64maxstr);
547        }
548        dl.set(int64Value);
549        int64Value = dl.getInt64();
550        if (int64Value != int64max) {
551            errln(fail + int64maxstr);
552        }
553    }
554    // test negative of max int64 value (1 shy of min int64 value)
555    dl.fIsPositive = FALSE;
556    {
557        if (!dl.fitsIntoInt64(FALSE)) {
558            errln(fail + "-" + int64maxstr + " didn't fit");
559        }
560        int64_t int64Value = dl.getInt64();
561        if (int64Value != -int64max) {
562            errln(fail + "-" + int64maxstr);
563        }
564        dl.set(int64Value);
565        int64Value = dl.getInt64();
566        if (int64Value != -int64max) {
567            errln(fail + "-" + int64maxstr);
568        }
569    }
570    // test min int64 value
571    setFromString(dl, int64minstr);
572    {
573        if (!dl.fitsIntoInt64(FALSE)) {
574            errln(fail + "-" + int64minstr + " didn't fit");
575        }
576        int64_t int64Value = dl.getInt64();
577        if (int64Value != int64min) {
578            errln(fail + int64minstr);
579        }
580        dl.set(int64Value);
581        int64Value = dl.getInt64();
582        if (int64Value != int64min) {
583            errln(fail + int64minstr);
584        }
585    }
586    // test negative of min int 64 value (1 more than max int64 value)
587    dl.fIsPositive = TRUE; // won't fit
588    {
589        if (dl.fitsIntoInt64(FALSE)) {
590            errln(fail + "-(" + int64minstr + ") didn't fit");
591        }
592    }*/
593}
594
595// -------------------------------------
596
597// Test the handling of quotes
598void
599NumberFormatTest::TestQuotes(void)
600{
601    UErrorCode status = U_ZERO_ERROR;
602    UnicodeString *pat;
603    DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
604    if (U_FAILURE(status)) {
605        errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
606        delete sym;
607        return;
608    }
609    pat = new UnicodeString("a'fo''o'b#");
610    DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
611    UnicodeString s;
612    ((NumberFormat*)fmt)->format((int32_t)123, s);
613    logln((UnicodeString)"Pattern \"" + *pat + "\"");
614    logln((UnicodeString)" Format 123 -> " + escape(s));
615    if (!(s=="afo'ob123"))
616        errln((UnicodeString)"FAIL: Expected afo'ob123");
617
618    s.truncate(0);
619    delete fmt;
620    delete pat;
621
622    pat = new UnicodeString("a''b#");
623    fmt = new DecimalFormat(*pat, *sym, status);
624    ((NumberFormat*)fmt)->format((int32_t)123, s);
625    logln((UnicodeString)"Pattern \"" + *pat + "\"");
626    logln((UnicodeString)" Format 123 -> " + escape(s));
627    if (!(s=="a'b123"))
628        errln((UnicodeString)"FAIL: Expected a'b123");
629    delete fmt;
630    delete pat;
631    delete sym;
632}
633
634/**
635 * Test the handling of the currency symbol in patterns.
636 */
637void
638NumberFormatTest::TestCurrencySign(void)
639{
640    UErrorCode status = U_ZERO_ERROR;
641    DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
642    UnicodeString pat;
643    UChar currency = 0x00A4;
644    if (U_FAILURE(status)) {
645        errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
646        delete sym;
647        return;
648    }
649    // "\xA4#,##0.00;-\xA4#,##0.00"
650    pat.append(currency).append("#,##0.00;-").
651        append(currency).append("#,##0.00");
652    DecimalFormat *fmt = new DecimalFormat(pat, *sym, status);
653    UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s);
654    pat.truncate(0);
655    logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
656    logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
657    if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56");
658    s.truncate(0);
659    ((NumberFormat*)fmt)->format(- 1234.56, s);
660    logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
661    if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56");
662    delete fmt;
663    pat.truncate(0);
664    // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
665    pat.append(currency).append(currency).
666        append(" #,##0.00;").
667        append(currency).append(currency).
668        append(" -#,##0.00");
669    fmt = new DecimalFormat(pat, *sym, status);
670    s.truncate(0);
671    ((NumberFormat*)fmt)->format(1234.56, s);
672    logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
673    logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
674    if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56");
675    s.truncate(0);
676    ((NumberFormat*)fmt)->format(-1234.56, s);
677    logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
678    if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56");
679    delete fmt;
680    delete sym;
681    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status));
682}
683
684// -------------------------------------
685
686static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
687
688UnicodeString&
689NumberFormatTest::escape(UnicodeString& s)
690{
691    UnicodeString buf;
692    for (int32_t i=0; i<s.length(); ++i)
693    {
694        UChar c = s[(int32_t)i];
695        if (c <= (UChar)0x7F) buf += c;
696        else {
697            buf += (UChar)0x5c; buf += (UChar)0x55;
698            buf += toHexString((c & 0xF000) >> 12);
699            buf += toHexString((c & 0x0F00) >> 8);
700            buf += toHexString((c & 0x00F0) >> 4);
701            buf += toHexString(c & 0x000F);
702        }
703    }
704    return (s = buf);
705}
706
707
708// -------------------------------------
709static const char* testCases[][2]= {
710     /* locale ID */  /* expected */
711    {"ca_ES_PREEURO", "\\u20A7\\u00A01.150" },
712    {"de_LU_PREEURO", "1,150\\u00A0F" },
713    {"el_GR_PREEURO", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
714    {"en_BE_PREEURO", "1.150,50\\u00A0BEF" },
715    {"es_ES_PREEURO", "1.150\\u00A0\\u20A7" },
716    {"eu_ES_PREEURO", "\\u20A7\\u00A01.150" },
717    {"gl_ES_PREEURO", "1.150\\u00A0\\u20A7" },
718    {"it_IT_PREEURO", "ITL\\u00A01.150" },
719    {"pt_PT_PREEURO", "1,150$50\\u00A0Esc."},
720    {"en_US@currency=JPY", "\\u00A51,150"},
721    {"en_US@currency=jpy", "\\u00A51,150"},
722    {"en-US-u-cu-jpy", "\\u00A51,150"}
723};
724/**
725 * Test localized currency patterns.
726 */
727void
728NumberFormatTest::TestCurrency(void)
729{
730    UErrorCode status = U_ZERO_ERROR;
731    NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
732    if (U_FAILURE(status)) {
733        dataerrln("Error calling NumberFormat::createCurrencyInstance()");
734        return;
735    }
736
737    UnicodeString s; currencyFmt->format(1.50, s);
738    logln((UnicodeString)"Un pauvre ici a..........." + s);
739    if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
740        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$");
741    delete currencyFmt;
742    s.truncate(0);
743    char loc[256]={0};
744    int len = uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
745    (void)len;  // Suppress unused variable warning.
746    currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
747    currencyFmt->format(1.50, s);
748    logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
749    if (!(s==CharsToUnicodeString("1,50\\u00A0DEM")))
750        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DEM");
751    delete currencyFmt;
752    s.truncate(0);
753    len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
754    currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
755    currencyFmt->format(1.50, s);
756    logln((UnicodeString)"Un pauvre en France a....." + s);
757    if (!(s==CharsToUnicodeString("1,50\\u00A0F")))
758        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F");
759    delete currencyFmt;
760    if (U_FAILURE(status))
761        errln((UnicodeString)"FAIL: Status " + (int32_t)status);
762
763    for(int i=0; i < (int)(sizeof(testCases)/sizeof(testCases[i])); i++){
764        status = U_ZERO_ERROR;
765        const char *localeID = testCases[i][0];
766        UnicodeString expected(testCases[i][1], -1, US_INV);
767        expected = expected.unescape();
768        s.truncate(0);
769        char loc[256]={0};
770        uloc_canonicalize(localeID, loc, 256, &status);
771        currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
772        if(U_FAILURE(status)){
773            errln("Could not create currency formatter for locale %s",localeID);
774            continue;
775        }
776        currencyFmt->format(1150.50, s);
777        if(s!=expected){
778            errln(UnicodeString("FAIL: Expected: ")+expected
779                    + UnicodeString(" Got: ") + s
780                    + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
781        }
782        if (U_FAILURE(status)){
783            errln((UnicodeString)"FAIL: Status " + (int32_t)status);
784        }
785        delete currencyFmt;
786    }
787}
788
789// -------------------------------------
790
791/**
792 * Test the Currency object handling, new as of ICU 2.2.
793 */
794void NumberFormatTest::TestCurrencyObject() {
795    UErrorCode ec = U_ZERO_ERROR;
796    NumberFormat* fmt =
797        NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
798
799    if (U_FAILURE(ec)) {
800        dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec));
801        delete fmt;
802        return;
803    }
804
805    Locale null("", "", "");
806
807    expectCurrency(*fmt, null, 1234.56, "$1,234.56");
808
809    expectCurrency(*fmt, Locale::getFrance(),
810                   1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
811
812    expectCurrency(*fmt, Locale::getJapan(),
813                   1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
814
815    expectCurrency(*fmt, Locale("fr", "CH", ""),
816                   1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
817
818    expectCurrency(*fmt, Locale::getUS(),
819                   1234.56, "$1,234.56");
820
821    delete fmt;
822    fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
823
824    if (U_FAILURE(ec)) {
825        errln("FAIL: getCurrencyInstance(FRANCE)");
826        delete fmt;
827        return;
828    }
829
830    expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
831
832    expectCurrency(*fmt, Locale::getJapan(),
833                   1234.56, CharsToUnicodeString("1 235 \\u00A5JP")); // Yen
834
835    expectCurrency(*fmt, Locale("fr", "CH", ""),
836                   1234.56, "1 234,56 CHF"); // no more 0.05 rounding here, see cldrbug 5548
837
838    expectCurrency(*fmt, Locale::getUS(),
839                   1234.56, "1 234,56 $US");
840
841    expectCurrency(*fmt, Locale::getFrance(),
842                   1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
843
844    delete fmt;
845}
846
847// -------------------------------------
848
849/**
850 * Do rudimentary testing of parsing.
851 */
852void
853NumberFormatTest::TestParse(void)
854{
855    UErrorCode status = U_ZERO_ERROR;
856    UnicodeString arg("0");
857    DecimalFormat* format = new DecimalFormat("00", status);
858    //try {
859        Formattable n; format->parse(arg, n, status);
860        logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
861        if (n.getType() != Formattable::kLong ||
862            n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
863    delete format;
864    if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status));
865    //}
866    //catch(Exception e) {
867    //    errln((UnicodeString)"Exception caught: " + e);
868    //}
869}
870
871// -------------------------------------
872
873static const char *lenientAffixTestCases[] = {
874        "(1)",
875        "( 1)",
876        "(1 )",
877        "( 1 )"
878};
879
880static const char *lenientMinusTestCases[] = {
881    "-5",
882    "\\u22125",
883    "\\u20105"
884};
885
886static const char *lenientCurrencyTestCases[] = {
887        "$1,000",
888        "$ 1,000",
889        "$1000",
890        "$ 1000",
891        "$1 000.00",
892        "$ 1 000.00",
893        "$ 1\\u00A0000.00",
894        "1000.00"
895};
896
897// changed from () to - per cldrbug 5674
898static const char *lenientNegativeCurrencyTestCases[] = {
899        "-$1,000",
900        "-$ 1,000",
901        "-$1000",
902        "-$ 1000",
903        "-$1 000.00",
904        "-$ 1 000.00",
905        "- $ 1,000.00 ",
906        "-$ 1\\u00A0000.00",
907        "-1000.00"
908};
909
910static const char *lenientPercentTestCases[] = {
911        "25%",
912        " 25%",
913        " 25 %",
914    	"25 %",
915		"25\\u00A0%",
916		"25"
917};
918
919static const char *lenientNegativePercentTestCases[] = {
920		"-25%",
921		" -25%",
922		" - 25%",
923		"- 25 %",
924		" - 25 %",
925		"-25 %",
926		"-25\\u00A0%",
927		"-25",
928		"- 25"
929};
930
931static const char *strictFailureTestCases[] = {
932		" 1000",
933		"10,00",
934		"1,000,.0"
935};
936
937#define ARRAY_SIZE(array) ((int32_t) (sizeof (array) / sizeof(array[0])))
938
939/**
940 * Test lenient parsing.
941 */
942void
943NumberFormatTest::TestLenientParse(void)
944{
945    UErrorCode status = U_ZERO_ERROR;
946    DecimalFormat *format = new DecimalFormat("(#,##0)", status);
947    Formattable n;
948
949    if (format == NULL || U_FAILURE(status)) {
950        dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status));
951    } else {
952        format->setLenient(TRUE);
953        for (int32_t t = 0; t < ARRAY_SIZE (lenientAffixTestCases); t += 1) {
954        	UnicodeString testCase = ctou(lenientAffixTestCases[t]);
955
956            format->parse(testCase, n, status);
957            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
958
959            if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
960            	n.getLong() != 1) {
961            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t] + (UnicodeString) "\"");
962            	status = U_ZERO_ERROR;
963            }
964       }
965       delete format;
966    }
967
968    Locale en_US("en_US");
969    Locale sv_SE("sv_SE");
970
971    NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
972
973    if (mFormat == NULL || U_FAILURE(status)) {
974        dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
975    } else {
976        mFormat->setLenient(TRUE);
977        for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) {
978            UnicodeString testCase = ctou(lenientMinusTestCases[t]);
979
980            mFormat->parse(testCase, n, status);
981            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
982
983            if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
984                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
985                status = U_ZERO_ERROR;
986            }
987        }
988        delete mFormat;
989    }
990
991    mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
992
993    if (mFormat == NULL || U_FAILURE(status)) {
994        dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
995    } else {
996        mFormat->setLenient(TRUE);
997        for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) {
998            UnicodeString testCase = ctou(lenientMinusTestCases[t]);
999
1000            mFormat->parse(testCase, n, status);
1001            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1002
1003            if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
1004                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
1005                status = U_ZERO_ERROR;
1006            }
1007        }
1008        delete mFormat;
1009    }
1010
1011    NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
1012
1013    if (cFormat == NULL || U_FAILURE(status)) {
1014        dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status));
1015    } else {
1016        cFormat->setLenient(TRUE);
1017        for (int32_t t = 0; t < ARRAY_SIZE (lenientCurrencyTestCases); t += 1) {
1018        	UnicodeString testCase = ctou(lenientCurrencyTestCases[t]);
1019
1020            cFormat->parse(testCase, n, status);
1021            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1022
1023            if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1024            	n.getLong() != 1000) {
1025            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t] + (UnicodeString) "\"");
1026            	status = U_ZERO_ERROR;
1027            }
1028        }
1029
1030        for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativeCurrencyTestCases); t += 1) {
1031        	UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]);
1032
1033            cFormat->parse(testCase, n, status);
1034            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1035
1036            if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1037            	n.getLong() != -1000) {
1038            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t] + (UnicodeString) "\"");
1039            	status = U_ZERO_ERROR;
1040            }
1041        }
1042
1043        delete cFormat;
1044    }
1045
1046    NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status);
1047
1048    if (pFormat == NULL || U_FAILURE(status)) {
1049        dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status));
1050    } else {
1051        pFormat->setLenient(TRUE);
1052        for (int32_t t = 0; t < ARRAY_SIZE (lenientPercentTestCases); t += 1) {
1053        	UnicodeString testCase = ctou(lenientPercentTestCases[t]);
1054
1055        	pFormat->parse(testCase, n, status);
1056            logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1057
1058            if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1059            	n.getDouble() != 0.25) {
1060            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t] + (UnicodeString) "\"");
1061            	status = U_ZERO_ERROR;
1062            }
1063        }
1064
1065        for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativePercentTestCases); t += 1) {
1066        	UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]);
1067
1068        	pFormat->parse(testCase, n, status);
1069            logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1070
1071            if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1072            	n.getDouble() != -0.25) {
1073            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t] + (UnicodeString) "\"");
1074            	status = U_ZERO_ERROR;
1075            }
1076        }
1077
1078        delete pFormat;
1079    }
1080
1081   // Test cases that should fail with a strict parse and pass with a
1082   // lenient parse.
1083   NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
1084
1085   if (nFormat == NULL || U_FAILURE(status)) {
1086       dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
1087   } else {
1088       // first, make sure that they fail with a strict parse
1089       for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) {
1090	       UnicodeString testCase = ctou(strictFailureTestCases[t]);
1091
1092	       nFormat->parse(testCase, n, status);
1093	       logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1094
1095	       if (! U_FAILURE(status)) {
1096		       errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1097	       }
1098
1099	       status = U_ZERO_ERROR;
1100       }
1101
1102       // then, make sure that they pass with a lenient parse
1103       nFormat->setLenient(TRUE);
1104       for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) {
1105	       UnicodeString testCase = ctou(strictFailureTestCases[t]);
1106
1107	       nFormat->parse(testCase, n, status);
1108	       logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1109
1110	       if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1111	            	n.getLong() != 1000) {
1112		       errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1113		       status = U_ZERO_ERROR;
1114	       }
1115       }
1116
1117       delete nFormat;
1118   }
1119}
1120
1121// -------------------------------------
1122
1123/**
1124 * Test proper rounding by the format method.
1125 */
1126void
1127NumberFormatTest::TestRounding487(void)
1128{
1129    UErrorCode status = U_ZERO_ERROR;
1130    NumberFormat *nf = NumberFormat::createInstance(status);
1131    if (U_FAILURE(status)) {
1132        dataerrln("Error calling NumberFormat::createInstance()");
1133        return;
1134    }
1135
1136    roundingTest(*nf, 0.00159999, 4, "0.0016");
1137    roundingTest(*nf, 0.00995, 4, "0.01");
1138
1139    roundingTest(*nf, 12.3995, 3, "12.4");
1140
1141    roundingTest(*nf, 12.4999, 0, "12");
1142    roundingTest(*nf, - 19.5, 0, "-20");
1143    delete nf;
1144    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1145}
1146
1147/**
1148 * Test the functioning of the secondary grouping value.
1149 */
1150void NumberFormatTest::TestSecondaryGrouping(void) {
1151    UErrorCode status = U_ZERO_ERROR;
1152    DecimalFormatSymbols US(Locale::getUS(), status);
1153    CHECK(status, "DecimalFormatSymbols ct");
1154
1155    DecimalFormat f("#,##,###", US, status);
1156    CHECK(status, "DecimalFormat ct");
1157
1158    expect2(f, (int32_t)123456789L, "12,34,56,789");
1159    expectPat(f, "#,##,###");
1160    f.applyPattern("#,###", status);
1161    CHECK(status, "applyPattern");
1162
1163    f.setSecondaryGroupingSize(4);
1164    expect2(f, (int32_t)123456789L, "12,3456,789");
1165    expectPat(f, "#,####,###");
1166    NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
1167    CHECK_DATA(status, "createInstance(hi_IN)");
1168
1169    UnicodeString out;
1170    int32_t l = (int32_t)1876543210L;
1171    g->format(l, out);
1172    delete g;
1173    // expect "1,87,65,43,210", but with Hindi digits
1174    //         01234567890123
1175    UBool ok = TRUE;
1176    if (out.length() != 14) {
1177        ok = FALSE;
1178    } else {
1179        for (int32_t i=0; i<out.length(); ++i) {
1180            UBool expectGroup = FALSE;
1181            switch (i) {
1182            case 1:
1183            case 4:
1184            case 7:
1185            case 10:
1186                expectGroup = TRUE;
1187                break;
1188            }
1189            // Later -- fix this to get the actual grouping
1190            // character from the resource bundle.
1191            UBool isGroup = (out.charAt(i) == 0x002C);
1192            if (isGroup != expectGroup) {
1193                ok = FALSE;
1194                break;
1195            }
1196        }
1197    }
1198    if (!ok) {
1199        errln((UnicodeString)"FAIL  Expected " + l +
1200              " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1201              escape(out) + "\"");
1202    } else {
1203        logln((UnicodeString)"Ok    " + l +
1204              " x hi_IN -> \"" +
1205              escape(out) + "\"");
1206    }
1207}
1208
1209void NumberFormatTest::TestWhiteSpaceParsing(void) {
1210    UErrorCode ec = U_ZERO_ERROR;
1211    DecimalFormatSymbols US(Locale::getUS(), ec);
1212    DecimalFormat fmt("a  b#0c  ", US, ec);
1213    if (U_FAILURE(ec)) {
1214        errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
1215        return;
1216    }
1217    int32_t n = 1234;
1218    expect(fmt, "a b1234c ", n);
1219    expect(fmt, "a   b1234c   ", n);
1220}
1221
1222/**
1223 * Test currencies whose display name is a ChoiceFormat.
1224 */
1225void NumberFormatTest::TestComplexCurrency() {
1226
1227//    UErrorCode ec = U_ZERO_ERROR;
1228//    Locale loc("kn", "IN", "");
1229//    NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
1230//    if (U_SUCCESS(ec)) {
1231//        expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
1232//        Use .00392625 because that's 2^-8.  Any value less than 0.005 is fine.
1233//        expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
1234//        expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
1235//        expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
1236//        expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
1237//        expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
1238//    } else {
1239//        errln("FAIL: getCurrencyInstance(kn_IN)");
1240//    }
1241//    delete fmt;
1242
1243}
1244
1245// -------------------------------------
1246
1247void
1248NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
1249{
1250    nf.setMaximumFractionDigits(maxFractionDigits);
1251    UnicodeString out; nf.format(x, out);
1252    logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
1253    if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected);
1254}
1255
1256/**
1257 * Upgrade to alphaWorks
1258 */
1259void NumberFormatTest::TestExponent(void) {
1260    UErrorCode status = U_ZERO_ERROR;
1261    DecimalFormatSymbols US(Locale::getUS(), status);
1262    CHECK(status, "DecimalFormatSymbols constructor");
1263    DecimalFormat fmt1(UnicodeString("0.###E0"), US, status);
1264    CHECK(status, "DecimalFormat(0.###E0)");
1265    DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status);
1266    CHECK(status, "DecimalFormat(0.###E+0)");
1267    int32_t n = 1234;
1268    expect2(fmt1, n, "1.234E3");
1269    expect2(fmt2, n, "1.234E+3");
1270    expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
1271}
1272
1273/**
1274 * Upgrade to alphaWorks
1275 */
1276void NumberFormatTest::TestScientific(void) {
1277    UErrorCode status = U_ZERO_ERROR;
1278    DecimalFormatSymbols US(Locale::getUS(), status);
1279    CHECK(status, "DecimalFormatSymbols constructor");
1280
1281    // Test pattern round-trip
1282    const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1283                          "0.###E0;[0.###E0]" };
1284    int32_t PAT_length = (int32_t)(sizeof(PAT) / sizeof(PAT[0]));
1285    int32_t DIGITS[] = {
1286        // min int, max int, min frac, max frac
1287        0, 1, 0, 0, // "#E0"
1288        1, 1, 0, 4, // "0.####E0"
1289        2, 2, 3, 3, // "00.000E00"
1290        1, 3, 0, 4, // "##0.####E000"
1291        1, 1, 0, 3, // "0.###E0;[0.###E0]"
1292    };
1293    for (int32_t i=0; i<PAT_length; ++i) {
1294        UnicodeString pat(PAT[i]);
1295        DecimalFormat df(pat, US, status);
1296        CHECK(status, "DecimalFormat constructor");
1297        UnicodeString pat2;
1298        df.toPattern(pat2);
1299        if (pat == pat2) {
1300            logln(UnicodeString("Ok   Pattern rt \"") +
1301                  pat + "\" -> \"" +
1302                  pat2 + "\"");
1303        } else {
1304            errln(UnicodeString("FAIL Pattern rt \"") +
1305                  pat + "\" -> \"" +
1306                  pat2 + "\"");
1307        }
1308        // Make sure digit counts match what we expect
1309        if (df.getMinimumIntegerDigits() != DIGITS[4*i] ||
1310            df.getMaximumIntegerDigits() != DIGITS[4*i+1] ||
1311            df.getMinimumFractionDigits() != DIGITS[4*i+2] ||
1312            df.getMaximumFractionDigits() != DIGITS[4*i+3]) {
1313            errln(UnicodeString("FAIL \"" + pat +
1314                                "\" min/max int; min/max frac = ") +
1315                  df.getMinimumIntegerDigits() + "/" +
1316                  df.getMaximumIntegerDigits() + ";" +
1317                  df.getMinimumFractionDigits() + "/" +
1318                  df.getMaximumFractionDigits() + ", expect " +
1319                  DIGITS[4*i] + "/" +
1320                  DIGITS[4*i+1] + ";" +
1321                  DIGITS[4*i+2] + "/" +
1322                  DIGITS[4*i+3]);
1323        }
1324    }
1325
1326
1327    // Test the constructor for default locale. We have to
1328    // manually set the default locale, as there is no
1329    // guarantee that the default locale has the same
1330    // scientific format.
1331    Locale def = Locale::getDefault();
1332    Locale::setDefault(Locale::getUS(), status);
1333    expect2(NumberFormat::createScientificInstance(status),
1334           12345.678901,
1335           "1.2345678901E4", status);
1336    Locale::setDefault(def, status);
1337
1338    expect2(new DecimalFormat("#E0", US, status),
1339           12345.0,
1340           "1.2345E4", status);
1341    expect(new DecimalFormat("0E0", US, status),
1342           12345.0,
1343           "1E4", status);
1344    expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
1345           12345.678901,
1346           "1.2345678901E4", status);
1347    expect(new DecimalFormat("##0.###E0", US, status),
1348           12345.0,
1349           "12.34E3", status);
1350    expect(new DecimalFormat("##0.###E0", US, status),
1351           12345.00001,
1352           "12.35E3", status);
1353    expect2(new DecimalFormat("##0.####E0", US, status),
1354           (int32_t) 12345,
1355           "12.345E3", status);
1356    expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
1357           12345.678901,
1358           "1,2345678901E4", status);
1359    expect(new DecimalFormat("##0.####E0", US, status),
1360           789.12345e-9,
1361           "789.12E-9", status);
1362    expect2(new DecimalFormat("##0.####E0", US, status),
1363           780.e-9,
1364           "780E-9", status);
1365    expect(new DecimalFormat(".###E0", US, status),
1366           45678.0,
1367           ".457E5", status);
1368    expect2(new DecimalFormat(".###E0", US, status),
1369           (int32_t) 0,
1370           ".0E0", status);
1371    /*
1372    expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1373                                 new DecimalFormat("##E0", US),
1374                                 new DecimalFormat("####E0", US),
1375                                 new DecimalFormat("0E0", US),
1376                                 new DecimalFormat("00E0", US),
1377                                 new DecimalFormat("000E0", US),
1378                               },
1379           new Long(45678000),
1380           new String[] { "4.5678E7",
1381                          "45.678E6",
1382                          "4567.8E4",
1383                          "5E7",
1384                          "46E6",
1385                          "457E5",
1386                        }
1387           );
1388    !
1389    ! Unroll this test into individual tests below...
1390    !
1391    */
1392    expect2(new DecimalFormat("#E0", US, status),
1393           (int32_t) 45678000, "4.5678E7", status);
1394    expect2(new DecimalFormat("##E0", US, status),
1395           (int32_t) 45678000, "45.678E6", status);
1396    expect2(new DecimalFormat("####E0", US, status),
1397           (int32_t) 45678000, "4567.8E4", status);
1398    expect(new DecimalFormat("0E0", US, status),
1399           (int32_t) 45678000, "5E7", status);
1400    expect(new DecimalFormat("00E0", US, status),
1401           (int32_t) 45678000, "46E6", status);
1402    expect(new DecimalFormat("000E0", US, status),
1403           (int32_t) 45678000, "457E5", status);
1404    /*
1405    expect(new DecimalFormat("###E0", US, status),
1406           new Object[] { new Double(0.0000123), "12.3E-6",
1407                          new Double(0.000123), "123E-6",
1408                          new Double(0.00123), "1.23E-3",
1409                          new Double(0.0123), "12.3E-3",
1410                          new Double(0.123), "123E-3",
1411                          new Double(1.23), "1.23E0",
1412                          new Double(12.3), "12.3E0",
1413                          new Double(123), "123E0",
1414                          new Double(1230), "1.23E3",
1415                         });
1416    !
1417    ! Unroll this test into individual tests below...
1418    !
1419    */
1420    expect2(new DecimalFormat("###E0", US, status),
1421           0.0000123, "12.3E-6", status);
1422    expect2(new DecimalFormat("###E0", US, status),
1423           0.000123, "123E-6", status);
1424    expect2(new DecimalFormat("###E0", US, status),
1425           0.00123, "1.23E-3", status);
1426    expect2(new DecimalFormat("###E0", US, status),
1427           0.0123, "12.3E-3", status);
1428    expect2(new DecimalFormat("###E0", US, status),
1429           0.123, "123E-3", status);
1430    expect2(new DecimalFormat("###E0", US, status),
1431           1.23, "1.23E0", status);
1432    expect2(new DecimalFormat("###E0", US, status),
1433           12.3, "12.3E0", status);
1434    expect2(new DecimalFormat("###E0", US, status),
1435           123.0, "123E0", status);
1436    expect2(new DecimalFormat("###E0", US, status),
1437           1230.0, "1.23E3", status);
1438    /*
1439    expect(new DecimalFormat("0.#E+00", US, status),
1440           new Object[] { new Double(0.00012), "1.2E-04",
1441                          new Long(12000),     "1.2E+04",
1442                         });
1443    !
1444    ! Unroll this test into individual tests below...
1445    !
1446    */
1447    expect2(new DecimalFormat("0.#E+00", US, status),
1448           0.00012, "1.2E-04", status);
1449    expect2(new DecimalFormat("0.#E+00", US, status),
1450           (int32_t) 12000, "1.2E+04", status);
1451}
1452
1453/**
1454 * Upgrade to alphaWorks
1455 */
1456void NumberFormatTest::TestPad(void) {
1457    UErrorCode status = U_ZERO_ERROR;
1458    DecimalFormatSymbols US(Locale::getUS(), status);
1459    CHECK(status, "DecimalFormatSymbols constructor");
1460
1461    expect2(new DecimalFormat("*^##.##", US, status),
1462           int32_t(0), "^^^^0", status);
1463    expect2(new DecimalFormat("*^##.##", US, status),
1464           -1.3, "^-1.3", status);
1465    expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1466           int32_t(0), "0.0E0______ g-m/s^2", status);
1467    expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1468           1.0/3, "333.333E-3_ g-m/s^2", status);
1469    expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1470           int32_t(0), "0.0______ g-m/s^2", status);
1471    expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1472           1.0/3, "0.33333__ g-m/s^2", status);
1473
1474    // Test padding before a sign
1475    const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1476    expect2(new DecimalFormat(formatStr, US, status),
1477           int32_t(-10),  "xxxxxxxxxx(10.0)", status);
1478    expect2(new DecimalFormat(formatStr, US, status),
1479           int32_t(-1000),"xxxxxxx(1,000.0)", status);
1480    expect2(new DecimalFormat(formatStr, US, status),
1481           int32_t(-1000000),"xxx(1,000,000.0)", status);
1482    expect2(new DecimalFormat(formatStr, US, status),
1483           -100.37,       "xxxxxxxx(100.37)", status);
1484    expect2(new DecimalFormat(formatStr, US, status),
1485           -10456.37,     "xxxxx(10,456.37)", status);
1486    expect2(new DecimalFormat(formatStr, US, status),
1487           -1120456.37,   "xx(1,120,456.37)", status);
1488    expect2(new DecimalFormat(formatStr, US, status),
1489           -112045600.37, "(112,045,600.37)", status);
1490    expect2(new DecimalFormat(formatStr, US, status),
1491           -1252045600.37,"(1,252,045,600.37)", status);
1492
1493    expect2(new DecimalFormat(formatStr, US, status),
1494           int32_t(10),  "xxxxxxxxxxxx10.0", status);
1495    expect2(new DecimalFormat(formatStr, US, status),
1496           int32_t(1000),"xxxxxxxxx1,000.0", status);
1497    expect2(new DecimalFormat(formatStr, US, status),
1498           int32_t(1000000),"xxxxx1,000,000.0", status);
1499    expect2(new DecimalFormat(formatStr, US, status),
1500           100.37,       "xxxxxxxxxx100.37", status);
1501    expect2(new DecimalFormat(formatStr, US, status),
1502           10456.37,     "xxxxxxx10,456.37", status);
1503    expect2(new DecimalFormat(formatStr, US, status),
1504           1120456.37,   "xxxx1,120,456.37", status);
1505    expect2(new DecimalFormat(formatStr, US, status),
1506           112045600.37, "xx112,045,600.37", status);
1507    expect2(new DecimalFormat(formatStr, US, status),
1508           10252045600.37,"10,252,045,600.37", status);
1509
1510
1511    // Test padding between a sign and a number
1512    const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1513    expect2(new DecimalFormat(formatStr2, US, status),
1514           int32_t(-10),  "(10.0xxxxxxxxxx)", status);
1515    expect2(new DecimalFormat(formatStr2, US, status),
1516           int32_t(-1000),"(1,000.0xxxxxxx)", status);
1517    expect2(new DecimalFormat(formatStr2, US, status),
1518           int32_t(-1000000),"(1,000,000.0xxx)", status);
1519    expect2(new DecimalFormat(formatStr2, US, status),
1520           -100.37,       "(100.37xxxxxxxx)", status);
1521    expect2(new DecimalFormat(formatStr2, US, status),
1522           -10456.37,     "(10,456.37xxxxx)", status);
1523    expect2(new DecimalFormat(formatStr2, US, status),
1524           -1120456.37,   "(1,120,456.37xx)", status);
1525    expect2(new DecimalFormat(formatStr2, US, status),
1526           -112045600.37, "(112,045,600.37)", status);
1527    expect2(new DecimalFormat(formatStr2, US, status),
1528           -1252045600.37,"(1,252,045,600.37)", status);
1529
1530    expect2(new DecimalFormat(formatStr2, US, status),
1531           int32_t(10),  "10.0xxxxxxxxxxxx", status);
1532    expect2(new DecimalFormat(formatStr2, US, status),
1533           int32_t(1000),"1,000.0xxxxxxxxx", status);
1534    expect2(new DecimalFormat(formatStr2, US, status),
1535           int32_t(1000000),"1,000,000.0xxxxx", status);
1536    expect2(new DecimalFormat(formatStr2, US, status),
1537           100.37,       "100.37xxxxxxxxxx", status);
1538    expect2(new DecimalFormat(formatStr2, US, status),
1539           10456.37,     "10,456.37xxxxxxx", status);
1540    expect2(new DecimalFormat(formatStr2, US, status),
1541           1120456.37,   "1,120,456.37xxxx", status);
1542    expect2(new DecimalFormat(formatStr2, US, status),
1543           112045600.37, "112,045,600.37xx", status);
1544    expect2(new DecimalFormat(formatStr2, US, status),
1545           10252045600.37,"10,252,045,600.37", status);
1546
1547    //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1548    DecimalFormat fmt("#", US, status);
1549    CHECK(status, "DecimalFormat constructor");
1550    UnicodeString padString("P");
1551    fmt.setPadCharacter(padString);
1552    expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString);
1553    fmt.setPadCharacter((UnicodeString)"^");
1554    expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^");
1555    //commented untill implementation is complete
1556  /*  fmt.setPadCharacter((UnicodeString)"^^^");
1557    expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1558    padString.remove();
1559    padString.append((UChar)0x0061);
1560    padString.append((UChar)0x0302);
1561    fmt.setPadCharacter(padString);
1562    UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1563    UnicodeString pattern(patternChars);
1564    expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1565 */
1566
1567}
1568
1569/**
1570 * Upgrade to alphaWorks
1571 */
1572void NumberFormatTest::TestPatterns2(void) {
1573    UErrorCode status = U_ZERO_ERROR;
1574    DecimalFormatSymbols US(Locale::getUS(), status);
1575    CHECK(status, "DecimalFormatSymbols constructor");
1576
1577    DecimalFormat fmt("#", US, status);
1578    CHECK(status, "DecimalFormat constructor");
1579
1580    UChar hat = 0x005E; /*^*/
1581
1582    expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
1583    expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
1584    expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
1585    expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
1586    expectPad(fmt, "$*^$#", ILLEGAL);
1587    expectPad(fmt, "#$*^$", ILLEGAL);
1588    expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
1589              12, (UChar)0x0078 /*x*/);
1590    expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
1591              3, (UChar)0x0078 /*x*/);
1592    expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
1593              10, (UChar)0x0061 /*a*/);
1594
1595    fmt.applyPattern("AA#,##0.00ZZ", status);
1596    CHECK(status, "applyPattern");
1597    fmt.setPadCharacter(hat);
1598
1599    fmt.setFormatWidth(10);
1600
1601    fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
1602    expectPat(fmt, "*^AA#,##0.00ZZ");
1603
1604    fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
1605    expectPat(fmt, "AA#,##0.00*^ZZ");
1606
1607    fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
1608    expectPat(fmt, "AA#,##0.00ZZ*^");
1609
1610    //            12  3456789012
1611    UnicodeString exp("AA*^#,##0.00ZZ", "");
1612    fmt.setFormatWidth(12);
1613    fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
1614    expectPat(fmt, exp);
1615
1616    fmt.setFormatWidth(13);
1617    //              12  34567890123
1618    expectPat(fmt, "AA*^##,##0.00ZZ");
1619
1620    fmt.setFormatWidth(14);
1621    //              12  345678901234
1622    expectPat(fmt, "AA*^###,##0.00ZZ");
1623
1624    fmt.setFormatWidth(15);
1625    //              12  3456789012345
1626    expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
1627
1628    fmt.setFormatWidth(16);
1629    //              12  34567890123456
1630    expectPat(fmt, "AA*^#,###,##0.00ZZ");
1631}
1632
1633void NumberFormatTest::TestSurrogateSupport(void) {
1634    UErrorCode status = U_ZERO_ERROR;
1635    DecimalFormatSymbols custom(Locale::getUS(), status);
1636    CHECK(status, "DecimalFormatSymbols constructor");
1637
1638    custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
1639    custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
1640    custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
1641    custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
1642
1643    UnicodeString patternStr("*\\U00010000##.##", "");
1644    patternStr = patternStr.unescape();
1645    UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1646    expStr = expStr.unescape();
1647    expect2(new DecimalFormat(patternStr, custom, status),
1648           int32_t(0), expStr, status);
1649
1650    status = U_ZERO_ERROR;
1651    expect2(new DecimalFormat("*^##.##", custom, status),
1652           int32_t(0), "^^^^0", status);
1653    status = U_ZERO_ERROR;
1654    expect2(new DecimalFormat("##.##", custom, status),
1655           -1.3, " minus 1decimal3", status);
1656    status = U_ZERO_ERROR;
1657    expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
1658           int32_t(0), "0decimal0exponent0 g-m/s^2", status);
1659    status = U_ZERO_ERROR;
1660    expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
1661           1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
1662    status = U_ZERO_ERROR;
1663    expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
1664           int32_t(0), "0decimal0 g-m/s^2", status);
1665    status = U_ZERO_ERROR;
1666    expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
1667           1.0/3, "0decimal33333 g-m/s^2", status);
1668
1669    UnicodeString zero((UChar32)0x10000);
1670    UnicodeString one((UChar32)0x10001);
1671    UnicodeString two((UChar32)0x10002);
1672    UnicodeString five((UChar32)0x10005);
1673    custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
1674    custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one);
1675    custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two);
1676    custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five);
1677    expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1678    expStr = expStr.unescape();
1679    status = U_ZERO_ERROR;
1680    expect2(new DecimalFormat("##0.000", custom, status),
1681           1.25, expStr, status);
1682
1683    custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
1684    custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
1685    custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
1686    patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
1687    patternStr = patternStr.unescape();
1688    expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1689    status = U_ZERO_ERROR;
1690    expect2(new DecimalFormat(patternStr, custom, status),
1691           int32_t(-20), expStr, status);
1692
1693    custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent");
1694    patternStr = "'You''ve lost ' -0.00 %' of your money today'";
1695    patternStr = patternStr.unescape();
1696    expStr = UnicodeString(" minus You've lost   minus 2000decimal00 percent of your money today", "");
1697    status = U_ZERO_ERROR;
1698    expect2(new DecimalFormat(patternStr, custom, status),
1699           int32_t(-20), expStr, status);
1700}
1701
1702void NumberFormatTest::TestCurrencyPatterns(void) {
1703    int32_t i, locCount;
1704    const Locale* locs = NumberFormat::getAvailableLocales(locCount);
1705    for (i=0; i<locCount; ++i) {
1706        UErrorCode ec = U_ZERO_ERROR;
1707        NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec);
1708        if (U_FAILURE(ec)) {
1709            errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
1710        } else {
1711            // Make sure currency formats do not have a variable number
1712            // of fraction digits
1713            int32_t min = nf->getMinimumFractionDigits();
1714            int32_t max = nf->getMaximumFractionDigits();
1715            if (min != max) {
1716                UnicodeString a, b;
1717                nf->format(1.0, a);
1718                nf->format(1.125, b);
1719                errln((UnicodeString)"FAIL: " + locs[i].getName() +
1720                      " min fraction digits != max fraction digits; "
1721                      "x 1.0 => " + escape(a) +
1722                      "; x 1.125 => " + escape(b));
1723            }
1724
1725            // Make sure EURO currency formats have exactly 2 fraction digits
1726            DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
1727            if (df != NULL) {
1728                if (u_strcmp(EUR, df->getCurrency()) == 0) {
1729                    if (min != 2 || max != 2) {
1730                        UnicodeString a;
1731                        nf->format(1.0, a);
1732                        errln((UnicodeString)"FAIL: " + locs[i].getName() +
1733                              " is a EURO format but it does not have 2 fraction digits; "
1734                              "x 1.0 => " +
1735                              escape(a));
1736                    }
1737                }
1738            }
1739        }
1740        delete nf;
1741    }
1742}
1743
1744void NumberFormatTest::TestRegCurrency(void) {
1745#if !UCONFIG_NO_SERVICE
1746    UErrorCode status = U_ZERO_ERROR;
1747    UChar USD[4];
1748    ucurr_forLocale("en_US", USD, 4, &status);
1749    UChar YEN[4];
1750    ucurr_forLocale("ja_JP", YEN, 4, &status);
1751    UChar TMP[4];
1752    static const UChar QQQ[] = {0x51, 0x51, 0x51, 0};
1753    if(U_FAILURE(status)) {
1754        errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status));
1755        return;
1756    }
1757
1758    UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
1759    UCurrRegistryKey enUSEUROkey = ucurr_register(QQQ, "en_US_EURO", &status);
1760
1761    ucurr_forLocale("en_US", TMP, 4, &status);
1762    if (u_strcmp(YEN, TMP) != 0) {
1763        errln("FAIL: didn't return YEN registered for en_US");
1764    }
1765
1766    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1767    if (u_strcmp(QQQ, TMP) != 0) {
1768        errln("FAIL: didn't return QQQ for en_US_EURO");
1769    }
1770
1771    int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
1772    if (fallbackLen) {
1773        errln("FAIL: tried to fallback en_XX_BAR");
1774    }
1775    status = U_ZERO_ERROR; // reset
1776
1777    if (!ucurr_unregister(enkey, &status)) {
1778        errln("FAIL: couldn't unregister enkey");
1779    }
1780
1781    ucurr_forLocale("en_US", TMP, 4, &status);
1782    if (u_strcmp(USD, TMP) != 0) {
1783        errln("FAIL: didn't return USD for en_US after unregister of en_US");
1784    }
1785    status = U_ZERO_ERROR; // reset
1786
1787    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1788    if (u_strcmp(QQQ, TMP) != 0) {
1789        errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
1790    }
1791
1792    ucurr_forLocale("en_US_BLAH", TMP, 4, &status);
1793    if (u_strcmp(USD, TMP) != 0) {
1794        errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1795    }
1796    status = U_ZERO_ERROR; // reset
1797
1798    if (!ucurr_unregister(enUSEUROkey, &status)) {
1799        errln("FAIL: couldn't unregister enUSEUROkey");
1800    }
1801
1802    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1803    if (u_strcmp(EUR, TMP) != 0) {
1804        errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
1805    }
1806    status = U_ZERO_ERROR; // reset
1807#endif
1808}
1809
1810void NumberFormatTest::TestCurrencyNames(void) {
1811    // Do a basic check of getName()
1812    // USD { "US$", "US Dollar"            } // 04/04/1792-
1813    UErrorCode ec = U_ZERO_ERROR;
1814    static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/
1815    static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/
1816    static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1817    static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
1818    UBool isChoiceFormat;
1819    int32_t len;
1820    const UBool possibleDataError = TRUE;
1821    // Warning: HARD-CODED LOCALE DATA in this test.  If it fails, CHECK
1822    // THE LOCALE DATA before diving into the code.
1823    assertEquals("USD.getName(SYMBOL_NAME)",
1824                 UnicodeString("$"),
1825                 UnicodeString(ucurr_getName(USD, "en",
1826                                             UCURR_SYMBOL_NAME,
1827                                             &isChoiceFormat, &len, &ec)),
1828                                             possibleDataError);
1829    assertEquals("USD.getName(LONG_NAME)",
1830                 UnicodeString("US Dollar"),
1831                 UnicodeString(ucurr_getName(USD, "en",
1832                                             UCURR_LONG_NAME,
1833                                             &isChoiceFormat, &len, &ec)),
1834                                             possibleDataError);
1835    assertEquals("CAD.getName(SYMBOL_NAME)",
1836                 UnicodeString("CA$"),
1837                 UnicodeString(ucurr_getName(CAD, "en",
1838                                             UCURR_SYMBOL_NAME,
1839                                             &isChoiceFormat, &len, &ec)),
1840                                             possibleDataError);
1841    assertEquals("CAD.getName(SYMBOL_NAME)",
1842                 UnicodeString("$"),
1843                 UnicodeString(ucurr_getName(CAD, "en_CA",
1844                                             UCURR_SYMBOL_NAME,
1845                                             &isChoiceFormat, &len, &ec)),
1846                                             possibleDataError);
1847    assertEquals("USD.getName(SYMBOL_NAME) in en_AU",
1848                 UnicodeString("US$"),
1849                 UnicodeString(ucurr_getName(USD, "en_AU",
1850                                             UCURR_SYMBOL_NAME,
1851                                             &isChoiceFormat, &len, &ec)),
1852                                             possibleDataError);
1853    assertEquals("CAD.getName(SYMBOL_NAME)",
1854                 UnicodeString("CA$"),
1855                 UnicodeString(ucurr_getName(CAD, "en_AU",
1856                                             UCURR_SYMBOL_NAME,
1857                                             &isChoiceFormat, &len, &ec)),
1858                                             possibleDataError);
1859    assertEquals("USX.getName(LONG_NAME)",
1860                 UnicodeString("USX"),
1861                 UnicodeString(ucurr_getName(USX, "en_US",
1862                                             UCURR_LONG_NAME,
1863                                             &isChoiceFormat, &len, &ec)),
1864                                             possibleDataError);
1865    assertSuccess("ucurr_getName", ec);
1866
1867    ec = U_ZERO_ERROR;
1868
1869    // Test that a default or fallback warning is being returned. JB 4239.
1870    ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat,
1871                            &len, &ec);
1872    assertTrue("ucurr_getName (es_ES fallback)",
1873                    U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
1874
1875    ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat,
1876                            &len, &ec);
1877    assertTrue("ucurr_getName (zh_TW fallback)",
1878                    U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
1879
1880    ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
1881                            &len, &ec);
1882    assertTrue("ucurr_getName (en_US default)",
1883                    U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE);
1884
1885    ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat,
1886                            &len, &ec);
1887    assertTrue("ucurr_getName (ti default)",
1888                    U_USING_DEFAULT_WARNING == ec, TRUE);
1889
1890    // Test that a default warning is being returned when falling back to root. JB 4536.
1891    ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
1892                            &len, &ec);
1893    assertTrue("ucurr_getName (cy default to root)",
1894                    U_USING_DEFAULT_WARNING == ec, TRUE);
1895
1896    // TODO add more tests later
1897}
1898
1899void NumberFormatTest::TestCurrencyUnit(void){
1900    UErrorCode ec = U_ZERO_ERROR;
1901    static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1902    static const UChar BAD[] = {63, 63, 63, 0}; /*???*/
1903    static const UChar BAD2[] = {63, 63, 65, 0}; /*???*/
1904    CurrencyUnit cu(USD, ec);
1905    assertSuccess("CurrencyUnit", ec);
1906
1907    const UChar * r = cu.getISOCurrency(); // who is the buffer owner ?
1908    assertEquals("getISOCurrency()", USD, r);
1909
1910    CurrencyUnit cu2(cu);
1911    if (!(cu2 == cu)){
1912        errln("CurrencyUnit copy constructed object should be same");
1913    }
1914
1915    CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
1916    if (!(*cu3 == cu)){
1917        errln("CurrencyUnit cloned object should be same");
1918    }
1919    CurrencyUnit bad(BAD, ec);
1920    assertSuccess("CurrencyUnit", ec);
1921    if (cu.getIndex() == bad.getIndex()) {
1922        errln("Indexes of different currencies should differ.");
1923    }
1924    CurrencyUnit bad2(BAD2, ec);
1925    assertSuccess("CurrencyUnit", ec);
1926    if (bad2.getIndex() != bad.getIndex()) {
1927        errln("Indexes of unrecognized currencies should be the same.");
1928    }
1929    if (bad == bad2) {
1930        errln("Different unrecognized currencies should not be equal.");
1931    }
1932    bad = bad2;
1933    if (bad != bad2) {
1934        errln("Currency unit assignment should be the same.");
1935    }
1936    delete cu3;
1937}
1938
1939void NumberFormatTest::TestCurrencyAmount(void){
1940    UErrorCode ec = U_ZERO_ERROR;
1941    static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1942    CurrencyAmount ca(9, USD, ec);
1943    assertSuccess("CurrencyAmount", ec);
1944
1945    CurrencyAmount ca2(ca);
1946    if (!(ca2 == ca)){
1947        errln("CurrencyAmount copy constructed object should be same");
1948    }
1949
1950    ca2=ca;
1951    if (!(ca2 == ca)){
1952        errln("CurrencyAmount assigned object should be same");
1953    }
1954
1955    CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone();
1956    if (!(*ca3 == ca)){
1957        errln("CurrencyAmount cloned object should be same");
1958    }
1959    delete ca3;
1960}
1961
1962void NumberFormatTest::TestSymbolsWithBadLocale(void) {
1963    Locale locDefault;
1964    static const char *badLocales[] = {
1965        // length < ULOC_FULLNAME_CAPACITY
1966        "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
1967
1968        // length > ULOC_FULLNAME_CAPACITY
1969        "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"
1970    }; // expect U_USING_DEFAULT_WARNING for both
1971
1972    unsigned int i;
1973    for (i = 0; i < sizeof(badLocales) / sizeof(char*); i++) {
1974        const char *localeName = badLocales[i];
1975        Locale locBad(localeName);
1976        UErrorCode status = U_ZERO_ERROR;
1977        UnicodeString intlCurrencySymbol((UChar)0xa4);
1978
1979        intlCurrencySymbol.append((UChar)0xa4);
1980
1981        logln("Current locale is %s", Locale::getDefault().getName());
1982        Locale::setDefault(locBad, status);
1983        logln("Current locale is %s", Locale::getDefault().getName());
1984        DecimalFormatSymbols mySymbols(status);
1985        if (status != U_USING_DEFAULT_WARNING) {
1986            errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
1987        }
1988        if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
1989            errln("DecimalFormatSymbols does not have the right locale.", locBad.getName());
1990        }
1991        int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol;
1992        for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) {
1993            UnicodeString symbolString = mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum);
1994            logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ") + prettify(symbolString));
1995            if (symbolString.length() == 0
1996                && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
1997                && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
1998            {
1999                errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
2000            }
2001        }
2002
2003        status = U_ZERO_ERROR;
2004        Locale::setDefault(locDefault, status);
2005        logln("Current locale is %s", Locale::getDefault().getName());
2006    }
2007}
2008
2009/**
2010 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
2011 * behave the same, except for memory ownership semantics. (No
2012 * version of this test on Java, since Java has only one method.)
2013 */
2014void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
2015    UErrorCode ec = U_ZERO_ERROR;
2016    DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2017    if (U_FAILURE(ec)) {
2018        errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec));
2019        delete sym;
2020        return;
2021    }
2022    UnicodeString pat(" #,##0.00");
2023    pat.insert(0, (UChar)0x00A4);
2024    DecimalFormat fmt(pat, sym, ec);
2025    if (U_FAILURE(ec)) {
2026        errln("Fail: DecimalFormat constructor");
2027        return;
2028    }
2029
2030    UnicodeString str;
2031    fmt.format(2350.75, str);
2032    if (str == "$ 2,350.75") {
2033        logln(str);
2034    } else {
2035        dataerrln("Fail: " + str + ", expected $ 2,350.75");
2036    }
2037
2038    sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2039    if (U_FAILURE(ec)) {
2040        errln("Fail: DecimalFormatSymbols constructor");
2041        delete sym;
2042        return;
2043    }
2044    sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2045    fmt.adoptDecimalFormatSymbols(sym);
2046
2047    str.truncate(0);
2048    fmt.format(2350.75, str);
2049    if (str == "Q 2,350.75") {
2050        logln(str);
2051    } else {
2052        dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2053    }
2054
2055    sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2056    if (U_FAILURE(ec)) {
2057        errln("Fail: DecimalFormatSymbols constructor");
2058        delete sym;
2059        return;
2060    }
2061    DecimalFormat fmt2(pat, sym, ec);
2062    if (U_FAILURE(ec)) {
2063        errln("Fail: DecimalFormat constructor");
2064        return;
2065    }
2066
2067    DecimalFormatSymbols sym2(Locale::getUS(), ec);
2068    if (U_FAILURE(ec)) {
2069        errln("Fail: DecimalFormatSymbols constructor");
2070        return;
2071    }
2072    sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2073    fmt2.setDecimalFormatSymbols(sym2);
2074
2075    str.truncate(0);
2076    fmt2.format(2350.75, str);
2077    if (str == "Q 2,350.75") {
2078        logln(str);
2079    } else {
2080        dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2081    }
2082}
2083
2084void NumberFormatTest::TestPerMill() {
2085    UErrorCode ec = U_ZERO_ERROR;
2086    UnicodeString str;
2087    DecimalFormat fmt(ctou("###.###\\u2030"), ec);
2088    if (!assertSuccess("DecimalFormat ct", ec)) return;
2089    assertEquals("0.4857 x ###.###\\u2030",
2090                 ctou("485.7\\u2030"), fmt.format(0.4857, str));
2091
2092    DecimalFormatSymbols sym(Locale::getUS(), ec);
2093    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
2094    DecimalFormat fmt2("", sym, ec);
2095    fmt2.applyLocalizedPattern("###.###m", ec);
2096    if (!assertSuccess("setup", ec)) return;
2097    str.truncate(0);
2098    assertEquals("0.4857 x ###.###m",
2099                 "485.7m", fmt2.format(0.4857, str));
2100}
2101
2102/**
2103 * Generic test for patterns that should be legal/illegal.
2104 */
2105void NumberFormatTest::TestIllegalPatterns() {
2106    // Test cases:
2107    // Prefix with "-:" for illegal patterns
2108    // Prefix with "+:" for legal patterns
2109    const char* DATA[] = {
2110        // Unquoted special characters in the suffix are illegal
2111        "-:000.000|###",
2112        "+:000.000'|###'",
2113        0
2114    };
2115    for (int32_t i=0; DATA[i]; ++i) {
2116        const char* pat=DATA[i];
2117        UBool valid = (*pat) == '+';
2118        pat += 2;
2119        UErrorCode ec = U_ZERO_ERROR;
2120        DecimalFormat fmt(pat, ec); // locale doesn't matter here
2121        if (U_SUCCESS(ec) == valid) {
2122            logln("Ok: pattern \"%s\": %s",
2123                  pat, u_errorName(ec));
2124        } else {
2125            errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s",
2126                  pat, (valid?"succeeded":"failed"),
2127                  u_errorName(ec));
2128        }
2129    }
2130}
2131
2132//----------------------------------------------------------------------
2133
2134static const char* KEYWORDS[] = {
2135    /*0*/ "ref=", // <reference pattern to parse numbers>
2136    /*1*/ "loc=", // <locale for formats>
2137    /*2*/ "f:",   // <pattern or '-'> <number> <exp. string>
2138    /*3*/ "fp:",  // <pattern or '-'> <number> <exp. string> <exp. number>
2139    /*4*/ "rt:",  // <pattern or '-'> <(exp.) number> <(exp.) string>
2140    /*5*/ "p:",   // <pattern or '-'> <string> <exp. number>
2141    /*6*/ "perr:", // <pattern or '-'> <invalid string>
2142    /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
2143    /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2144    0
2145};
2146
2147/**
2148 * Return an integer representing the next token from this
2149 * iterator.  The integer will be an index into the given list, or
2150 * -1 if there are no more tokens, or -2 if the token is not on
2151 * the list.
2152 */
2153static int32_t keywordIndex(const UnicodeString& tok) {
2154    for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
2155        if (tok==KEYWORDS[i]) {
2156            return i;
2157        }
2158    }
2159    return -1;
2160}
2161
2162/**
2163 * Parse a CurrencyAmount using the given NumberFormat, with
2164 * the 'delim' character separating the number and the currency.
2165 */
2166static void parseCurrencyAmount(const UnicodeString& str,
2167                                const NumberFormat& fmt,
2168                                UChar delim,
2169                                Formattable& result,
2170                                UErrorCode& ec) {
2171    UnicodeString num, cur;
2172    int32_t i = str.indexOf(delim);
2173    str.extractBetween(0, i, num);
2174    str.extractBetween(i+1, INT32_MAX, cur);
2175    Formattable n;
2176    fmt.parse(num, n, ec);
2177    result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
2178}
2179
2180void NumberFormatTest::TestCases() {
2181    UErrorCode ec = U_ZERO_ERROR;
2182    TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
2183    if (U_FAILURE(ec)) {
2184        dataerrln("Couldn't open NumberFormatTestCases.txt");
2185        return;
2186    }
2187    TokenIterator tokens(&reader);
2188
2189    Locale loc("en", "US", "");
2190    DecimalFormat *ref = 0, *fmt = 0;
2191    MeasureFormat *mfmt = 0;
2192    UnicodeString pat, tok, mloc, str, out, where, currAmt;
2193    Formattable n;
2194
2195    for (;;) {
2196        ec = U_ZERO_ERROR;
2197        if (!tokens.next(tok, ec)) {
2198            break;
2199        }
2200        where = UnicodeString("(") + tokens.getLineNumber() + ") ";
2201        int32_t cmd = keywordIndex(tok);
2202        switch (cmd) {
2203        case 0:
2204            // ref= <reference pattern>
2205            if (!tokens.next(tok, ec)) goto error;
2206            delete ref;
2207            ref = new DecimalFormat(tok,
2208                      new DecimalFormatSymbols(Locale::getUS(), ec), ec);
2209            if (U_FAILURE(ec)) {
2210                dataerrln("Error constructing DecimalFormat");
2211                goto error;
2212            }
2213            break;
2214        case 1:
2215            // loc= <locale>
2216            if (!tokens.next(tok, ec)) goto error;
2217            loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
2218            break;
2219        case 2: // f:
2220        case 3: // fp:
2221        case 4: // rt:
2222        case 5: // p:
2223            if (!tokens.next(tok, ec)) goto error;
2224            if (tok != "-") {
2225                pat = tok;
2226                delete fmt;
2227                fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
2228                if (U_FAILURE(ec)) {
2229                    errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
2230                    ec = U_ZERO_ERROR;
2231                    if (!tokens.next(tok, ec)) goto error;
2232                    if (!tokens.next(tok, ec)) goto error;
2233                    if (cmd == 3) {
2234                        if (!tokens.next(tok, ec)) goto error;
2235                    }
2236                    continue;
2237                }
2238            }
2239            if (cmd == 2 || cmd == 3 || cmd == 4) {
2240                // f: <pattern or '-'> <number> <exp. string>
2241                // fp: <pattern or '-'> <number> <exp. string> <exp. number>
2242                // rt: <pattern or '-'> <number> <string>
2243                UnicodeString num;
2244                if (!tokens.next(num, ec)) goto error;
2245                if (!tokens.next(str, ec)) goto error;
2246                ref->parse(num, n, ec);
2247                assertSuccess("parse", ec);
2248                assertEquals(where + "\"" + pat + "\".format(" + num + ")",
2249                             str, fmt->format(n, out.remove(), ec));
2250                assertSuccess("format", ec);
2251                if (cmd == 3) { // fp:
2252                    if (!tokens.next(num, ec)) goto error;
2253                    ref->parse(num, n, ec);
2254                    assertSuccess("parse", ec);
2255                }
2256                if (cmd != 2) { // != f:
2257                    Formattable m;
2258                    fmt->parse(str, m, ec);
2259                    assertSuccess("parse", ec);
2260                    assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2261                                 n, m);
2262                }
2263            }
2264            // p: <pattern or '-'> <string to parse> <exp. number>
2265            else {
2266                UnicodeString expstr;
2267                if (!tokens.next(str, ec)) goto error;
2268                if (!tokens.next(expstr, ec)) goto error;
2269                Formattable exp, n;
2270                ref->parse(expstr, exp, ec);
2271                assertSuccess("parse", ec);
2272                fmt->parse(str, n, ec);
2273                assertSuccess("parse", ec);
2274                assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2275                             exp, n);
2276            }
2277            break;
2278        case 8: // fpc:
2279            if (!tokens.next(tok, ec)) goto error;
2280            if (tok != "-") {
2281                mloc = tok;
2282                delete mfmt;
2283                mfmt = MeasureFormat::createCurrencyFormat(
2284                    Locale::createFromName(
2285                        CharString().appendInvariantChars(mloc, ec).data()), ec);
2286                if (U_FAILURE(ec)) {
2287                    errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
2288                    ec = U_ZERO_ERROR;
2289                    if (!tokens.next(tok, ec)) goto error;
2290                    if (!tokens.next(tok, ec)) goto error;
2291                    if (!tokens.next(tok, ec)) goto error;
2292                    continue;
2293                }
2294            }
2295            // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2296            if (!tokens.next(currAmt, ec)) goto error;
2297            if (!tokens.next(str, ec)) goto error;
2298            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2299            if (assertSuccess("parseCurrencyAmount", ec)) {
2300                assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
2301                             str, mfmt->format(n, out.remove(), ec));
2302                assertSuccess("format", ec);
2303            }
2304            if (!tokens.next(currAmt, ec)) goto error;
2305            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2306            if (assertSuccess("parseCurrencyAmount", ec)) {
2307                Formattable m;
2308
2309                mfmt->parseObject(str, m, ec);
2310                if (assertSuccess("parseCurrency", ec)) {
2311                    assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
2312                                 n, m);
2313                } else {
2314                    errln("FAIL: source " + str);
2315                }
2316            }
2317            break;
2318        case 6:
2319            // perr: <pattern or '-'> <invalid string>
2320            errln("FAIL: Under construction");
2321            goto done;
2322        case 7: {
2323            // pat: <pattern> <exp. toPattern, or '-' or 'err'>
2324            UnicodeString testpat;
2325            UnicodeString exppat;
2326            if (!tokens.next(testpat, ec)) goto error;
2327            if (!tokens.next(exppat, ec)) goto error;
2328            UBool err = exppat == "err";
2329            UBool existingPat = FALSE;
2330            if (testpat == "-") {
2331                if (err) {
2332                    errln("FAIL: " + where + "Invalid command \"pat: - err\"");
2333                    continue;
2334                }
2335                existingPat = TRUE;
2336                testpat = pat;
2337            }
2338            if (exppat == "-") exppat = testpat;
2339            DecimalFormat* f = 0;
2340            UErrorCode ec2 = U_ZERO_ERROR;
2341            if (existingPat) {
2342                f = fmt;
2343            } else {
2344                f = new DecimalFormat(testpat, ec2);
2345            }
2346            if (U_SUCCESS(ec2)) {
2347                if (err) {
2348                    errln("FAIL: " + where + "Invalid pattern \"" + testpat +
2349                          "\" was accepted");
2350                } else {
2351                    UnicodeString pat2;
2352                    assertEquals(where + "\"" + testpat + "\".toPattern()",
2353                                 exppat, f->toPattern(pat2));
2354                }
2355            } else {
2356                if (err) {
2357                    logln("Ok: " + where + "Invalid pattern \"" + testpat +
2358                          "\" failed: " + u_errorName(ec2));
2359                } else {
2360                    errln("FAIL: " + where + "Valid pattern \"" + testpat +
2361                          "\" failed: " + u_errorName(ec2));
2362                }
2363            }
2364            if (!existingPat) delete f;
2365            } break;
2366        case -1:
2367            errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
2368            goto done;
2369        }
2370    }
2371    goto done;
2372
2373 error:
2374    if (U_SUCCESS(ec)) {
2375        errln("FAIL: Unexpected EOF");
2376    } else {
2377        errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
2378    }
2379
2380 done:
2381    delete mfmt;
2382    delete fmt;
2383    delete ref;
2384}
2385
2386
2387//----------------------------------------------------------------------
2388// Support methods
2389//----------------------------------------------------------------------
2390
2391UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
2392    if (a.getType() == b.getType()) {
2393        return a == b;
2394    }
2395
2396    if (a.getType() == Formattable::kLong) {
2397        if (b.getType() == Formattable::kInt64) {
2398            return a.getLong() == b.getLong();
2399        } else if (b.getType() == Formattable::kDouble) {
2400            return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
2401        }
2402    } else if (a.getType() == Formattable::kDouble) {
2403        if (b.getType() == Formattable::kLong) {
2404            return a.getDouble() == (double) b.getLong();
2405        } else if (b.getType() == Formattable::kInt64) {
2406            return a.getDouble() == (double)b.getInt64();
2407        }
2408    } else if (a.getType() == Formattable::kInt64) {
2409        if (b.getType() == Formattable::kLong) {
2410                return a.getInt64() == (int64_t)b.getLong();
2411        } else if (b.getType() == Formattable::kDouble) {
2412            return a.getInt64() == (int64_t)b.getDouble();
2413        }
2414    }
2415    return FALSE;
2416}
2417
2418void NumberFormatTest::expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2419    // Don't round-trip format test, since we explicitly do it
2420    expect_rbnf(fmt, n, str, FALSE);
2421    expect_rbnf(fmt, str, n);
2422}
2423
2424void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2425    // Don't round-trip format test, since we explicitly do it
2426    expect(fmt, n, str, FALSE);
2427    expect(fmt, str, n);
2428}
2429
2430void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
2431                               const UnicodeString& exp,
2432                               UErrorCode status) {
2433    if (fmt == NULL || U_FAILURE(status)) {
2434        dataerrln("FAIL: NumberFormat constructor");
2435    } else {
2436        expect2(*fmt, n, exp);
2437    }
2438    delete fmt;
2439}
2440
2441void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2442    UErrorCode status = U_ZERO_ERROR;
2443    Formattable num;
2444    fmt.parse(str, num, status);
2445    if (U_FAILURE(status)) {
2446        dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status));
2447        return;
2448    }
2449    UnicodeString pat;
2450    ((DecimalFormat*) &fmt)->toPattern(pat);
2451    if (equalValue(num, n)) {
2452        logln(UnicodeString("Ok   \"") + str + "\" x " +
2453              pat + " = " +
2454              toString(num));
2455    } else {
2456        dataerrln(UnicodeString("FAIL \"") + str + "\" x " +
2457              pat + " = " +
2458              toString(num) + ", expected " + toString(n));
2459    }
2460}
2461
2462void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2463    UErrorCode status = U_ZERO_ERROR;
2464    Formattable num;
2465    fmt.parse(str, num, status);
2466    if (U_FAILURE(status)) {
2467        errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
2468        return;
2469    }
2470    if (equalValue(num, n)) {
2471        logln(UnicodeString("Ok   \"") + str + " = " +
2472              toString(num));
2473    } else {
2474        errln(UnicodeString("FAIL \"") + str + " = " +
2475              toString(num) + ", expected " + toString(n));
2476    }
2477}
2478
2479void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n,
2480                              const UnicodeString& exp, UBool rt) {
2481    UnicodeString saw;
2482    FieldPosition pos;
2483    UErrorCode status = U_ZERO_ERROR;
2484    fmt.format(n, saw, pos, status);
2485    CHECK(status, "NumberFormat::format");
2486    if (saw == exp) {
2487        logln(UnicodeString("Ok   ") + toString(n) +
2488              " = \"" +
2489              escape(saw) + "\"");
2490        // We should be able to round-trip the formatted string =>
2491        // number => string (but not the other way around: number
2492        // => string => number2, might have number2 != number):
2493        if (rt) {
2494            Formattable n2;
2495            fmt.parse(exp, n2, status);
2496            if (U_FAILURE(status)) {
2497                errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
2498                return;
2499            }
2500            UnicodeString saw2;
2501            fmt.format(n2, saw2, pos, status);
2502            CHECK(status, "NumberFormat::format");
2503            if (saw2 != exp) {
2504                errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2505                      " => \"" + saw2 + "\"");
2506            }
2507        }
2508    } else {
2509        errln(UnicodeString("FAIL ") + toString(n) +
2510              " = \"" +
2511              escape(saw) + "\", expected \"" + exp + "\"");
2512    }
2513}
2514
2515void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
2516                              const UnicodeString& exp, UBool rt) {
2517    UnicodeString saw;
2518    FieldPosition pos;
2519    UErrorCode status = U_ZERO_ERROR;
2520    fmt.format(n, saw, pos, status);
2521    CHECK(status, "NumberFormat::format");
2522    UnicodeString pat;
2523    ((DecimalFormat*) &fmt)->toPattern(pat);
2524    if (saw == exp) {
2525        logln(UnicodeString("Ok   ") + toString(n) + " x " +
2526              escape(pat) + " = \"" +
2527              escape(saw) + "\"");
2528        // We should be able to round-trip the formatted string =>
2529        // number => string (but not the other way around: number
2530        // => string => number2, might have number2 != number):
2531        if (rt) {
2532            Formattable n2;
2533            fmt.parse(exp, n2, status);
2534            if (U_FAILURE(status)) {
2535                errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status));
2536                return;
2537            }
2538            UnicodeString saw2;
2539            fmt.format(n2, saw2, pos, status);
2540            CHECK(status, "NumberFormat::format");
2541            if (saw2 != exp) {
2542                errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2543                      " => \"" + saw2 + "\"");
2544            }
2545        }
2546    } else {
2547        dataerrln(UnicodeString("FAIL ") + toString(n) + " x " +
2548              escape(pat) + " = \"" +
2549              escape(saw) + "\", expected \"" + exp + "\"");
2550    }
2551}
2552
2553void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
2554                              const UnicodeString& exp, UBool rt,
2555                              UErrorCode status) {
2556    if (fmt == NULL || U_FAILURE(status)) {
2557        dataerrln("FAIL: NumberFormat constructor");
2558    } else {
2559        expect(*fmt, n, exp, rt);
2560    }
2561    delete fmt;
2562}
2563
2564void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale,
2565                                      double value, const UnicodeString& string) {
2566    UErrorCode ec = U_ZERO_ERROR;
2567    DecimalFormat& fmt = * (DecimalFormat*) &nf;
2568    const UChar DEFAULT_CURR[] = {45/*-*/,0};
2569    UChar curr[4];
2570    u_strcpy(curr, DEFAULT_CURR);
2571    if (*locale.getLanguage() != 0) {
2572        ucurr_forLocale(locale.getName(), curr, 4, &ec);
2573        assertSuccess("ucurr_forLocale", ec);
2574        fmt.setCurrency(curr, ec);
2575        assertSuccess("DecimalFormat::setCurrency", ec);
2576        fmt.setCurrency(curr); //Deprecated variant, for coverage only
2577    }
2578    UnicodeString s;
2579    fmt.format(value, s);
2580    s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
2581
2582    // Default display of the number yields "1234.5599999999999"
2583    // instead of "1234.56".  Use a formatter to fix this.
2584    NumberFormat* f =
2585        NumberFormat::createInstance(Locale::getUS(), ec);
2586    UnicodeString v;
2587    if (U_FAILURE(ec)) {
2588        // Oops; bad formatter.  Use default op+= display.
2589        v = (UnicodeString)"" + value;
2590    } else {
2591        f->setMaximumFractionDigits(4);
2592        f->setGroupingUsed(FALSE);
2593        f->format(value, v);
2594    }
2595    delete f;
2596
2597    if (s == string) {
2598        logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
2599    } else {
2600        errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
2601              ", expected " + prettify(string));
2602    }
2603}
2604
2605void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
2606    UnicodeString pat;
2607    fmt.toPattern(pat);
2608    if (pat == exp) {
2609        logln(UnicodeString("Ok   \"") + pat + "\"");
2610    } else {
2611        errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
2612    }
2613}
2614
2615void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2616                                 int32_t pos) {
2617    expectPad(fmt, pat, pos, 0, (UnicodeString)"");
2618}
2619void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2620                                 int32_t pos, int32_t width, UChar pad) {
2621    expectPad(fmt, pat, pos, width, UnicodeString(pad));
2622}
2623void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2624                                 int32_t pos, int32_t width, const UnicodeString& pad) {
2625    int32_t apos = 0, awidth = 0;
2626    UnicodeString apadStr;
2627    UErrorCode status = U_ZERO_ERROR;
2628    fmt.applyPattern(pat, status);
2629    if (U_SUCCESS(status)) {
2630        apos = fmt.getPadPosition();
2631        awidth = fmt.getFormatWidth();
2632        apadStr=fmt.getPadCharacterString();
2633    } else {
2634        apos = -1;
2635        awidth = width;
2636        apadStr = pad;
2637    }
2638    if (apos == pos && awidth == width && apadStr == pad) {
2639        UnicodeString infoStr;
2640        if (pos == ILLEGAL) {
2641            infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
2642        }
2643        logln(UnicodeString("Ok   \"") + pat + "\" pos=" + apos + infoStr);
2644    } else {
2645        errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
2646              " width=" + awidth + " pad=" + apadStr +
2647              ", expected " + pos + " " + width + " " + pad);
2648    }
2649}
2650
2651// This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale  - FIXME
2652void NumberFormatTest::TestCompatibleCurrencies() {
2653/*
2654    static const UChar JPY[] = {0x4A, 0x50, 0x59, 0};
2655    static const UChar CNY[] = {0x43, 0x4E, 0x59, 0};
2656    UErrorCode status = U_ZERO_ERROR;
2657    LocalPointer<NumberFormat> fmt(
2658        NumberFormat::createCurrencyInstance(Locale::getUS(), status));
2659    if (U_FAILURE(status)) {
2660        errln("Could not create number format instance.");
2661        return;
2662    }
2663    logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
2664    expectParseCurrency(*fmt, JPY, 1235,  "\\u00A51,235");
2665    logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__);
2666    expectParseCurrency(*fmt, JPY, 1235,  "\\uFFE51,235");
2667    logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
2668    expectParseCurrency(*fmt, CNY, 1235,  "CN\\u00A51,235");
2669
2670    LocalPointer<NumberFormat> fmtTW(
2671        NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
2672
2673    logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__);
2674    expectParseCurrency(*fmtTW, CNY, 1235,  "\\u00A51,235");
2675    logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__);
2676    expectParseCurrency(*fmtTW, CNY, 1235,  "\\uFFE51,235");
2677
2678    LocalPointer<NumberFormat> fmtJP(
2679        NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
2680
2681    logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__);
2682    expectParseCurrency(*fmtJP, JPY, 1235,  "\\u00A51,235");
2683    logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
2684    expectParseCurrency(*fmtJP, JPY, 1235,  "\\uFFE51,235");
2685
2686    // more..
2687*/
2688}
2689
2690void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text) {
2691    ParsePosition ppos;
2692    UnicodeString utext = ctou(text);
2693    LocalPointer<CurrencyAmount> currencyAmount(fmt.parseCurrency(utext, ppos));
2694    if (!ppos.getIndex()) {
2695        errln(UnicodeString("Parse of ") + utext + " should have succeeded.");
2696        return;
2697    }
2698    UErrorCode status = U_ZERO_ERROR;
2699
2700    char theInfo[100];
2701    sprintf(theInfo, "For locale %s, string \"%s\", currency ",
2702            fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(),
2703            text);
2704    u_austrcpy(theInfo+uprv_strlen(theInfo), currency);
2705
2706    char theOperation[100];
2707
2708    uprv_strcpy(theOperation, theInfo);
2709    uprv_strcat(theOperation, ", check amount:");
2710    assertTrue(theOperation, amount ==  currencyAmount->getNumber().getDouble(status));
2711
2712    uprv_strcpy(theOperation, theInfo);
2713    uprv_strcat(theOperation, ", check currency:");
2714    assertEquals(theOperation, currency, currencyAmount->getISOCurrency());
2715}
2716
2717
2718void NumberFormatTest::TestJB3832(){
2719    const char* localeID = "pt_PT@currency=PTE";
2720    Locale loc(localeID);
2721    UErrorCode status = U_ZERO_ERROR;
2722    UnicodeString expected(CharsToUnicodeString("1,150$50\\u00A0Esc."));
2723    UnicodeString s;
2724    NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
2725    if(U_FAILURE(status)){
2726        dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status));
2727        return;
2728    }
2729    currencyFmt->format(1150.50, s);
2730    if(s!=expected){
2731        errln(UnicodeString("FAIL: Expected: ")+expected
2732                + UnicodeString(" Got: ") + s
2733                + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
2734    }
2735    if (U_FAILURE(status)){
2736        errln("FAIL: Status %s", u_errorName(status));
2737    }
2738    delete currencyFmt;
2739}
2740
2741void NumberFormatTest::TestHost()
2742{
2743#if U_PLATFORM_USES_ONLY_WIN32_API
2744    Win32NumberTest::testLocales(this);
2745#endif
2746    Locale loc("en_US@compat=host");
2747    for (UNumberFormatStyle k = UNUM_DECIMAL;
2748         k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) {
2749        UErrorCode status = U_ZERO_ERROR;
2750        LocalPointer<NumberFormat> full(NumberFormat::createInstance(loc, k, status));
2751        if (!NumberFormat::isStyleSupported(k)) {
2752            if (status != U_UNSUPPORTED_ERROR) {
2753                errln("FAIL: expected style %d to be unsupported - %s",
2754                      k, u_errorName(status));
2755            }
2756            continue;
2757        }
2758        if (full.isNull() || U_FAILURE(status)) {
2759            dataerrln("FAIL: Can't create number instance of style %d for host - %s",
2760                      k, u_errorName(status));
2761            return;
2762        }
2763        UnicodeString result1;
2764        Formattable number(10.00);
2765        full->format(number, result1, status);
2766        if (U_FAILURE(status)) {
2767            errln("FAIL: Can't format for host");
2768            return;
2769        }
2770        Formattable formattable;
2771        full->parse(result1, formattable, status);
2772        if (U_FAILURE(status)) {
2773            errln("FAIL: Can't parse for host");
2774            return;
2775        }
2776    }
2777}
2778
2779void NumberFormatTest::TestHostClone()
2780{
2781    /*
2782    Verify that a cloned formatter gives the same results
2783    and is useable after the original has been deleted.
2784    */
2785    // This is mainly important on Windows.
2786    UErrorCode status = U_ZERO_ERROR;
2787    Locale loc("en_US@compat=host");
2788    UDate now = Calendar::getNow();
2789    NumberFormat *full = NumberFormat::createInstance(loc, status);
2790    if (full == NULL || U_FAILURE(status)) {
2791        dataerrln("FAIL: Can't create Relative date instance - %s", u_errorName(status));
2792        return;
2793    }
2794    UnicodeString result1;
2795    full->format(now, result1, status);
2796    Format *fullClone = full->clone();
2797    delete full;
2798    full = NULL;
2799
2800    UnicodeString result2;
2801    fullClone->format(now, result2, status);
2802    if (U_FAILURE(status)) {
2803        errln("FAIL: format failure.");
2804    }
2805    if (result1 != result2) {
2806        errln("FAIL: Clone returned different result from non-clone.");
2807    }
2808    delete fullClone;
2809}
2810
2811void NumberFormatTest::TestCurrencyFormat()
2812{
2813    // This test is here to increase code coverage.
2814    UErrorCode status = U_ZERO_ERROR;
2815    MeasureFormat *cloneObj;
2816    UnicodeString str;
2817    Formattable toFormat, result;
2818    static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
2819
2820    Locale  saveDefaultLocale = Locale::getDefault();
2821    Locale::setDefault( Locale::getUK(), status );
2822    if (U_FAILURE(status)) {
2823        errln("couldn't set default Locale!");
2824        return;
2825    }
2826
2827    MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
2828    Locale::setDefault( saveDefaultLocale, status );
2829    if (U_FAILURE(status)){
2830        dataerrln("FAIL: Status %s", u_errorName(status));
2831        return;
2832    }
2833    cloneObj = (MeasureFormat *)measureObj->clone();
2834    if (cloneObj == NULL) {
2835        errln("Clone doesn't work");
2836        return;
2837    }
2838    toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status));
2839    measureObj->format(toFormat, str, status);
2840    measureObj->parseObject(str, result, status);
2841    if (U_FAILURE(status)){
2842        errln("FAIL: Status %s", u_errorName(status));
2843    }
2844    if (result != toFormat) {
2845        errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2846    }
2847    status = U_ZERO_ERROR;
2848    str.truncate(0);
2849    cloneObj->format(toFormat, str, status);
2850    cloneObj->parseObject(str, result, status);
2851    if (U_FAILURE(status)){
2852        errln("FAIL: Status %s", u_errorName(status));
2853    }
2854    if (result != toFormat) {
2855        errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2856    }
2857    if (*measureObj != *cloneObj) {
2858        errln("Cloned object is not equal to the original object");
2859    }
2860    delete measureObj;
2861    delete cloneObj;
2862
2863    status = U_USELESS_COLLATOR_ERROR;
2864    if (MeasureFormat::createCurrencyFormat(status) != NULL) {
2865        errln("createCurrencyFormat should have returned NULL.");
2866    }
2867}
2868
2869/* Port of ICU4J rounding test. */
2870void NumberFormatTest::TestRounding() {
2871    UErrorCode status = U_ZERO_ERROR;
2872    DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
2873
2874    if (U_FAILURE(status)) {
2875        dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
2876        return;
2877    }
2878
2879    int roundingIncrements[]={1, 2, 5, 20, 50, 100};
2880    int testValues[]={0, 300};
2881
2882    for (int j=0; j<2; j++) {
2883        for (int mode=DecimalFormat::kRoundUp;mode<DecimalFormat::kRoundHalfEven;mode++) {
2884            df->setRoundingMode((DecimalFormat::ERoundingMode)mode);
2885            for (int increment=0; increment<6; increment++) {
2886                double base=testValues[j];
2887                double rInc=roundingIncrements[increment];
2888                checkRounding(df, base, 20, rInc);
2889                rInc=1.000000000/rInc;
2890                checkRounding(df, base, 20, rInc);
2891            }
2892        }
2893    }
2894    delete df;
2895}
2896
2897void NumberFormatTest::TestRoundingPattern() {
2898    UErrorCode status = U_ZERO_ERROR;
2899    struct {
2900        UnicodeString  pattern;
2901        double        testCase;
2902        UnicodeString expected;
2903    } tests[] = {
2904            { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" },
2905            { (UnicodeString)"#50",    1230,  (UnicodeString)"1250" }
2906    };
2907    int32_t numOfTests = (sizeof(tests)/sizeof(tests[0]));
2908    UnicodeString result;
2909
2910    DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
2911    if (U_FAILURE(status)) {
2912        dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
2913        return;
2914    }
2915
2916    for (int32_t i = 0; i < numOfTests; i++) {
2917        result.remove();
2918
2919        df->applyPattern(tests[i].pattern, status);
2920        if (U_FAILURE(status)) {
2921            errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status));
2922        }
2923
2924        df->format(tests[i].testCase, result);
2925
2926        if (result != tests[i].expected) {
2927            errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
2928        }
2929    }
2930
2931    delete df;
2932}
2933
2934void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) {
2935    df->setRoundingIncrement(increment);
2936    double lastParsed=INT32_MIN; //Intger.MIN_VALUE
2937    for (int i=-iterations; i<=iterations;i++) {
2938        double iValue=base+(increment*(i*0.1));
2939        double smallIncrement=0.00000001;
2940        if (iValue!=0) {
2941            smallIncrement*=iValue;
2942        }
2943        //we not only test the value, but some values in a small range around it
2944        lastParsed=checkRound(df, iValue-smallIncrement, lastParsed);
2945        lastParsed=checkRound(df, iValue, lastParsed);
2946        lastParsed=checkRound(df, iValue+smallIncrement, lastParsed);
2947    }
2948}
2949
2950double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) {
2951    UErrorCode status=U_ZERO_ERROR;
2952    UnicodeString formattedDecimal;
2953    double parsed;
2954    Formattable result;
2955    df->format(iValue, formattedDecimal, status);
2956
2957    if (U_FAILURE(status)) {
2958        errln("Error formatting number.");
2959    }
2960
2961    df->parse(formattedDecimal, result, status);
2962
2963    if (U_FAILURE(status)) {
2964        errln("Error parsing number.");
2965    }
2966
2967    parsed=result.getDouble();
2968
2969    if (lastParsed>parsed) {
2970        errln("Rounding wrong direction! %d > %d", lastParsed, parsed);
2971    }
2972
2973    return lastParsed;
2974}
2975
2976void NumberFormatTest::TestNonpositiveMultiplier() {
2977    UErrorCode status = U_ZERO_ERROR;
2978    DecimalFormatSymbols US(Locale::getUS(), status);
2979    CHECK(status, "DecimalFormatSymbols constructor");
2980    DecimalFormat df(UnicodeString("0"), US, status);
2981    CHECK(status, "DecimalFormat(0)");
2982
2983    // test zero multiplier
2984
2985    int32_t mult = df.getMultiplier();
2986    df.setMultiplier(0);
2987    if (df.getMultiplier() != mult) {
2988        errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
2989    }
2990
2991    // test negative multiplier
2992
2993    df.setMultiplier(-1);
2994    if (df.getMultiplier() != -1) {
2995        errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
2996        return;
2997    }
2998
2999    expect(df, "1122.123", -1122.123);
3000    expect(df, "-1122.123", 1122.123);
3001    expect(df, "1.2", -1.2);
3002    expect(df, "-1.2", 1.2);
3003
3004    // Note:  the tests with the final parameter of FALSE will not round trip.
3005    //        The initial numeric value will format correctly, after the multiplier.
3006    //        Parsing the formatted text will be out-of-range for an int64, however.
3007    //        The expect() function could be modified to detect this and fall back
3008    //        to looking at the decimal parsed value, but it doesn't.
3009    expect(df, U_INT64_MIN,    "9223372036854775808", FALSE);
3010    expect(df, U_INT64_MIN+1,  "9223372036854775807");
3011    expect(df, (int64_t)-123,                  "123");
3012    expect(df, (int64_t)123,                  "-123");
3013    expect(df, U_INT64_MAX-1, "-9223372036854775806");
3014    expect(df, U_INT64_MAX,   "-9223372036854775807");
3015
3016    df.setMultiplier(-2);
3017    expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806");
3018    expect(df, -(U_INT64_MIN/2),   "-9223372036854775808");
3019    expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE);
3020
3021    df.setMultiplier(-7);
3022    expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE);
3023    expect(df, -(U_INT64_MAX/7),   "9223372036854775807");
3024    expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800");
3025
3026    // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
3027    // (right now the big numbers get turned into doubles and lose tons of accuracy)
3028    //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
3029    //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
3030    //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
3031    //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
3032
3033    // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
3034    //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3035    //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3036    //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3037    //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3038}
3039
3040typedef struct {
3041    const char * stringToParse;
3042    int          parsedPos;
3043    int          errorIndex;
3044    UBool        lenient;
3045} TestSpaceParsingItem;
3046
3047void
3048NumberFormatTest::TestSpaceParsing() {
3049    // the data are:
3050    // the string to be parsed, parsed position, parsed error index
3051    const TestSpaceParsingItem DATA[] = {
3052        // TOTO: Update the following TODOs, some may be handled now
3053        {"$124",           4, -1, FALSE},
3054        {"$124 $124",      4, -1, FALSE},
3055        {"$124 ",          4, -1, FALSE},
3056        //{"$ 124 ",       5, -1, FALSE}, // TODO: need to handle space correctly
3057        //{"$\\u00A0124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
3058        {"$ 124 ",         0,  1, FALSE}, // errorIndex used to be 0, now 1 (better)
3059        {"$\\u00A0124 ",   0,  1, FALSE}, // errorIndex used to be 0, now 1 (better)
3060        {" $ 124 ",        0,  0, FALSE}, // TODO: need to handle space correctly
3061        {"124$",           0,  3, FALSE}, // TODO: need to handle space correctly
3062        // {"124 $",       5, -1, FALSE}, // TODO: OK or not, need currency spacing rule
3063        {"124 $",          0,  3, FALSE},
3064        {"$124",           4, -1, TRUE},
3065        {"$124 $124",      4, -1, TRUE},
3066        {"$124 ",          4, -1, TRUE},
3067        {"$ 124 ",         5, -1, TRUE},
3068        {"$\\u00A0124 ",   5, -1, TRUE},
3069        {" $ 124 ",        6, -1, TRUE},
3070        //{"124$",         4, -1, TRUE}, // TODO: need to handle trailing currency correctly
3071        {"124$",           3, -1, TRUE},
3072        //{"124 $",        5, -1, TRUE}, // TODO: OK or not, need currency spacing rule
3073        {"124 $",          4, -1, TRUE},
3074    };
3075    UErrorCode status = U_ZERO_ERROR;
3076    Locale locale("en_US");
3077    NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status);
3078
3079    if (U_FAILURE(status)) {
3080        delete foo;
3081        return;
3082    }
3083    for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) {
3084        ParsePosition parsePosition(0);
3085        UnicodeString stringToBeParsed = ctou(DATA[i].stringToParse);
3086        int parsedPosition = DATA[i].parsedPos;
3087        int errorIndex = DATA[i].errorIndex;
3088        foo->setLenient(DATA[i].lenient);
3089        Formattable result;
3090        foo->parse(stringToBeParsed, result, parsePosition);
3091        if (parsePosition.getIndex() != parsedPosition ||
3092            parsePosition.getErrorIndex() != errorIndex) {
3093            errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
3094        }
3095        if (parsePosition.getErrorIndex() == -1 &&
3096            result.getType() == Formattable::kLong &&
3097            result.getLong() != 124) {
3098            errln("FAILED parse " + stringToBeParsed + "; wrong number, expect: 124, got " + result.getLong());
3099        }
3100    }
3101    delete foo;
3102}
3103
3104/**
3105 * Test using various numbering systems and numbering system keyword.
3106 */
3107typedef struct {
3108    const char *localeName;
3109    double      value;
3110    UBool        isRBNF;
3111    const char *expectedResult;
3112} TestNumberingSystemItem;
3113
3114void NumberFormatTest::TestNumberingSystems() {
3115
3116    const TestNumberingSystemItem DATA[] = {
3117        { "en_US@numbers=thai", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
3118        { "en_US@numbers=hebr", 5678.0, TRUE, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
3119        { "en_US@numbers=arabext", 1234.567, FALSE, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
3120        { "ar_EG", 1234.567, FALSE, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
3121        { "th_TH@numbers=traditional", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
3122        { "ar_MA", 1234.567, FALSE, "1.234,567" },
3123        { "en_US@numbers=hanidec", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3124        { "ta_IN@numbers=native", 1234.567, FALSE, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
3125        { "ta_IN@numbers=traditional", 1235.0, TRUE, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
3126        { "ta_IN@numbers=finance", 1234.567, FALSE, "1,234.567" }, // fall back to default per TR35
3127        { "zh_TW@numbers=native", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3128        { "zh_TW@numbers=traditional", 1234.567, TRUE, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
3129        { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
3130        { NULL, 0, FALSE, NULL }
3131    };
3132
3133    UErrorCode ec;
3134
3135    const TestNumberingSystemItem *item;
3136    for (item = DATA; item->localeName != NULL; item++) {
3137        ec = U_ZERO_ERROR;
3138        Locale loc = Locale::createFromName(item->localeName);
3139
3140        NumberFormat *origFmt = NumberFormat::createInstance(loc,ec);
3141        if (U_FAILURE(ec)) {
3142            dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec));
3143            continue;
3144        }
3145        // Clone to test ticket #10682
3146        NumberFormat *fmt = (NumberFormat *) origFmt->clone();
3147        delete origFmt;
3148
3149
3150        if (item->isRBNF) {
3151            expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3152        } else {
3153            expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3154        }
3155        delete fmt;
3156    }
3157
3158
3159    // Test bogus keyword value
3160    ec = U_ZERO_ERROR;
3161    Locale loc4 = Locale::createFromName("en_US@numbers=foobar");
3162    NumberFormat* fmt4= NumberFormat::createInstance(loc4, ec);
3163    if ( ec != U_UNSUPPORTED_ERROR ) {
3164        errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
3165        delete fmt4;
3166    }
3167
3168    ec = U_ZERO_ERROR;
3169    NumberingSystem *ns = NumberingSystem::createInstance(ec);
3170    if (U_FAILURE(ec)) {
3171        dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec));
3172    }
3173
3174    if ( ns != NULL ) {
3175        ns->getDynamicClassID();
3176        ns->getStaticClassID();
3177    } else {
3178        errln("FAIL: getInstance() returned NULL.");
3179    }
3180
3181    NumberingSystem *ns1 = new NumberingSystem(*ns);
3182    if (ns1 == NULL) {
3183        errln("FAIL: NumberSystem copy constructor returned NULL.");
3184    }
3185
3186    delete ns1;
3187    delete ns;
3188
3189}
3190
3191
3192void
3193NumberFormatTest::TestMultiCurrencySign() {
3194    const char* DATA[][6] = {
3195        // the fields in the following test are:
3196        // locale,
3197        // currency pattern (with negative pattern),
3198        // currency number to be formatted,
3199        // currency format using currency symbol name, such as "$" for USD,
3200        // currency format using currency ISO name, such as "USD",
3201        // currency format using plural name, such as "US dollars".
3202        // for US locale
3203        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
3204        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
3205        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollars1.00"},
3206        // for CHINA locale
3207        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\uFFE51,234.56", "CNY1,234.56", "\\u4EBA\\u6C11\\u5E011,234.56"},
3208        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\uFFE51,234.56)", "(CNY1,234.56)", "(\\u4EBA\\u6C11\\u5E011,234.56)"},
3209        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\uFFE51.00", "CNY1.00", "\\u4EBA\\u6C11\\u5E011.00"}
3210    };
3211
3212    const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0};
3213    UnicodeString doubleCurrencyStr(doubleCurrencySign);
3214    const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
3215    UnicodeString tripleCurrencyStr(tripleCurrencySign);
3216
3217    for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) {
3218        const char* locale = DATA[i][0];
3219        UnicodeString pat = ctou(DATA[i][1]);
3220        double numberToBeFormat = atof(DATA[i][2]);
3221        UErrorCode status = U_ZERO_ERROR;
3222        DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale(locale), status);
3223        if (U_FAILURE(status)) {
3224            delete sym;
3225            continue;
3226        }
3227        for (int j=1; j<=3; ++j) {
3228            // j represents the number of currency sign in the pattern.
3229            if (j == 2) {
3230                pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr);
3231            } else if (j == 3) {
3232                pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr);
3233            }
3234
3235            DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status);
3236            if (U_FAILURE(status)) {
3237                errln("FAILED init DecimalFormat ");
3238                delete fmt;
3239                continue;
3240            }
3241            UnicodeString s;
3242            ((NumberFormat*) fmt)->format(numberToBeFormat, s);
3243            // DATA[i][3] is the currency format result using a
3244            // single currency sign.
3245            // DATA[i][4] is the currency format result using
3246            // double currency sign.
3247            // DATA[i][5] is the currency format result using
3248            // triple currency sign.
3249            // DATA[i][j+2] is the currency format result using
3250            // 'j' number of currency sign.
3251            UnicodeString currencyFormatResult = ctou(DATA[i][2+j]);
3252            if (s.compare(currencyFormatResult)) {
3253                errln("FAIL format: Expected " + currencyFormatResult + "; Got " + s);
3254            }
3255            // mix style parsing
3256            for (int k=3; k<=5; ++k) {
3257              // DATA[i][3] is the currency format result using a
3258              // single currency sign.
3259              // DATA[i][4] is the currency format result using
3260              // double currency sign.
3261              // DATA[i][5] is the currency format result using
3262              // triple currency sign.
3263              UnicodeString oneCurrencyFormat = ctou(DATA[i][k]);
3264              UErrorCode status = U_ZERO_ERROR;
3265              Formattable parseRes;
3266              fmt->parse(oneCurrencyFormat, parseRes, status);
3267              if (U_FAILURE(status) ||
3268                  (parseRes.getType() == Formattable::kDouble &&
3269                   parseRes.getDouble() != numberToBeFormat) ||
3270                  (parseRes.getType() == Formattable::kLong &&
3271                   parseRes.getLong() != numberToBeFormat)) {
3272                  errln("FAILED parse " + oneCurrencyFormat + "; (i, j, k): " +
3273                        i + ", " + j + ", " + k);
3274              }
3275            }
3276            delete fmt;
3277        }
3278        delete sym;
3279    }
3280}
3281
3282
3283void
3284NumberFormatTest::TestCurrencyFormatForMixParsing() {
3285    UErrorCode status = U_ZERO_ERROR;
3286    MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status);
3287    if (U_FAILURE(status)) {
3288        delete curFmt;
3289        return;
3290    }
3291    const char* formats[] = {
3292        "$1,234.56",  // string to be parsed
3293        "USD1,234.56",
3294        "US dollars1,234.56",
3295        "1,234.56 US dollars"
3296    };
3297    const CurrencyAmount* curramt = NULL;
3298    for (uint32_t i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
3299        UnicodeString stringToBeParsed = ctou(formats[i]);
3300        logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed);
3301        Formattable result;
3302        UErrorCode status = U_ZERO_ERROR;
3303        curFmt->parseObject(stringToBeParsed, result, status);
3304        if (U_FAILURE(status)) {
3305          errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status));
3306        } else if (result.getType() != Formattable::kObject ||
3307            (curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL ||
3308            curramt->getNumber().getDouble() != 1234.56 ||
3309            UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD)
3310        ) {
3311            errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
3312            if (curramt->getNumber().getDouble() != 1234.56) {
3313                errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble());
3314            }
3315            if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
3316                errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
3317            }
3318        }
3319    }
3320    delete curFmt;
3321}
3322
3323
3324void
3325NumberFormatTest::TestDecimalFormatCurrencyParse() {
3326    // Locale.US
3327    UErrorCode status = U_ZERO_ERROR;
3328    DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status);
3329    if (U_FAILURE(status)) {
3330        delete sym;
3331        return;
3332    }
3333    UnicodeString pat;
3334    UChar currency = 0x00A4;
3335    // "\xA4#,##0.00;-\xA4#,##0.00"
3336    pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
3337    DecimalFormat* fmt = new DecimalFormat(pat, sym, status);
3338    if (U_FAILURE(status)) {
3339        delete fmt;
3340        errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3341        return;
3342    }
3343    const char* DATA[][2] = {
3344        // the data are:
3345        // string to be parsed, the parsed result (number)
3346        {"$1.00", "1"},
3347        {"USD1.00", "1"},
3348        {"1.00 US dollar", "1"},
3349        {"$1,234.56", "1234.56"},
3350        {"USD1,234.56", "1234.56"},
3351        {"1,234.56 US dollar", "1234.56"},
3352    };
3353    for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) {
3354        UnicodeString stringToBeParsed = ctou(DATA[i][0]);
3355        double parsedResult = atof(DATA[i][1]);
3356        UErrorCode status = U_ZERO_ERROR;
3357        Formattable result;
3358        fmt->parse(stringToBeParsed, result, status);
3359        if (U_FAILURE(status) ||
3360            (result.getType() == Formattable::kDouble &&
3361            result.getDouble() != parsedResult) ||
3362            (result.getType() == Formattable::kLong &&
3363            result.getLong() != parsedResult)) {
3364            errln((UnicodeString)"FAIL parse: Expected " + parsedResult);
3365        }
3366    }
3367    delete fmt;
3368}
3369
3370
3371void
3372NumberFormatTest::TestCurrencyIsoPluralFormat() {
3373    static const char* DATA[][6] = {
3374        // the data are:
3375        // locale,
3376        // currency amount to be formatted,
3377        // currency ISO code to be formatted,
3378        // format result using CURRENCYSTYLE,
3379        // format result using ISOCURRENCYSTYLE,
3380        // format result using PLURALCURRENCYSTYLE,
3381
3382        {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollars"},
3383        {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},
3384        {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD1,234.56", "-1,234.56 US dollars"},
3385        {"zh_CN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00\\u7F8E\\u5143"},
3386        {"zh_CN", "1234.56", "USD", "US$\\u00A01,234.56", "USD\\u00A01,234.56", "1,234.56\\u7F8E\\u5143"},
3387        // wrong ISO code {"zh_CN", "1", "CHY", "CHY1.00", "CHY1.00", "1.00 CHY"},
3388        // wrong ISO code {"zh_CN", "1234.56", "CHY", "CHY1,234.56", "CHY1,234.56", "1,234.56 CHY"},
3389        {"zh_CN", "1", "CNY", "\\uFFE5\\u00A01.00", "CNY\\u00A01.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3390        {"zh_CN", "1234.56", "CNY", "\\uFFE5\\u00A01,234.56", "CNY\\u00A01,234.56", "1,234.56\\u4EBA\\u6C11\\u5E01"},
3391        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u0440\\u0443\\u0431.", "1,00\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3392        {"ru_RU", "2", "RUB", "2,00\\u00A0\\u0440\\u0443\\u0431.", "2,00\\u00A0RUB", "2,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3393        {"ru_RU", "5", "RUB", "5,00\\u00A0\\u0440\\u0443\\u0431.", "5,00\\u00A0RUB", "5,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"},
3394        // test locale without currency information
3395        {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3396        // test choice format
3397        {"es_AR", "1", "INR", "INR1,00", "INR1,00", "1,00 rupia india"},
3398    };
3399    static const UNumberFormatStyle currencyStyles[] = {
3400        UNUM_CURRENCY,
3401        UNUM_CURRENCY_ISO,
3402        UNUM_CURRENCY_PLURAL
3403    };
3404
3405    for (int32_t i=0; i<LENGTHOF(DATA); ++i) {
3406      for (int32_t kIndex = 0; kIndex < LENGTHOF(currencyStyles); ++kIndex) {
3407        UNumberFormatStyle k = currencyStyles[kIndex];
3408        const char* localeString = DATA[i][0];
3409        double numberToBeFormat = atof(DATA[i][1]);
3410        const char* currencyISOCode = DATA[i][2];
3411        Locale locale(localeString);
3412        UErrorCode status = U_ZERO_ERROR;
3413        NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3414        if (U_FAILURE(status)) {
3415            delete numFmt;
3416            dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3417            continue;
3418        }
3419        UChar currencyCode[4];
3420        u_charsToUChars(currencyISOCode, currencyCode, 4);
3421        numFmt->setCurrency(currencyCode, status);
3422        if (U_FAILURE(status)) {
3423            delete numFmt;
3424            errln((UnicodeString)"can not set currency:" + currencyISOCode);
3425            continue;
3426        }
3427
3428        UnicodeString strBuf;
3429        numFmt->format(numberToBeFormat, strBuf);
3430        int resultDataIndex = 3 + kIndex;
3431        // DATA[i][resultDataIndex] is the currency format result
3432        // using 'k' currency style.
3433        UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
3434        if (strBuf.compare(formatResult)) {
3435            errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
3436        }
3437        // test parsing, and test parsing for all currency formats.
3438        for (int j = 3; j < 6; ++j) {
3439            // DATA[i][3] is the currency format result using
3440            // CURRENCYSTYLE formatter.
3441            // DATA[i][4] is the currency format result using
3442            // ISOCURRENCYSTYLE formatter.
3443            // DATA[i][5] is the currency format result using
3444            // PLURALCURRENCYSTYLE formatter.
3445            UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
3446            UErrorCode status = U_ZERO_ERROR;
3447            Formattable parseResult;
3448            numFmt->parse(oneCurrencyFormatResult, parseResult, status);
3449            if (U_FAILURE(status) ||
3450                (parseResult.getType() == Formattable::kDouble &&
3451                 parseResult.getDouble() != numberToBeFormat) ||
3452                (parseResult.getType() == Formattable::kLong &&
3453                 parseResult.getLong() != numberToBeFormat)) {
3454                errln((UnicodeString)"FAIL: getCurrencyFormat of locale " +
3455                      localeString + " failed roundtripping the number");
3456                if (parseResult.getType() == Formattable::kDouble) {
3457                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble());
3458                } else {
3459                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
3460                }
3461            }
3462        }
3463        delete numFmt;
3464      }
3465    }
3466}
3467
3468void
3469NumberFormatTest::TestCurrencyParsing() {
3470    static const char* DATA[][6] = {
3471        // the data are:
3472        // locale,
3473        // currency amount to be formatted,
3474        // currency ISO code to be formatted,
3475        // format result using CURRENCYSTYLE,
3476        // format result using ISOCURRENCYSTYLE,
3477        // format result using PLURALCURRENCYSTYLE,
3478        {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
3479        {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
3480        {"es_AR", "1", "USD", "US$1,00", "USD1,00", "1,00 d\\u00f3lar estadounidense"},
3481        {"ar_EG", "1", "USD", "US$\\u00a0\\u0661\\u066b\\u0660\\u0660", "USD\\u00a0\\u0661\\u066b\\u0660\\u0660", "\\u0661\\u066b\\u0660\\u0660 \\u062f\\u0648\\u0644\\u0627\\u0631 \\u0623\\u0645\\u0631\\u064a\\u0643\\u064a"},
3482        {"fa_CA", "1", "USD", "\\u200e$\\u06f1\\u066b\\u06f0\\u06f0", "\\u200eUSD\\u06f1\\u066b\\u06f0\\u06f0", "\\u200e\\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627\\u06f1\\u066b\\u06f0\\u06f0"},
3483        {"he_IL", "1", "USD", "1.00\\u00a0US$", "1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
3484        {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 Ameri\\u010dki dolar"},
3485        {"id_ID", "1", "USD", "US$1,00", "USD1,00", "1,00 Dolar Amerika Serikat"},
3486        {"it_IT", "1", "USD", "1,00\\u00a0US$", "1,00\\u00a0USD", "1,00 Dollaro Statunitense"},
3487        {"ko_KR", "1", "USD", "US$1.00", "USD1.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
3488        {"ja_JP", "1", "USD", "$1.00", "USD1.00", "1.00 \\u7c73\\u30c9\\u30eb"},
3489        {"zh_CN", "1", "CNY", "\\uFFE5\\u00a01.00", "CNY\\u00a01.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3490        {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3491        {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3492        {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00 \\u65e5\\u5713"},
3493        {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY1.00", "1.00 \\u65e5\\u672c\\u5186"},
3494        {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00 \\u65e5\\u672c\\u5186"},
3495        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u0440\\u0443\\u0431.", "1,00\\u00A0RUB", "1,00 \\u0420\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"}
3496    };
3497    static const UNumberFormatStyle currencyStyles[] = {
3498        UNUM_CURRENCY,
3499        UNUM_CURRENCY_ISO,
3500        UNUM_CURRENCY_PLURAL
3501    };
3502    static const char* currencyStyleNames[] = {
3503      "UNUM_CURRENCY",
3504      "UNUM_CURRENCY_ISO",
3505      "UNUM_CURRENCY_PLURAL"
3506    };
3507
3508#ifdef NUMFMTST_CACHE_DEBUG
3509int deadloop = 0;
3510for (;;) {
3511    printf("loop: %d\n", deadloop++);
3512#endif
3513    for (uint32_t i=0; i< sizeof(DATA)/sizeof(DATA[0]); ++i) {  /* i = test case #  - should be i=0*/
3514      for (int32_t kIndex = 2; kIndex < LENGTHOF(currencyStyles); ++kIndex) {
3515        UNumberFormatStyle k = currencyStyles[kIndex]; /* k = style */
3516        const char* localeString = DATA[i][0];
3517        double numberToBeFormat = atof(DATA[i][1]);
3518        const char* currencyISOCode = DATA[i][2];
3519        Locale locale(localeString);
3520        UErrorCode status = U_ZERO_ERROR;
3521        NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3522        logln("#%d NumberFormat(%s, %s) Currency=%s\n",
3523              i, localeString, currencyStyleNames[kIndex],
3524              currencyISOCode);
3525
3526        if (U_FAILURE(status)) {
3527            delete numFmt;
3528            dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3529            continue;
3530        }
3531        UChar currencyCode[4];
3532        u_charsToUChars(currencyISOCode, currencyCode, 4);
3533        numFmt->setCurrency(currencyCode, status);
3534        if (U_FAILURE(status)) {
3535            delete numFmt;
3536            errln((UnicodeString)"can not set currency:" + currencyISOCode);
3537            continue;
3538        }
3539
3540        UnicodeString strBuf;
3541        numFmt->format(numberToBeFormat, strBuf);
3542        /*
3543        int resultDataIndex = 3 + kIndex;
3544        // DATA[i][resultDataIndex] is the currency format result
3545        // using 'k' currency style.
3546        UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
3547        if (strBuf.compare(formatResult)) {
3548            errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
3549        }
3550        */
3551        // test parsing, and test parsing for all currency formats.
3552        for (int j = 3; j < 6; ++j) {
3553            // DATA[i][3] is the currency format result using
3554            // CURRENCYSTYLE formatter.
3555            // DATA[i][4] is the currency format result using
3556            // ISOCURRENCYSTYLE formatter.
3557            // DATA[i][5] is the currency format result using
3558            // PLURALCURRENCYSTYLE formatter.
3559            UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
3560            UErrorCode status = U_ZERO_ERROR;
3561            Formattable parseResult;
3562            logln("parse(%s)", DATA[i][j]);
3563            numFmt->parse(oneCurrencyFormatResult, parseResult, status);
3564            if (U_FAILURE(status) ||
3565                (parseResult.getType() == Formattable::kDouble &&
3566                 parseResult.getDouble() != numberToBeFormat) ||
3567                (parseResult.getType() == Formattable::kLong &&
3568                 parseResult.getLong() != numberToBeFormat)) {
3569                errln((UnicodeString)"FAIL: NumberFormat(" + localeString +", " + currencyStyleNames[kIndex] +
3570                      "), Currency="+currencyISOCode+", parse("+DATA[i][j]+") returned error " + (UnicodeString)u_errorName(status)+".  Testcase: data[" + i + "][" + currencyStyleNames[j-3] +"="+j+"]");
3571                if (parseResult.getType() == Formattable::kDouble) {
3572                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (double): " +parseResult.getDouble());
3573                } else {
3574                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (long): " +parseResult.getLong());
3575                }
3576                errln((UnicodeString)" round-trip would be: " + strBuf);
3577            }
3578        }
3579        delete numFmt;
3580      }
3581    }
3582#ifdef NUMFMTST_CACHE_DEBUG
3583}
3584#endif
3585}
3586
3587
3588void
3589NumberFormatTest::TestParseCurrencyInUCurr() {
3590    const char* DATA[] = {
3591        "1.00 US DOLLAR",  // case in-sensitive
3592        "$1.00",
3593        "USD1.00",
3594        "US dollar1.00",
3595        "US dollars1.00",
3596        "$1.00",
3597        "A$1.00",
3598        "ADP1.00",
3599        "ADP1.00",
3600        "AED1.00",
3601        "AED1.00",
3602        "AFA1.00",
3603        "AFA1.00",
3604        "AFN1.00",
3605        "ALL1.00",
3606        "AMD1.00",
3607        "ANG1.00",
3608        "AOA1.00",
3609        "AOK1.00",
3610        "AOK1.00",
3611        "AON1.00",
3612        "AON1.00",
3613        "AOR1.00",
3614        "AOR1.00",
3615        "ARS1.00",
3616        "ARA1.00",
3617        "ARA1.00",
3618        "ARP1.00",
3619        "ARP1.00",
3620        "ARS1.00",
3621        "ATS1.00",
3622        "ATS1.00",
3623        "AUD1.00",
3624        "AWG1.00",
3625        "AZM1.00",
3626        "AZM1.00",
3627        "AZN1.00",
3628        "Afghan Afghani (1927\\u20132002)1.00",
3629        "Afghan afghani (1927\\u20132002)1.00",
3630        "Afghan Afghani1.00",
3631        "Afghan Afghanis1.00",
3632        "Albanian Lek1.00",
3633        "Albanian lek1.00",
3634        "Albanian lek\\u00eb1.00",
3635        "Algerian Dinar1.00",
3636        "Algerian dinar1.00",
3637        "Algerian dinars1.00",
3638        "Andorran Peseta1.00",
3639        "Andorran peseta1.00",
3640        "Andorran pesetas1.00",
3641        "Angolan Kwanza (1977\\u20131991)1.00",
3642        "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
3643        "Angolan Kwanza1.00",
3644        "Angolan New Kwanza (1990\\u20132000)1.00",
3645        "Angolan kwanza (1977\\u20131991)1.00",
3646        "Angolan readjusted kwanza (1995\\u20131999)1.00",
3647        "Angolan kwanza1.00",
3648        "Angolan kwanzas (1977\\u20131991)1.00",
3649        "Angolan readjusted kwanzas (1995\\u20131999)1.00",
3650        "Angolan kwanzas1.00",
3651        "Angolan new kwanza (1990\\u20132000)1.00",
3652        "Angolan new kwanzas (1990\\u20132000)1.00",
3653        "Argentine Austral1.00",
3654        "Argentine Peso (1983\\u20131985)1.00",
3655        "Argentine Peso1.00",
3656        "Argentine austral1.00",
3657        "Argentine australs1.00",
3658        "Argentine peso (1983\\u20131985)1.00",
3659        "Argentine peso1.00",
3660        "Argentine pesos (1983\\u20131985)1.00",
3661        "Argentine pesos1.00",
3662        "Armenian Dram1.00",
3663        "Armenian dram1.00",
3664        "Armenian drams1.00",
3665        "Aruban Florin1.00",
3666        "Aruban florin1.00",
3667        "Australian Dollar1.00",
3668        "Australian dollar1.00",
3669        "Australian dollars1.00",
3670        "Austrian Schilling1.00",
3671        "Austrian schilling1.00",
3672        "Austrian schillings1.00",
3673        "Azerbaijani Manat (1993\\u20132006)1.00",
3674        "Azerbaijani Manat1.00",
3675        "Azerbaijani manat (1993\\u20132006)1.00",
3676        "Azerbaijani manat1.00",
3677        "Azerbaijani manats (1993\\u20132006)1.00",
3678        "Azerbaijani manats1.00",
3679        "BAD1.00",
3680        "BAD1.00",
3681        "BAM1.00",
3682        "BBD1.00",
3683        "BDT1.00",
3684        "BEC1.00",
3685        "BEC1.00",
3686        "BEF1.00",
3687        "BEL1.00",
3688        "BEL1.00",
3689        "BGL1.00",
3690        "BGN1.00",
3691        "BGN1.00",
3692        "BHD1.00",
3693        "BIF1.00",
3694        "BMD1.00",
3695        "BND1.00",
3696        "BOB1.00",
3697        "BOP1.00",
3698        "BOP1.00",
3699        "BOV1.00",
3700        "BOV1.00",
3701        "BRB1.00",
3702        "BRB1.00",
3703        "BRC1.00",
3704        "BRC1.00",
3705        "BRE1.00",
3706        "BRE1.00",
3707        "BRL1.00",
3708        "BRN1.00",
3709        "BRN1.00",
3710        "BRR1.00",
3711        "BRR1.00",
3712        "BSD1.00",
3713        "BSD1.00",
3714        "BTN1.00",
3715        "BUK1.00",
3716        "BUK1.00",
3717        "BWP1.00",
3718        "BYB1.00",
3719        "BYB1.00",
3720        "BYR1.00",
3721        "BZD1.00",
3722        "Bahamian Dollar1.00",
3723        "Bahamian dollar1.00",
3724        "Bahamian dollars1.00",
3725        "Bahraini Dinar1.00",
3726        "Bahraini dinar1.00",
3727        "Bahraini dinars1.00",
3728        "Bangladeshi Taka1.00",
3729        "Bangladeshi taka1.00",
3730        "Bangladeshi takas1.00",
3731        "Barbadian Dollar1.00",
3732        "Barbadian dollar1.00",
3733        "Barbadian dollars1.00",
3734        "Belarusian New Ruble (1994\\u20131999)1.00",
3735        "Belarusian Ruble1.00",
3736        "Belarusian new ruble (1994\\u20131999)1.00",
3737        "Belarusian new rubles (1994\\u20131999)1.00",
3738        "Belarusian ruble1.00",
3739        "Belarusian rubles1.00",
3740        "Belgian Franc (convertible)1.00",
3741        "Belgian Franc (financial)1.00",
3742        "Belgian Franc1.00",
3743        "Belgian franc (convertible)1.00",
3744        "Belgian franc (financial)1.00",
3745        "Belgian franc1.00",
3746        "Belgian francs (convertible)1.00",
3747        "Belgian francs (financial)1.00",
3748        "Belgian francs1.00",
3749        "Belize Dollar1.00",
3750        "Belize dollar1.00",
3751        "Belize dollars1.00",
3752        "Bermudan Dollar1.00",
3753        "Bermudan dollar1.00",
3754        "Bermudan dollars1.00",
3755        "Bhutanese Ngultrum1.00",
3756        "Bhutanese ngultrum1.00",
3757        "Bhutanese ngultrums1.00",
3758        "Bolivian Mvdol1.00",
3759        "Bolivian Peso1.00",
3760        "Bolivian mvdol1.00",
3761        "Bolivian mvdols1.00",
3762        "Bolivian peso1.00",
3763        "Bolivian pesos1.00",
3764        "Bolivian Boliviano1.00",
3765        "Bolivian Boliviano1.00",
3766        "Bolivian Bolivianos1.00",
3767        "Bosnia-Herzegovina Convertible Mark1.00",
3768        "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
3769        "Bosnia-Herzegovina convertible mark1.00",
3770        "Bosnia-Herzegovina convertible marks1.00",
3771        "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
3772        "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
3773        "Botswanan Pula1.00",
3774        "Botswanan pula1.00",
3775        "Botswanan pulas1.00",
3776        "Brazilian New Cruzado (1989\\u20131990)1.00",
3777        "Brazilian Cruzado (1986\\u20131989)1.00",
3778        "Brazilian Cruzeiro (1990\\u20131993)1.00",
3779        "Brazilian New Cruzeiro (1967\\u20131986)1.00",
3780        "Brazilian Cruzeiro (1993\\u20131994)1.00",
3781        "Brazilian Real1.00",
3782        "Brazilian new cruzado (1989\\u20131990)1.00",
3783        "Brazilian new cruzados (1989\\u20131990)1.00",
3784        "Brazilian cruzado (1986\\u20131989)1.00",
3785        "Brazilian cruzados (1986\\u20131989)1.00",
3786        "Brazilian cruzeiro (1990\\u20131993)1.00",
3787        "Brazilian new cruzeiro (1967\\u20131986)1.00",
3788        "Brazilian cruzeiro (1993\\u20131994)1.00",
3789        "Brazilian cruzeiros (1990\\u20131993)1.00",
3790        "Brazilian new cruzeiros (1967\\u20131986)1.00",
3791        "Brazilian cruzeiros (1993\\u20131994)1.00",
3792        "Brazilian real1.00",
3793        "Brazilian reals1.00",
3794        "British Pound Sterling1.00",
3795        "British pound sterling1.00",
3796        "British pounds sterling1.00",
3797        "Brunei Dollar1.00",
3798        "Brunei dollar1.00",
3799        "Brunei dollars1.00",
3800        "Bulgarian Hard Lev1.00",
3801        "Bulgarian Lev1.00",
3802        "Bulgarian Leva1.00",
3803        "Bulgarian hard lev1.00",
3804        "Bulgarian hard leva1.00",
3805        "Bulgarian lev1.00",
3806        "Burmese Kyat1.00",
3807        "Burmese kyat1.00",
3808        "Burmese kyats1.00",
3809        "Burundian Franc1.00",
3810        "Burundian franc1.00",
3811        "Burundian francs1.00",
3812        "CA$1.00",
3813        "CAD1.00",
3814        "CDF1.00",
3815        "CDF1.00",
3816        "CFA Franc BCEAO1.00",
3817        "CFA Franc BEAC1.00",
3818        "CFA franc BCEAO1.00",
3819        "CFA franc BEAC1.00",
3820        "CFA francs BCEAO1.00",
3821        "CFA francs BEAC1.00",
3822        "CFP Franc1.00",
3823        "CFP franc1.00",
3824        "CFP francs1.00",
3825        "CFPF1.00",
3826        "CHE1.00",
3827        "CHE1.00",
3828        "CHF1.00",
3829        "CHW1.00",
3830        "CHW1.00",
3831        "CLF1.00",
3832        "CLF1.00",
3833        "CLP1.00",
3834        "CNY1.00",
3835        "COP1.00",
3836        "COU1.00",
3837        "COU1.00",
3838        "CRC1.00",
3839        "CSD1.00",
3840        "CSD1.00",
3841        "CSK1.00",
3842        "CSK1.00",
3843        "CUP1.00",
3844        "CUP1.00",
3845        "CVE1.00",
3846        "CYP1.00",
3847        "CZK1.00",
3848        "Cambodian Riel1.00",
3849        "Cambodian riel1.00",
3850        "Cambodian riels1.00",
3851        "Canadian Dollar1.00",
3852        "Canadian dollar1.00",
3853        "Canadian dollars1.00",
3854        "Cape Verdean Escudo1.00",
3855        "Cape Verdean escudo1.00",
3856        "Cape Verdean escudos1.00",
3857        "Cayman Islands Dollar1.00",
3858        "Cayman Islands dollar1.00",
3859        "Cayman Islands dollars1.00",
3860        "Chilean Peso1.00",
3861        "Chilean Unit of Account (UF)1.00",
3862        "Chilean peso1.00",
3863        "Chilean pesos1.00",
3864        "Chilean unit of account (UF)1.00",
3865        "Chilean units of account (UF)1.00",
3866        "Chinese Yuan1.00",
3867        "Chinese yuan1.00",
3868        "Colombian Peso1.00",
3869        "Colombian peso1.00",
3870        "Colombian pesos1.00",
3871        "Comorian Franc1.00",
3872        "Comorian franc1.00",
3873        "Comorian francs1.00",
3874        "Congolese Franc1.00",
3875        "Congolese franc1.00",
3876        "Congolese francs1.00",
3877        "Costa Rican Col\\u00f3n1.00",
3878        "Costa Rican col\\u00f3n1.00",
3879        "Costa Rican col\\u00f3ns1.00",
3880        "Croatian Dinar1.00",
3881        "Croatian Kuna1.00",
3882        "Croatian dinar1.00",
3883        "Croatian dinars1.00",
3884        "Croatian kuna1.00",
3885        "Croatian kunas1.00",
3886        "Cuban Peso1.00",
3887        "Cuban peso1.00",
3888        "Cuban pesos1.00",
3889        "Cypriot Pound1.00",
3890        "Cypriot pound1.00",
3891        "Cypriot pounds1.00",
3892        "Czech Republic Koruna1.00",
3893        "Czech Republic koruna1.00",
3894        "Czech Republic korunas1.00",
3895        "Czechoslovak Hard Koruna1.00",
3896        "Czechoslovak hard koruna1.00",
3897        "Czechoslovak hard korunas1.00",
3898        "DDM1.00",
3899        "DDM1.00",
3900        "DEM1.00",
3901        "DEM1.00",
3902        "DJF1.00",
3903        "DKK1.00",
3904        "DOP1.00",
3905        "DZD1.00",
3906        "Danish Krone1.00",
3907        "Danish krone1.00",
3908        "Danish kroner1.00",
3909        "German Mark1.00",
3910        "German mark1.00",
3911        "German marks1.00",
3912        "Djiboutian Franc1.00",
3913        "Djiboutian franc1.00",
3914        "Djiboutian francs1.00",
3915        "Dominican Peso1.00",
3916        "Dominican peso1.00",
3917        "Dominican pesos1.00",
3918        "EC$1.00",
3919        "ECS1.00",
3920        "ECS1.00",
3921        "ECV1.00",
3922        "ECV1.00",
3923        "EEK1.00",
3924        "EEK1.00",
3925        "EGP1.00",
3926        "EGP1.00",
3927        "ERN1.00",
3928        "ERN1.00",
3929        "ESA1.00",
3930        "ESA1.00",
3931        "ESB1.00",
3932        "ESB1.00",
3933        "ESP1.00",
3934        "ETB1.00",
3935        "EUR1.00",
3936        "East Caribbean Dollar1.00",
3937        "East Caribbean dollar1.00",
3938        "East Caribbean dollars1.00",
3939        "East German Mark1.00",
3940        "East German mark1.00",
3941        "East German marks1.00",
3942        "Ecuadorian Sucre1.00",
3943        "Ecuadorian Unit of Constant Value1.00",
3944        "Ecuadorian sucre1.00",
3945        "Ecuadorian sucres1.00",
3946        "Ecuadorian unit of constant value1.00",
3947        "Ecuadorian units of constant value1.00",
3948        "Egyptian Pound1.00",
3949        "Egyptian pound1.00",
3950        "Egyptian pounds1.00",
3951        "Salvadoran Col\\u00f3n1.00",
3952        "Salvadoran col\\u00f3n1.00",
3953        "Salvadoran colones1.00",
3954        "Equatorial Guinean Ekwele1.00",
3955        "Equatorial Guinean ekwele1.00",
3956        "Eritrean Nakfa1.00",
3957        "Eritrean nakfa1.00",
3958        "Eritrean nakfas1.00",
3959        "Estonian Kroon1.00",
3960        "Estonian kroon1.00",
3961        "Estonian kroons1.00",
3962        "Ethiopian Birr1.00",
3963        "Ethiopian birr1.00",
3964        "Ethiopian birrs1.00",
3965        "Euro1.00",
3966        "European Composite Unit1.00",
3967        "European Currency Unit1.00",
3968        "European Monetary Unit1.00",
3969        "European Unit of Account (XBC)1.00",
3970        "European Unit of Account (XBD)1.00",
3971        "European composite unit1.00",
3972        "European composite units1.00",
3973        "European currency unit1.00",
3974        "European currency units1.00",
3975        "European monetary unit1.00",
3976        "European monetary units1.00",
3977        "European unit of account (XBC)1.00",
3978        "European unit of account (XBD)1.00",
3979        "European units of account (XBC)1.00",
3980        "European units of account (XBD)1.00",
3981        "FIM1.00",
3982        "FIM1.00",
3983        "FJD1.00",
3984        "FKP1.00",
3985        "FKP1.00",
3986        "FRF1.00",
3987        "FRF1.00",
3988        "Falkland Islands Pound1.00",
3989        "Falkland Islands pound1.00",
3990        "Falkland Islands pounds1.00",
3991        "Fijian Dollar1.00",
3992        "Fijian dollar1.00",
3993        "Fijian dollars1.00",
3994        "Finnish Markka1.00",
3995        "Finnish markka1.00",
3996        "Finnish markkas1.00",
3997        "CHF1.00",
3998        "French Franc1.00",
3999        "French Gold Franc1.00",
4000        "French UIC-Franc1.00",
4001        "French UIC-franc1.00",
4002        "French UIC-francs1.00",
4003        "French franc1.00",
4004        "French francs1.00",
4005        "French gold franc1.00",
4006        "French gold francs1.00",
4007        "GBP1.00",
4008        "GEK1.00",
4009        "GEK1.00",
4010        "GEL1.00",
4011        "GHC1.00",
4012        "GHC1.00",
4013        "GHS1.00",
4014        "GIP1.00",
4015        "GIP1.00",
4016        "GMD1.00",
4017        "GMD1.00",
4018        "GNF1.00",
4019        "GNS1.00",
4020        "GNS1.00",
4021        "GQE1.00",
4022        "GQE1.00",
4023        "GRD1.00",
4024        "GRD1.00",
4025        "GTQ1.00",
4026        "GWE1.00",
4027        "GWE1.00",
4028        "GWP1.00",
4029        "GWP1.00",
4030        "GYD1.00",
4031        "Gambian Dalasi1.00",
4032        "Gambian dalasi1.00",
4033        "Gambian dalasis1.00",
4034        "Georgian Kupon Larit1.00",
4035        "Georgian Lari1.00",
4036        "Georgian kupon larit1.00",
4037        "Georgian kupon larits1.00",
4038        "Georgian lari1.00",
4039        "Georgian laris1.00",
4040        "Ghanaian Cedi (1979\\u20132007)1.00",
4041        "Ghanaian Cedi1.00",
4042        "Ghanaian cedi (1979\\u20132007)1.00",
4043        "Ghanaian cedi1.00",
4044        "Ghanaian cedis (1979\\u20132007)1.00",
4045        "Ghanaian cedis1.00",
4046        "Gibraltar Pound1.00",
4047        "Gibraltar pound1.00",
4048        "Gibraltar pounds1.00",
4049        "Gold1.00",
4050        "Gold1.00",
4051        "Greek Drachma1.00",
4052        "Greek drachma1.00",
4053        "Greek drachmas1.00",
4054        "Guatemalan Quetzal1.00",
4055        "Guatemalan quetzal1.00",
4056        "Guatemalan quetzals1.00",
4057        "Guinean Franc1.00",
4058        "Guinean Syli1.00",
4059        "Guinean franc1.00",
4060        "Guinean francs1.00",
4061        "Guinean syli1.00",
4062        "Guinean sylis1.00",
4063        "Guinea-Bissau Peso1.00",
4064        "Guinea-Bissau peso1.00",
4065        "Guinea-Bissau pesos1.00",
4066        "Guyanaese Dollar1.00",
4067        "Guyanaese dollar1.00",
4068        "Guyanaese dollars1.00",
4069        "HK$1.00",
4070        "HKD1.00",
4071        "HNL1.00",
4072        "HRD1.00",
4073        "HRD1.00",
4074        "HRK1.00",
4075        "HRK1.00",
4076        "HTG1.00",
4077        "HTG1.00",
4078        "HUF1.00",
4079        "Haitian Gourde1.00",
4080        "Haitian gourde1.00",
4081        "Haitian gourdes1.00",
4082        "Honduran Lempira1.00",
4083        "Honduran lempira1.00",
4084        "Honduran lempiras1.00",
4085        "Hong Kong Dollar1.00",
4086        "Hong Kong dollar1.00",
4087        "Hong Kong dollars1.00",
4088        "Hungarian Forint1.00",
4089        "Hungarian forint1.00",
4090        "Hungarian forints1.00",
4091        "IDR1.00",
4092        "IEP1.00",
4093        "ILP1.00",
4094        "ILP1.00",
4095        "ILS1.00",
4096        "INR1.00",
4097        "IQD1.00",
4098        "IRR1.00",
4099        "ISK1.00",
4100        "ISK1.00",
4101        "ITL1.00",
4102        "Icelandic Kr\\u00f3na1.00",
4103        "Icelandic kr\\u00f3na1.00",
4104        "Icelandic kr\\u00f3nur1.00",
4105        "Indian Rupee1.00",
4106        "Indian rupee1.00",
4107        "Indian rupees1.00",
4108        "Indonesian Rupiah1.00",
4109        "Indonesian rupiah1.00",
4110        "Indonesian rupiahs1.00",
4111        "Iranian Rial1.00",
4112        "Iranian rial1.00",
4113        "Iranian rials1.00",
4114        "Iraqi Dinar1.00",
4115        "Iraqi dinar1.00",
4116        "Iraqi dinars1.00",
4117        "Irish Pound1.00",
4118        "Irish pound1.00",
4119        "Irish pounds1.00",
4120        "Israeli Pound1.00",
4121        "Israeli new sheqel1.00",
4122        "Israeli pound1.00",
4123        "Israeli pounds1.00",
4124        "Italian Lira1.00",
4125        "Italian lira1.00",
4126        "Italian liras1.00",
4127        "JMD1.00",
4128        "JOD1.00",
4129        "JPY1.00",
4130        "Jamaican Dollar1.00",
4131        "Jamaican dollar1.00",
4132        "Jamaican dollars1.00",
4133        "Japanese Yen1.00",
4134        "Japanese yen1.00",
4135        "Jordanian Dinar1.00",
4136        "Jordanian dinar1.00",
4137        "Jordanian dinars1.00",
4138        "KES1.00",
4139        "KGS1.00",
4140        "KHR1.00",
4141        "KMF1.00",
4142        "KPW1.00",
4143        "KPW1.00",
4144        "KRW1.00",
4145        "KWD1.00",
4146        "KYD1.00",
4147        "KYD1.00",
4148        "KZT1.00",
4149        "Kazakhstani Tenge1.00",
4150        "Kazakhstani tenge1.00",
4151        "Kazakhstani tenges1.00",
4152        "Kenyan Shilling1.00",
4153        "Kenyan shilling1.00",
4154        "Kenyan shillings1.00",
4155        "Kuwaiti Dinar1.00",
4156        "Kuwaiti dinar1.00",
4157        "Kuwaiti dinars1.00",
4158        "Kyrgystani Som1.00",
4159        "Kyrgystani som1.00",
4160        "Kyrgystani soms1.00",
4161        "HNL1.00",
4162        "LAK1.00",
4163        "LAK1.00",
4164        "LBP1.00",
4165        "LKR1.00",
4166        "LRD1.00",
4167        "LRD1.00",
4168        "LSL1.00",
4169        "LTL1.00",
4170        "LTL1.00",
4171        "LTT1.00",
4172        "LTT1.00",
4173        "LUC1.00",
4174        "LUC1.00",
4175        "LUF1.00",
4176        "LUF1.00",
4177        "LUL1.00",
4178        "LUL1.00",
4179        "LVL1.00",
4180        "LVL1.00",
4181        "LVR1.00",
4182        "LVR1.00",
4183        "LYD1.00",
4184        "Laotian Kip1.00",
4185        "Laotian kip1.00",
4186        "Laotian kips1.00",
4187        "Latvian Lats1.00",
4188        "Latvian Ruble1.00",
4189        "Latvian lats1.00",
4190        "Latvian lati1.00",
4191        "Latvian ruble1.00",
4192        "Latvian rubles1.00",
4193        "Lebanese Pound1.00",
4194        "Lebanese pound1.00",
4195        "Lebanese pounds1.00",
4196        "Lesotho Loti1.00",
4197        "Lesotho loti1.00",
4198        "Lesotho lotis1.00",
4199        "Liberian Dollar1.00",
4200        "Liberian dollar1.00",
4201        "Liberian dollars1.00",
4202        "Libyan Dinar1.00",
4203        "Libyan dinar1.00",
4204        "Libyan dinars1.00",
4205        "Lithuanian Litas1.00",
4206        "Lithuanian Talonas1.00",
4207        "Lithuanian litas1.00",
4208        "Lithuanian litai1.00",
4209        "Lithuanian talonas1.00",
4210        "Lithuanian talonases1.00",
4211        "Luxembourgian Convertible Franc1.00",
4212        "Luxembourg Financial Franc1.00",
4213        "Luxembourgian Franc1.00",
4214        "Luxembourgian convertible franc1.00",
4215        "Luxembourgian convertible francs1.00",
4216        "Luxembourg financial franc1.00",
4217        "Luxembourg financial francs1.00",
4218        "Luxembourgian franc1.00",
4219        "Luxembourgian francs1.00",
4220        "MAD1.00",
4221        "MAD1.00",
4222        "MAF1.00",
4223        "MAF1.00",
4224        "MDL1.00",
4225        "MDL1.00",
4226        "MX$1.00",
4227        "MGA1.00",
4228        "MGA1.00",
4229        "MGF1.00",
4230        "MGF1.00",
4231        "MKD1.00",
4232        "MLF1.00",
4233        "MLF1.00",
4234        "MMK1.00",
4235        "MMK1.00",
4236        "MNT1.00",
4237        "MOP1.00",
4238        "MOP1.00",
4239        "MRO1.00",
4240        "MTL1.00",
4241        "MTP1.00",
4242        "MTP1.00",
4243        "MUR1.00",
4244        "MUR1.00",
4245        "MVR1.00",
4246        "MVR1.00",
4247        "MWK1.00",
4248        "MXN1.00",
4249        "MXP1.00",
4250        "MXP1.00",
4251        "MXV1.00",
4252        "MXV1.00",
4253        "MYR1.00",
4254        "MZE1.00",
4255        "MZE1.00",
4256        "MZM1.00",
4257        "MZN1.00",
4258        "Macanese Pataca1.00",
4259        "Macanese pataca1.00",
4260        "Macanese patacas1.00",
4261        "Macedonian Denar1.00",
4262        "Macedonian denar1.00",
4263        "Macedonian denari1.00",
4264        "Malagasy Ariaries1.00",
4265        "Malagasy Ariary1.00",
4266        "Malagasy Ariary1.00",
4267        "Malagasy Franc1.00",
4268        "Malagasy franc1.00",
4269        "Malagasy francs1.00",
4270        "Malawian Kwacha1.00",
4271        "Malawian Kwacha1.00",
4272        "Malawian Kwachas1.00",
4273        "Malaysian Ringgit1.00",
4274        "Malaysian ringgit1.00",
4275        "Malaysian ringgits1.00",
4276        "Maldivian Rufiyaa1.00",
4277        "Maldivian rufiyaa1.00",
4278        "Maldivian rufiyaas1.00",
4279        "Malian Franc1.00",
4280        "Malian franc1.00",
4281        "Malian francs1.00",
4282        "Maltese Lira1.00",
4283        "Maltese Pound1.00",
4284        "Maltese lira1.00",
4285        "Maltese lira1.00",
4286        "Maltese pound1.00",
4287        "Maltese pounds1.00",
4288        "Mauritanian Ouguiya1.00",
4289        "Mauritanian ouguiya1.00",
4290        "Mauritanian ouguiyas1.00",
4291        "Mauritian Rupee1.00",
4292        "Mauritian rupee1.00",
4293        "Mauritian rupees1.00",
4294        "Mexican Peso1.00",
4295        "Mexican Silver Peso (1861\\u20131992)1.00",
4296        "Mexican Investment Unit1.00",
4297        "Mexican peso1.00",
4298        "Mexican pesos1.00",
4299        "Mexican silver peso (1861\\u20131992)1.00",
4300        "Mexican silver pesos (1861\\u20131992)1.00",
4301        "Mexican investment unit1.00",
4302        "Mexican investment units1.00",
4303        "Moldovan Leu1.00",
4304        "Moldovan leu1.00",
4305        "Moldovan lei1.00",
4306        "Mongolian Tugrik1.00",
4307        "Mongolian tugrik1.00",
4308        "Mongolian tugriks1.00",
4309        "Moroccan Dirham1.00",
4310        "Moroccan Franc1.00",
4311        "Moroccan dirham1.00",
4312        "Moroccan dirhams1.00",
4313        "Moroccan franc1.00",
4314        "Moroccan francs1.00",
4315        "Mozambican Escudo1.00",
4316        "Mozambican Metical1.00",
4317        "Mozambican escudo1.00",
4318        "Mozambican escudos1.00",
4319        "Mozambican metical1.00",
4320        "Mozambican meticals1.00",
4321        "Myanmar Kyat1.00",
4322        "Myanmar kyat1.00",
4323        "Myanmar kyats1.00",
4324        "NAD1.00",
4325        "NGN1.00",
4326        "NIC1.00",
4327        "NIO1.00",
4328        "NIO1.00",
4329        "NLG1.00",
4330        "NLG1.00",
4331        "NOK1.00",
4332        "NPR1.00",
4333        "NT$1.00",
4334        "NZ$1.00",
4335        "NZD1.00",
4336        "Namibian Dollar1.00",
4337        "Namibian dollar1.00",
4338        "Namibian dollars1.00",
4339        "Nepalese Rupee1.00",
4340        "Nepalese rupee1.00",
4341        "Nepalese rupees1.00",
4342        "Netherlands Antillean Guilder1.00",
4343        "Netherlands Antillean guilder1.00",
4344        "Netherlands Antillean guilders1.00",
4345        "Dutch Guilder1.00",
4346        "Dutch guilder1.00",
4347        "Dutch guilders1.00",
4348        "Israeli New Sheqel1.00",
4349        "Israeli New Sheqels1.00",
4350        "New Zealand Dollar1.00",
4351        "New Zealand dollar1.00",
4352        "New Zealand dollars1.00",
4353        "Nicaraguan C\\u00f3rdoba1.00",
4354        "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00",
4355        "Nicaraguan c\\u00f3rdoba1.00",
4356        "Nicaraguan c\\u00f3rdobas1.00",
4357        "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00",
4358        "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00",
4359        "Nigerian Naira1.00",
4360        "Nigerian naira1.00",
4361        "Nigerian nairas1.00",
4362        "North Korean Won1.00",
4363        "North Korean won1.00",
4364        "North Korean won1.00",
4365        "Norwegian Krone1.00",
4366        "Norwegian krone1.00",
4367        "Norwegian kroner1.00",
4368        "OMR1.00",
4369        "Mozambican Metical (1980\\u20132006)1.00",
4370        "Mozambican metical (1980\\u20132006)1.00",
4371        "Mozambican meticals (1980\\u20132006)1.00",
4372        "Romanian Lei (1952\\u20132006)1.00",
4373        "Romanian Leu (1952\\u20132006)1.00",
4374        "Romanian leu (1952\\u20132006)1.00",
4375        "Serbian Dinar (2002\\u20132006)1.00",
4376        "Serbian dinar (2002\\u20132006)1.00",
4377        "Serbian dinars (2002\\u20132006)1.00",
4378        "Sudanese Dinar (1992\\u20132007)1.00",
4379        "Sudanese Pound (1957\\u20131998)1.00",
4380        "Sudanese dinar (1992\\u20132007)1.00",
4381        "Sudanese dinars (1992\\u20132007)1.00",
4382        "Sudanese pound (1957\\u20131998)1.00",
4383        "Sudanese pounds (1957\\u20131998)1.00",
4384        "Turkish Lira (1922\\u20132005)1.00",
4385        "Turkish Lira (1922\\u20132005)1.00",
4386        "Omani Rial1.00",
4387        "Omani rial1.00",
4388        "Omani rials1.00",
4389        "PAB1.00",
4390        "PAB1.00",
4391        "PEI1.00",
4392        "PEI1.00",
4393        "PEN1.00",
4394        "PEN1.00",
4395        "PES1.00",
4396        "PES1.00",
4397        "PGK1.00",
4398        "PGK1.00",
4399        "PHP1.00",
4400        "PKR1.00",
4401        "PLN1.00",
4402        "PLZ1.00",
4403        "PLZ1.00",
4404        "PTE1.00",
4405        "PTE1.00",
4406        "PYG1.00",
4407        "Pakistani Rupee1.00",
4408        "Pakistani rupee1.00",
4409        "Pakistani rupees1.00",
4410        "Palladium1.00",
4411        "Palladium1.00",
4412        "Panamanian Balboa1.00",
4413        "Panamanian balboa1.00",
4414        "Panamanian balboas1.00",
4415        "Papua New Guinean Kina1.00",
4416        "Papua New Guinean kina1.00",
4417        "Papua New Guinean kina1.00",
4418        "Paraguayan Guarani1.00",
4419        "Paraguayan guarani1.00",
4420        "Paraguayan guaranis1.00",
4421        "Peruvian Inti1.00",
4422        "Peruvian Nuevo Sol1.00",
4423        "Peruvian Sol (1863\\u20131965)1.00",
4424        "Peruvian inti1.00",
4425        "Peruvian intis1.00",
4426        "Peruvian nuevo sol1.00",
4427        "Peruvian nuevos soles1.00",
4428        "Peruvian sol (1863\\u20131965)1.00",
4429        "Peruvian soles (1863\\u20131965)1.00",
4430        "Philippine Peso1.00",
4431        "Philippine peso1.00",
4432        "Philippine pesos1.00",
4433        "Platinum1.00",
4434        "Platinum1.00",
4435        "Polish Zloty (1950\\u20131995)1.00",
4436        "Polish Zloty1.00",
4437        "Polish zlotys1.00",
4438        "Polish zloty (PLZ)1.00",
4439        "Polish zloty1.00",
4440        "Polish zlotys (PLZ)1.00",
4441        "Portuguese Escudo1.00",
4442        "Portuguese Guinea Escudo1.00",
4443        "Portuguese Guinea escudo1.00",
4444        "Portuguese Guinea escudos1.00",
4445        "Portuguese escudo1.00",
4446        "Portuguese escudos1.00",
4447        "GTQ1.00",
4448        "QAR1.00",
4449        "Qatari Rial1.00",
4450        "Qatari rial1.00",
4451        "Qatari rials1.00",
4452        "RHD1.00",
4453        "RHD1.00",
4454        "RINET Funds1.00",
4455        "RINET Funds1.00",
4456        "CN\\u00a51.00",
4457        "ROL1.00",
4458        "ROL1.00",
4459        "RON1.00",
4460        "RON1.00",
4461        "RSD1.00",
4462        "RSD1.00",
4463        "RUB1.00",
4464        "RUB1.00",
4465        "RUR1.00",
4466        "RUR1.00",
4467        "RWF1.00",
4468        "RWF1.00",
4469        "Rhodesian Dollar1.00",
4470        "Rhodesian dollar1.00",
4471        "Rhodesian dollars1.00",
4472        "Romanian Leu1.00",
4473        "Romanian lei1.00",
4474        "Romanian leu1.00",
4475        "Russian Ruble (1991\\u20131998)1.00",
4476        "Russian Ruble1.00",
4477        "Russian ruble (1991\\u20131998)1.00",
4478        "Russian ruble1.00",
4479        "Russian rubles (1991\\u20131998)1.00",
4480        "Russian rubles1.00",
4481        "Rwandan Franc1.00",
4482        "Rwandan franc1.00",
4483        "Rwandan francs1.00",
4484        "SAR1.00",
4485        "SBD1.00",
4486        "SCR1.00",
4487        "SDD1.00",
4488        "SDD1.00",
4489        "SDG1.00",
4490        "SDG1.00",
4491        "SDP1.00",
4492        "SDP1.00",
4493        "SEK1.00",
4494        "SGD1.00",
4495        "SHP1.00",
4496        "SHP1.00",
4497        "SIT1.00",
4498        "SIT1.00",
4499        "SKK1.00",
4500        "SLL1.00",
4501        "SLL1.00",
4502        "SOS1.00",
4503        "SRD1.00",
4504        "SRD1.00",
4505        "SRG1.00",
4506        "STD1.00",
4507        "SUR1.00",
4508        "SUR1.00",
4509        "SVC1.00",
4510        "SVC1.00",
4511        "SYP1.00",
4512        "SZL1.00",
4513        "Saint Helena Pound1.00",
4514        "Saint Helena pound1.00",
4515        "Saint Helena pounds1.00",
4516        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobra1.00",
4517        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobra1.00",
4518        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobras1.00",
4519        "Saudi Riyal1.00",
4520        "Saudi riyal1.00",
4521        "Saudi riyals1.00",
4522        "Serbian Dinar1.00",
4523        "Serbian dinar1.00",
4524        "Serbian dinars1.00",
4525        "Seychellois Rupee1.00",
4526        "Seychellois rupee1.00",
4527        "Seychellois rupees1.00",
4528        "Sierra Leonean Leone1.00",
4529        "Sierra Leonean leone1.00",
4530        "Sierra Leonean leones1.00",
4531        "Silver1.00",
4532        "Silver1.00",
4533        "Singapore Dollar1.00",
4534        "Singapore dollar1.00",
4535        "Singapore dollars1.00",
4536        "Slovak Koruna1.00",
4537        "Slovak koruna1.00",
4538        "Slovak korunas1.00",
4539        "Slovenian Tolar1.00",
4540        "Slovenian tolar1.00",
4541        "Slovenian tolars1.00",
4542        "Solomon Islands Dollar1.00",
4543        "Solomon Islands dollar1.00",
4544        "Solomon Islands dollars1.00",
4545        "Somali Shilling1.00",
4546        "Somali shilling1.00",
4547        "Somali shillings1.00",
4548        "South African Rand (financial)1.00",
4549        "South African Rand1.00",
4550        "South African rand (financial)1.00",
4551        "South African rand1.00",
4552        "South African rands (financial)1.00",
4553        "South African rand1.00",
4554        "South Korean Won1.00",
4555        "South Korean won1.00",
4556        "South Korean won1.00",
4557        "Soviet Rouble1.00",
4558        "Soviet rouble1.00",
4559        "Soviet roubles1.00",
4560        "Spanish Peseta (A account)1.00",
4561        "Spanish Peseta (convertible account)1.00",
4562        "Spanish Peseta1.00",
4563        "Spanish peseta (A account)1.00",
4564        "Spanish peseta (convertible account)1.00",
4565        "Spanish peseta1.00",
4566        "Spanish pesetas (A account)1.00",
4567        "Spanish pesetas (convertible account)1.00",
4568        "Spanish pesetas1.00",
4569        "Special Drawing Rights1.00",
4570        "Sri Lankan Rupee1.00",
4571        "Sri Lankan rupee1.00",
4572        "Sri Lankan rupees1.00",
4573        "Sudanese Pound1.00",
4574        "Sudanese pound1.00",
4575        "Sudanese pounds1.00",
4576        "Surinamese Dollar1.00",
4577        "Surinamese dollar1.00",
4578        "Surinamese dollars1.00",
4579        "Surinamese Guilder1.00",
4580        "Surinamese guilder1.00",
4581        "Surinamese guilders1.00",
4582        "Swazi Lilangeni1.00",
4583        "Swazi lilangeni1.00",
4584        "Swazi emalangeni1.00",
4585        "Swedish Krona1.00",
4586        "Swedish krona1.00",
4587        "Swedish kronor1.00",
4588        "Swiss Franc1.00",
4589        "Swiss franc1.00",
4590        "Swiss francs1.00",
4591        "Syrian Pound1.00",
4592        "Syrian pound1.00",
4593        "Syrian pounds1.00",
4594        "THB1.00",
4595        "TJR1.00",
4596        "TJR1.00",
4597        "TJS1.00",
4598        "TJS1.00",
4599        "TMM1.00",
4600        "TMM1.00",
4601        "TND1.00",
4602        "TND1.00",
4603        "TOP1.00",
4604        "TPE1.00",
4605        "TPE1.00",
4606        "TRL1.00",
4607        "TRY1.00",
4608        "TRY1.00",
4609        "TTD1.00",
4610        "TWD1.00",
4611        "TZS1.00",
4612        "New Taiwan Dollar1.00",
4613        "New Taiwan dollar1.00",
4614        "New Taiwan dollars1.00",
4615        "Tajikistani Ruble1.00",
4616        "Tajikistani Somoni1.00",
4617        "Tajikistani ruble1.00",
4618        "Tajikistani rubles1.00",
4619        "Tajikistani somoni1.00",
4620        "Tajikistani somonis1.00",
4621        "Tanzanian Shilling1.00",
4622        "Tanzanian shilling1.00",
4623        "Tanzanian shillings1.00",
4624        "Testing Currency Code1.00",
4625        "Testing Currency Code1.00",
4626        "Thai Baht1.00",
4627        "Thai baht1.00",
4628        "Thai baht1.00",
4629        "Timorese Escudo1.00",
4630        "Timorese escudo1.00",
4631        "Timorese escudos1.00",
4632        "Tongan Pa\\u02bbanga1.00",
4633        "Tongan pa\\u02bbanga1.00",
4634        "Tongan pa\\u02bbanga1.00",
4635        "Trinidad and Tobago Dollar1.00",
4636        "Trinidad and Tobago dollar1.00",
4637        "Trinidad and Tobago dollars1.00",
4638        "Tunisian Dinar1.00",
4639        "Tunisian dinar1.00",
4640        "Tunisian dinars1.00",
4641        "Turkish Lira1.00",
4642        "Turkish Lira1.00",
4643        "Turkish lira1.00",
4644        "Turkmenistani Manat1.00",
4645        "Turkmenistani manat1.00",
4646        "Turkmenistani manat1.00",
4647        "UAE dirham1.00",
4648        "UAE dirhams1.00",
4649        "UAH1.00",
4650        "UAK1.00",
4651        "UAK1.00",
4652        "UGS1.00",
4653        "UGS1.00",
4654        "UGX1.00",
4655        "US Dollar (Next day)1.00",
4656        "US Dollar (Same day)1.00",
4657        "US Dollar1.00",
4658        "US dollar (next day)1.00",
4659        "US dollar (same day)1.00",
4660        "US dollar1.00",
4661        "US dollars (next day)1.00",
4662        "US dollars (same day)1.00",
4663        "US dollars1.00",
4664        "USD1.00",
4665        "USN1.00",
4666        "USN1.00",
4667        "USS1.00",
4668        "USS1.00",
4669        "UYI1.00",
4670        "UYI1.00",
4671        "UYP1.00",
4672        "UYP1.00",
4673        "UYU1.00",
4674        "UZS1.00",
4675        "UZS1.00",
4676        "Ugandan Shilling (1966\\u20131987)1.00",
4677        "Ugandan Shilling1.00",
4678        "Ugandan shilling (1966\\u20131987)1.00",
4679        "Ugandan shilling1.00",
4680        "Ugandan shillings (1966\\u20131987)1.00",
4681        "Ugandan shillings1.00",
4682        "Ukrainian Hryvnia1.00",
4683        "Ukrainian Karbovanets1.00",
4684        "Ukrainian hryvnia1.00",
4685        "Ukrainian hryvnias1.00",
4686        "Ukrainian karbovanets1.00",
4687        "Ukrainian karbovantsiv1.00",
4688        "Colombian Real Value Unit1.00",
4689        "United Arab Emirates Dirham1.00",
4690        "Unknown Currency1.00",
4691        "Uruguayan Peso (1975\\u20131993)1.00",
4692        "Uruguayan Peso1.00",
4693        "Uruguayan Peso (Indexed Units)1.00",
4694        "Uruguayan peso (1975\\u20131993)1.00",
4695        "Uruguayan peso (indexed units)1.00",
4696        "Uruguayan peso1.00",
4697        "Uruguayan pesos (1975\\u20131993)1.00",
4698        "Uruguayan pesos (indexed units)1.00",
4699        "Uruguayan pesos1.00",
4700        "Uzbekistan Som1.00",
4701        "Uzbekistan som1.00",
4702        "Uzbekistan som1.00",
4703        "VEB1.00",
4704        "VEF1.00",
4705        "VND1.00",
4706        "VUV1.00",
4707        "Vanuatu Vatu1.00",
4708        "Vanuatu vatu1.00",
4709        "Vanuatu vatus1.00",
4710        "Venezuelan Bol\\u00edvar1.00",
4711        "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00",
4712        "Venezuelan bol\\u00edvar1.00",
4713        "Venezuelan bol\\u00edvars1.00",
4714        "Venezuelan bol\\u00edvar (1871\\u20132008)1.00",
4715        "Venezuelan bol\\u00edvars (1871\\u20132008)1.00",
4716        "Vietnamese Dong1.00",
4717        "Vietnamese dong1.00",
4718        "Vietnamese dong1.00",
4719        "WIR Euro1.00",
4720        "WIR Franc1.00",
4721        "WIR euro1.00",
4722        "WIR euros1.00",
4723        "WIR franc1.00",
4724        "WIR francs1.00",
4725        "WST1.00",
4726        "WST1.00",
4727        "Samoan Tala1.00",
4728        "Samoan tala1.00",
4729        "Samoan tala1.00",
4730        "XAF1.00",
4731        "XAF1.00",
4732        "XAG1.00",
4733        "XAG1.00",
4734        "XAU1.00",
4735        "XAU1.00",
4736        "XBA1.00",
4737        "XBA1.00",
4738        "XBB1.00",
4739        "XBB1.00",
4740        "XBC1.00",
4741        "XBC1.00",
4742        "XBD1.00",
4743        "XBD1.00",
4744        "XCD1.00",
4745        "XDR1.00",
4746        "XDR1.00",
4747        "XEU1.00",
4748        "XEU1.00",
4749        "XFO1.00",
4750        "XFO1.00",
4751        "XFU1.00",
4752        "XFU1.00",
4753        "XOF1.00",
4754        "XOF1.00",
4755        "XPD1.00",
4756        "XPD1.00",
4757        "XPF1.00",
4758        "XPT1.00",
4759        "XPT1.00",
4760        "XRE1.00",
4761        "XRE1.00",
4762        "XTS1.00",
4763        "XTS1.00",
4764        "XXX1.00",
4765        "XXX1.00",
4766        "YDD1.00",
4767        "YDD1.00",
4768        "YER1.00",
4769        "YUD1.00",
4770        "YUD1.00",
4771        "YUM1.00",
4772        "YUM1.00",
4773        "YUN1.00",
4774        "YUN1.00",
4775        "Yemeni Dinar1.00",
4776        "Yemeni Rial1.00",
4777        "Yemeni dinar1.00",
4778        "Yemeni dinars1.00",
4779        "Yemeni rial1.00",
4780        "Yemeni rials1.00",
4781        "Yugoslavian Convertible Dinar (1990\\u20131992)1.00",
4782        "Yugoslavian Hard Dinar (1966\\u20131990)1.00",
4783        "Yugoslavian New Dinar (1994\\u20132002)1.00",
4784        "Yugoslavian convertible dinar (1990\\u20131992)1.00",
4785        "Yugoslavian convertible dinars (1990\\u20131992)1.00",
4786        "Yugoslavian hard dinar (1966\\u20131990)1.00",
4787        "Yugoslavian hard dinars (1966\\u20131990)1.00",
4788        "Yugoslavian new dinar (1994\\u20132002)1.00",
4789        "Yugoslavian new dinars (1994\\u20132002)1.00",
4790        "ZAL1.00",
4791        "ZAL1.00",
4792        "ZAR1.00",
4793        "ZMK1.00",
4794        "ZMK1.00",
4795        "ZRN1.00",
4796        "ZRN1.00",
4797        "ZRZ1.00",
4798        "ZRZ1.00",
4799        "ZWD1.00",
4800        "Zairean New Zaire (1993\\u20131998)1.00",
4801        "Zairean Zaire (1971\\u20131993)1.00",
4802        "Zairean new zaire (1993\\u20131998)1.00",
4803        "Zairean new zaires (1993\\u20131998)1.00",
4804        "Zairean zaire (1971\\u20131993)1.00",
4805        "Zairean zaires (1971\\u20131993)1.00",
4806        "Zambian Kwacha1.00",
4807        "Zambian kwacha1.00",
4808        "Zambian kwachas1.00",
4809        "Zimbabwean Dollar (1980\\u20132008)1.00",
4810        "Zimbabwean dollar (1980\\u20132008)1.00",
4811        "Zimbabwean dollars (1980\\u20132008)1.00",
4812        "euro1.00",
4813        "euros1.00",
4814        "Turkish lira (1922\\u20132005)1.00",
4815        "special drawing rights1.00",
4816        "Colombian real value unit1.00",
4817        "Colombian real value units1.00",
4818        "unknown currency1.00",
4819        "\\u00a31.00",
4820        "\\u00a51.00",
4821        "\\u0e3f1.00",
4822        "\\u20ab1.00",
4823        "\\u20aa1.00",
4824        "\\u20ac1.00",
4825        "Rs.1.00",          // Google Patch: Indian Rupee symbol \u20B9 -> "Rs."
4826        //
4827        // Following has extra text, should be parsed correctly too
4828        "$1.00 random",
4829        "USD1.00 random",
4830        "1.00 US dollar random",
4831        "1.00 US dollars random",
4832        "1.00 Afghan Afghani random",
4833        "1.00 Afghan Afghani random",
4834        "1.00 Afghan Afghanis (1927\\u20131992) random",
4835        "1.00 Afghan Afghanis random",
4836        "1.00 Albanian Lek random",
4837        "1.00 Albanian lek random",
4838        "1.00 Albanian lek\\u00eb random",
4839        "1.00 Algerian Dinar random",
4840        "1.00 Algerian dinar random",
4841        "1.00 Algerian dinars random",
4842        "1.00 Andorran Peseta random",
4843        "1.00 Andorran peseta random",
4844        "1.00 Andorran pesetas random",
4845        "1.00 Angolan Kwanza (1977\\u20131990) random",
4846        "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random",
4847        "1.00 Angolan Kwanza random",
4848        "1.00 Angolan New Kwanza (1990\\u20132000) random",
4849        "1.00 Angolan kwanza (1977\\u20131991) random",
4850        "1.00 Angolan readjusted kwanza (1995\\u20131999) random",
4851        "1.00 Angolan kwanza random",
4852        "1.00 Angolan kwanzas (1977\\u20131991) random",
4853        "1.00 Angolan readjusted kwanzas (1995\\u20131999) random",
4854        "1.00 Angolan kwanzas random",
4855        "1.00 Angolan new kwanza (1990\\u20132000) random",
4856        "1.00 Angolan new kwanzas (1990\\u20132000) random",
4857        "1.00 Argentine Austral random",
4858        "1.00 Argentine Peso (1983\\u20131985) random",
4859        "1.00 Argentine Peso random",
4860        "1.00 Argentine austral random",
4861        "1.00 Argentine australs random",
4862        "1.00 Argentine peso (1983\\u20131985) random",
4863        "1.00 Argentine peso random",
4864        "1.00 Argentine pesos (1983\\u20131985) random",
4865        "1.00 Argentine pesos random",
4866        "1.00 Armenian Dram random",
4867        "1.00 Armenian dram random",
4868        "1.00 Armenian drams random",
4869        "1.00 Aruban Florin random",
4870        "1.00 Aruban florin random",
4871        "1.00 Australian Dollar random",
4872        "1.00 Australian dollar random",
4873        "1.00 Australian dollars random",
4874        "1.00 Austrian Schilling random",
4875        "1.00 Austrian schilling random",
4876        "1.00 Austrian schillings random",
4877        "1.00 Azerbaijani Manat (1993\\u20132006) random",
4878        "1.00 Azerbaijani Manat random",
4879        "1.00 Azerbaijani manat (1993\\u20132006) random",
4880        "1.00 Azerbaijani manat random",
4881        "1.00 Azerbaijani manats (1993\\u20132006) random",
4882        "1.00 Azerbaijani manats random",
4883        "1.00 Bahamian Dollar random",
4884        "1.00 Bahamian dollar random",
4885        "1.00 Bahamian dollars random",
4886        "1.00 Bahraini Dinar random",
4887        "1.00 Bahraini dinar random",
4888        "1.00 Bahraini dinars random",
4889        "1.00 Bangladeshi Taka random",
4890        "1.00 Bangladeshi taka random",
4891        "1.00 Bangladeshi takas random",
4892        "1.00 Barbadian Dollar random",
4893        "1.00 Barbadian dollar random",
4894        "1.00 Barbadian dollars random",
4895        "1.00 Belarusian New Ruble (1994\\u20131999) random",
4896        "1.00 Belarusian Ruble random",
4897        "1.00 Belarusian new ruble (1994\\u20131999) random",
4898        "1.00 Belarusian new rubles (1994\\u20131999) random",
4899        "1.00 Belarusian ruble random",
4900        "1.00 Belarusian rubles random",
4901        "1.00 Belgian Franc (convertible) random",
4902        "1.00 Belgian Franc (financial) random",
4903        "1.00 Belgian Franc random",
4904        "1.00 Belgian franc (convertible) random",
4905        "1.00 Belgian franc (financial) random",
4906        "1.00 Belgian franc random",
4907        "1.00 Belgian francs (convertible) random",
4908        "1.00 Belgian francs (financial) random",
4909        "1.00 Belgian francs random",
4910        "1.00 Belize Dollar random",
4911        "1.00 Belize dollar random",
4912        "1.00 Belize dollars random",
4913        "1.00 Bermudan Dollar random",
4914        "1.00 Bermudan dollar random",
4915        "1.00 Bermudan dollars random",
4916        "1.00 Bhutanese Ngultrum random",
4917        "1.00 Bhutanese ngultrum random",
4918        "1.00 Bhutanese ngultrums random",
4919        "1.00 Bolivian Mvdol random",
4920        "1.00 Bolivian Peso random",
4921        "1.00 Bolivian mvdol random",
4922        "1.00 Bolivian mvdols random",
4923        "1.00 Bolivian peso random",
4924        "1.00 Bolivian pesos random",
4925        "1.00 Bolivian Boliviano random",
4926        "1.00 Bolivian Boliviano random",
4927        "1.00 Bolivian Bolivianos random",
4928        "1.00 Bosnia-Herzegovina Convertible Mark random",
4929        "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random",
4930        "1.00 Bosnia-Herzegovina convertible mark random",
4931        "1.00 Bosnia-Herzegovina convertible marks random",
4932        "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random",
4933        "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random",
4934        "1.00 Botswanan Pula random",
4935        "1.00 Botswanan pula random",
4936        "1.00 Botswanan pulas random",
4937        "1.00 Brazilian New Cruzado (1989\\u20131990) random",
4938        "1.00 Brazilian Cruzado (1986\\u20131989) random",
4939        "1.00 Brazilian Cruzeiro (1990\\u20131993) random",
4940        "1.00 Brazilian New Cruzeiro (1967\\u20131986) random",
4941        "1.00 Brazilian Cruzeiro (1993\\u20131994) random",
4942        "1.00 Brazilian Real random",
4943        "1.00 Brazilian new cruzado (1989\\u20131990) random",
4944        "1.00 Brazilian new cruzados (1989\\u20131990) random",
4945        "1.00 Brazilian cruzado (1986\\u20131989) random",
4946        "1.00 Brazilian cruzados (1986\\u20131989) random",
4947        "1.00 Brazilian cruzeiro (1990\\u20131993) random",
4948        "1.00 Brazilian new cruzeiro (1967\\u20131986) random",
4949        "1.00 Brazilian cruzeiro (1993\\u20131994) random",
4950        "1.00 Brazilian cruzeiros (1990\\u20131993) random",
4951        "1.00 Brazilian new cruzeiros (1967\\u20131986) random",
4952        "1.00 Brazilian cruzeiros (1993\\u20131994) random",
4953        "1.00 Brazilian real random",
4954        "1.00 Brazilian reals random",
4955        "1.00 British Pound Sterling random",
4956        "1.00 British pound sterling random",
4957        "1.00 British pounds sterling random",
4958        "1.00 Brunei Dollar random",
4959        "1.00 Brunei dollar random",
4960        "1.00 Brunei dollars random",
4961        "1.00 Bulgarian Hard Lev random",
4962        "1.00 Bulgarian Lev random",
4963        "1.00 Bulgarian Leva random",
4964        "1.00 Bulgarian hard lev random",
4965        "1.00 Bulgarian hard leva random",
4966        "1.00 Bulgarian lev random",
4967        "1.00 Burmese Kyat random",
4968        "1.00 Burmese kyat random",
4969        "1.00 Burmese kyats random",
4970        "1.00 Burundian Franc random",
4971        "1.00 Burundian franc random",
4972        "1.00 Burundian francs random",
4973        "1.00 Cambodian Riel random",
4974        "1.00 Cambodian riel random",
4975        "1.00 Cambodian riels random",
4976        "1.00 Canadian Dollar random",
4977        "1.00 Canadian dollar random",
4978        "1.00 Canadian dollars random",
4979        "1.00 Cape Verdean Escudo random",
4980        "1.00 Cape Verdean escudo random",
4981        "1.00 Cape Verdean escudos random",
4982        "1.00 Cayman Islands Dollar random",
4983        "1.00 Cayman Islands dollar random",
4984        "1.00 Cayman Islands dollars random",
4985        "1.00 Chilean Peso random",
4986        "1.00 Chilean Unit of Account (UF) random",
4987        "1.00 Chilean peso random",
4988        "1.00 Chilean pesos random",
4989        "1.00 Chilean unit of account (UF) random",
4990        "1.00 Chilean units of account (UF) random",
4991        "1.00 Chinese Yuan random",
4992        "1.00 Chinese yuan random",
4993        "1.00 Colombian Peso random",
4994        "1.00 Colombian peso random",
4995        "1.00 Colombian pesos random",
4996        "1.00 Comorian Franc random",
4997        "1.00 Comorian franc random",
4998        "1.00 Comorian francs random",
4999        "1.00 Congolese Franc Congolais random",
5000        "1.00 Congolese franc Congolais random",
5001        "1.00 Congolese francs Congolais random",
5002        "1.00 Costa Rican Col\\u00f3n random",
5003        "1.00 Costa Rican col\\u00f3n random",
5004        "1.00 Costa Rican col\\u00f3ns random",
5005        "1.00 Croatian Dinar random",
5006        "1.00 Croatian Kuna random",
5007        "1.00 Croatian dinar random",
5008        "1.00 Croatian dinars random",
5009        "1.00 Croatian kuna random",
5010        "1.00 Croatian kunas random",
5011        "1.00 Cuban Peso random",
5012        "1.00 Cuban peso random",
5013        "1.00 Cuban pesos random",
5014        "1.00 Cypriot Pound random",
5015        "1.00 Cypriot pound random",
5016        "1.00 Cypriot pounds random",
5017        "1.00 Czech Republic Koruna random",
5018        "1.00 Czech Republic koruna random",
5019        "1.00 Czech Republic korunas random",
5020        "1.00 Czechoslovak Hard Koruna random",
5021        "1.00 Czechoslovak hard koruna random",
5022        "1.00 Czechoslovak hard korunas random",
5023        "1.00 Danish Krone random",
5024        "1.00 Danish krone random",
5025        "1.00 Danish kroner random",
5026        "1.00 German Mark random",
5027        "1.00 German mark random",
5028        "1.00 German marks random",
5029        "1.00 Djiboutian Franc random",
5030        "1.00 Djiboutian franc random",
5031        "1.00 Djiboutian francs random",
5032        "1.00 Dominican Peso random",
5033        "1.00 Dominican peso random",
5034        "1.00 Dominican pesos random",
5035        "1.00 East Caribbean Dollar random",
5036        "1.00 East Caribbean dollar random",
5037        "1.00 East Caribbean dollars random",
5038        "1.00 East German Mark random",
5039        "1.00 East German mark random",
5040        "1.00 East German marks random",
5041        "1.00 Ecuadorian Sucre random",
5042        "1.00 Ecuadorian Unit of Constant Value random",
5043        "1.00 Ecuadorian sucre random",
5044        "1.00 Ecuadorian sucres random",
5045        "1.00 Ecuadorian unit of constant value random",
5046        "1.00 Ecuadorian units of constant value random",
5047        "1.00 Egyptian Pound random",
5048        "1.00 Egyptian pound random",
5049        "1.00 Egyptian pounds random",
5050        "1.00 Salvadoran Col\\u00f3n random",
5051        "1.00 Salvadoran col\\u00f3n random",
5052        "1.00 Salvadoran colones random",
5053        "1.00 Equatorial Guinean Ekwele random",
5054        "1.00 Equatorial Guinean ekwele random",
5055        "1.00 Eritrean Nakfa random",
5056        "1.00 Eritrean nakfa random",
5057        "1.00 Eritrean nakfas random",
5058        "1.00 Estonian Kroon random",
5059        "1.00 Estonian kroon random",
5060        "1.00 Estonian kroons random",
5061        "1.00 Ethiopian Birr random",
5062        "1.00 Ethiopian birr random",
5063        "1.00 Ethiopian birrs random",
5064        "1.00 European Composite Unit random",
5065        "1.00 European Currency Unit random",
5066        "1.00 European Monetary Unit random",
5067        "1.00 European Unit of Account (XBC) random",
5068        "1.00 European Unit of Account (XBD) random",
5069        "1.00 European composite unit random",
5070        "1.00 European composite units random",
5071        "1.00 European currency unit random",
5072        "1.00 European currency units random",
5073        "1.00 European monetary unit random",
5074        "1.00 European monetary units random",
5075        "1.00 European unit of account (XBC) random",
5076        "1.00 European unit of account (XBD) random",
5077        "1.00 European units of account (XBC) random",
5078        "1.00 European units of account (XBD) random",
5079        "1.00 Falkland Islands Pound random",
5080        "1.00 Falkland Islands pound random",
5081        "1.00 Falkland Islands pounds random",
5082        "1.00 Fijian Dollar random",
5083        "1.00 Fijian dollar random",
5084        "1.00 Fijian dollars random",
5085        "1.00 Finnish Markka random",
5086        "1.00 Finnish markka random",
5087        "1.00 Finnish markkas random",
5088        "1.00 French Franc random",
5089        "1.00 French Gold Franc random",
5090        "1.00 French UIC-Franc random",
5091        "1.00 French UIC-franc random",
5092        "1.00 French UIC-francs random",
5093        "1.00 French franc random",
5094        "1.00 French francs random",
5095        "1.00 French gold franc random",
5096        "1.00 French gold francs random",
5097        "1.00 Gambian Dalasi random",
5098        "1.00 Gambian dalasi random",
5099        "1.00 Gambian dalasis random",
5100        "1.00 Georgian Kupon Larit random",
5101        "1.00 Georgian Lari random",
5102        "1.00 Georgian kupon larit random",
5103        "1.00 Georgian kupon larits random",
5104        "1.00 Georgian lari random",
5105        "1.00 Georgian laris random",
5106        "1.00 Ghanaian Cedi (1979\\u20132007) random",
5107        "1.00 Ghanaian Cedi random",
5108        "1.00 Ghanaian cedi (1979\\u20132007) random",
5109        "1.00 Ghanaian cedi random",
5110        "1.00 Ghanaian cedis (1979\\u20132007) random",
5111        "1.00 Ghanaian cedis random",
5112        "1.00 Gibraltar Pound random",
5113        "1.00 Gibraltar pound random",
5114        "1.00 Gibraltar pounds random",
5115        "1.00 Gold random",
5116        "1.00 Gold random",
5117        "1.00 Greek Drachma random",
5118        "1.00 Greek drachma random",
5119        "1.00 Greek drachmas random",
5120        "1.00 Guatemalan Quetzal random",
5121        "1.00 Guatemalan quetzal random",
5122        "1.00 Guatemalan quetzals random",
5123        "1.00 Guinean Franc random",
5124        "1.00 Guinean Syli random",
5125        "1.00 Guinean franc random",
5126        "1.00 Guinean francs random",
5127        "1.00 Guinean syli random",
5128        "1.00 Guinean sylis random",
5129        "1.00 Guinea-Bissau Peso random",
5130        "1.00 Guinea-Bissau peso random",
5131        "1.00 Guinea-Bissau pesos random",
5132        "1.00 Guyanaese Dollar random",
5133        "1.00 Guyanaese dollar random",
5134        "1.00 Guyanaese dollars random",
5135        "1.00 Haitian Gourde random",
5136        "1.00 Haitian gourde random",
5137        "1.00 Haitian gourdes random",
5138        "1.00 Honduran Lempira random",
5139        "1.00 Honduran lempira random",
5140        "1.00 Honduran lempiras random",
5141        "1.00 Hong Kong Dollar random",
5142        "1.00 Hong Kong dollar random",
5143        "1.00 Hong Kong dollars random",
5144        "1.00 Hungarian Forint random",
5145        "1.00 Hungarian forint random",
5146        "1.00 Hungarian forints random",
5147        "1.00 Icelandic Kr\\u00f3na random",
5148        "1.00 Icelandic kr\\u00f3na random",
5149        "1.00 Icelandic kr\\u00f3nur random",
5150        "1.00 Indian Rupee random",
5151        "1.00 Indian rupee random",
5152        "1.00 Indian rupees random",
5153        "1.00 Indonesian Rupiah random",
5154        "1.00 Indonesian rupiah random",
5155        "1.00 Indonesian rupiahs random",
5156        "1.00 Iranian Rial random",
5157        "1.00 Iranian rial random",
5158        "1.00 Iranian rials random",
5159        "1.00 Iraqi Dinar random",
5160        "1.00 Iraqi dinar random",
5161        "1.00 Iraqi dinars random",
5162        "1.00 Irish Pound random",
5163        "1.00 Irish pound random",
5164        "1.00 Irish pounds random",
5165        "1.00 Israeli Pound random",
5166        "1.00 Israeli new sheqel random",
5167        "1.00 Israeli pound random",
5168        "1.00 Israeli pounds random",
5169        "1.00 Italian Lira random",
5170        "1.00 Italian lira random",
5171        "1.00 Italian liras random",
5172        "1.00 Jamaican Dollar random",
5173        "1.00 Jamaican dollar random",
5174        "1.00 Jamaican dollars random",
5175        "1.00 Japanese Yen random",
5176        "1.00 Japanese yen random",
5177        "1.00 Jordanian Dinar random",
5178        "1.00 Jordanian dinar random",
5179        "1.00 Jordanian dinars random",
5180        "1.00 Kazakhstani Tenge random",
5181        "1.00 Kazakhstani tenge random",
5182        "1.00 Kazakhstani tenges random",
5183        "1.00 Kenyan Shilling random",
5184        "1.00 Kenyan shilling random",
5185        "1.00 Kenyan shillings random",
5186        "1.00 Kuwaiti Dinar random",
5187        "1.00 Kuwaiti dinar random",
5188        "1.00 Kuwaiti dinars random",
5189        "1.00 Kyrgystani Som random",
5190        "1.00 Kyrgystani som random",
5191        "1.00 Kyrgystani soms random",
5192        "1.00 Laotian Kip random",
5193        "1.00 Laotian kip random",
5194        "1.00 Laotian kips random",
5195        "1.00 Latvian Lats random",
5196        "1.00 Latvian Ruble random",
5197        "1.00 Latvian lats random",
5198        "1.00 Latvian lati random",
5199        "1.00 Latvian ruble random",
5200        "1.00 Latvian rubles random",
5201        "1.00 Lebanese Pound random",
5202        "1.00 Lebanese pound random",
5203        "1.00 Lebanese pounds random",
5204        "1.00 Lesotho Loti random",
5205        "1.00 Lesotho loti random",
5206        "1.00 Lesotho lotis random",
5207        "1.00 Liberian Dollar random",
5208        "1.00 Liberian dollar random",
5209        "1.00 Liberian dollars random",
5210        "1.00 Libyan Dinar random",
5211        "1.00 Libyan dinar random",
5212        "1.00 Libyan dinars random",
5213        "1.00 Lithuanian Litas random",
5214        "1.00 Lithuanian Talonas random",
5215        "1.00 Lithuanian litas random",
5216        "1.00 Lithuanian litai random",
5217        "1.00 Lithuanian talonas random",
5218        "1.00 Lithuanian talonases random",
5219        "1.00 Luxembourgian Convertible Franc random",
5220        "1.00 Luxembourg Financial Franc random",
5221        "1.00 Luxembourgian Franc random",
5222        "1.00 Luxembourgian convertible franc random",
5223        "1.00 Luxembourgian convertible francs random",
5224        "1.00 Luxembourg financial franc random",
5225        "1.00 Luxembourg financial francs random",
5226        "1.00 Luxembourgian franc random",
5227        "1.00 Luxembourgian francs random",
5228        "1.00 Macanese Pataca random",
5229        "1.00 Macanese pataca random",
5230        "1.00 Macanese patacas random",
5231        "1.00 Macedonian Denar random",
5232        "1.00 Macedonian denar random",
5233        "1.00 Macedonian denari random",
5234        "1.00 Malagasy Ariaries random",
5235        "1.00 Malagasy Ariary random",
5236        "1.00 Malagasy Ariary random",
5237        "1.00 Malagasy Franc random",
5238        "1.00 Malagasy franc random",
5239        "1.00 Malagasy francs random",
5240        "1.00 Malawian Kwacha random",
5241        "1.00 Malawian Kwacha random",
5242        "1.00 Malawian Kwachas random",
5243        "1.00 Malaysian Ringgit random",
5244        "1.00 Malaysian ringgit random",
5245        "1.00 Malaysian ringgits random",
5246        "1.00 Maldivian Rufiyaa random",
5247        "1.00 Maldivian rufiyaa random",
5248        "1.00 Maldivian rufiyaas random",
5249        "1.00 Malian Franc random",
5250        "1.00 Malian franc random",
5251        "1.00 Malian francs random",
5252        "1.00 Maltese Lira random",
5253        "1.00 Maltese Pound random",
5254        "1.00 Maltese lira random",
5255        "1.00 Maltese liras random",
5256        "1.00 Maltese pound random",
5257        "1.00 Maltese pounds random",
5258        "1.00 Mauritanian Ouguiya random",
5259        "1.00 Mauritanian ouguiya random",
5260        "1.00 Mauritanian ouguiyas random",
5261        "1.00 Mauritian Rupee random",
5262        "1.00 Mauritian rupee random",
5263        "1.00 Mauritian rupees random",
5264        "1.00 Mexican Peso random",
5265        "1.00 Mexican Silver Peso (1861\\u20131992) random",
5266        "1.00 Mexican Investment Unit random",
5267        "1.00 Mexican peso random",
5268        "1.00 Mexican pesos random",
5269        "1.00 Mexican silver peso (1861\\u20131992) random",
5270        "1.00 Mexican silver pesos (1861\\u20131992) random",
5271        "1.00 Mexican investment unit random",
5272        "1.00 Mexican investment units random",
5273        "1.00 Moldovan Leu random",
5274        "1.00 Moldovan leu random",
5275        "1.00 Moldovan lei random",
5276        "1.00 Mongolian Tugrik random",
5277        "1.00 Mongolian tugrik random",
5278        "1.00 Mongolian tugriks random",
5279        "1.00 Moroccan Dirham random",
5280        "1.00 Moroccan Franc random",
5281        "1.00 Moroccan dirham random",
5282        "1.00 Moroccan dirhams random",
5283        "1.00 Moroccan franc random",
5284        "1.00 Moroccan francs random",
5285        "1.00 Mozambican Escudo random",
5286        "1.00 Mozambican Metical random",
5287        "1.00 Mozambican escudo random",
5288        "1.00 Mozambican escudos random",
5289        "1.00 Mozambican metical random",
5290        "1.00 Mozambican meticals random",
5291        "1.00 Myanmar Kyat random",
5292        "1.00 Myanmar kyat random",
5293        "1.00 Myanmar kyats random",
5294        "1.00 Namibian Dollar random",
5295        "1.00 Namibian dollar random",
5296        "1.00 Namibian dollars random",
5297        "1.00 Nepalese Rupee random",
5298        "1.00 Nepalese rupee random",
5299        "1.00 Nepalese rupees random",
5300        "1.00 Netherlands Antillean Guilder random",
5301        "1.00 Netherlands Antillean guilder random",
5302        "1.00 Netherlands Antillean guilders random",
5303        "1.00 Dutch Guilder random",
5304        "1.00 Dutch guilder random",
5305        "1.00 Dutch guilders random",
5306        "1.00 Israeli New Sheqel random",
5307        "1.00 Israeli new sheqels random",
5308        "1.00 New Zealand Dollar random",
5309        "1.00 New Zealand dollar random",
5310        "1.00 New Zealand dollars random",
5311        "1.00 Nicaraguan C\\u00f3rdoba random",
5312        "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random",
5313        "1.00 Nicaraguan c\\u00f3rdoba random",
5314        "1.00 Nicaraguan c\\u00f3rdoba random",
5315        "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random",
5316        "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random",
5317        "1.00 Nigerian Naira random",
5318        "1.00 Nigerian naira random",
5319        "1.00 Nigerian nairas random",
5320        "1.00 North Korean Won random",
5321        "1.00 North Korean won random",
5322        "1.00 North Korean won random",
5323        "1.00 Norwegian Krone random",
5324        "1.00 Norwegian krone random",
5325        "1.00 Norwegian kroner random",
5326        "1.00 Mozambican Metical (1980\\u20132006) random",
5327        "1.00 Mozambican metical (1980\\u20132006) random",
5328        "1.00 Mozambican meticals (1980\\u20132006) random",
5329        "1.00 Romanian Lei (1952\\u20132006) random",
5330        "1.00 Romanian Leu (1952\\u20132006) random",
5331        "1.00 Romanian leu (1952\\u20132006) random",
5332        "1.00 Serbian Dinar (2002\\u20132006) random",
5333        "1.00 Serbian dinar (2002\\u20132006) random",
5334        "1.00 Serbian dinars (2002\\u20132006) random",
5335        "1.00 Sudanese Dinar (1992\\u20132007) random",
5336        "1.00 Sudanese Pound (1957\\u20131998) random",
5337        "1.00 Sudanese dinar (1992\\u20132007) random",
5338        "1.00 Sudanese dinars (1992\\u20132007) random",
5339        "1.00 Sudanese pound (1957\\u20131998) random",
5340        "1.00 Sudanese pounds (1957\\u20131998) random",
5341        "1.00 Turkish Lira (1922\\u20132005) random",
5342        "1.00 Turkish Lira (1922\\u20132005) random",
5343        "1.00 Omani Rial random",
5344        "1.00 Omani rial random",
5345        "1.00 Omani rials random",
5346        "1.00 Pakistani Rupee random",
5347        "1.00 Pakistani rupee random",
5348        "1.00 Pakistani rupees random",
5349        "1.00 Palladium random",
5350        "1.00 Palladium random",
5351        "1.00 Panamanian Balboa random",
5352        "1.00 Panamanian balboa random",
5353        "1.00 Panamanian balboas random",
5354        "1.00 Papua New Guinean Kina random",
5355        "1.00 Papua New Guinean kina random",
5356        "1.00 Papua New Guinean kina random",
5357        "1.00 Paraguayan Guarani random",
5358        "1.00 Paraguayan guarani random",
5359        "1.00 Paraguayan guaranis random",
5360        "1.00 Peruvian Inti random",
5361        "1.00 Peruvian Nuevo Sol random",
5362        "1.00 Peruvian Sol (1863\\u20131965) random",
5363        "1.00 Peruvian inti random",
5364        "1.00 Peruvian intis random",
5365        "1.00 Peruvian nuevo sol random",
5366        "1.00 Peruvian nuevos soles random",
5367        "1.00 Peruvian sol (1863\\u20131965) random",
5368        "1.00 Peruvian soles (1863\\u20131965) random",
5369        "1.00 Philippine Peso random",
5370        "1.00 Philippine peso random",
5371        "1.00 Philippine pesos random",
5372        "1.00 Platinum random",
5373        "1.00 Platinum random",
5374        "1.00 Polish Zloty (1950\\u20131995) random",
5375        "1.00 Polish Zloty random",
5376        "1.00 Polish zlotys random",
5377        "1.00 Polish zloty (PLZ) random",
5378        "1.00 Polish zloty random",
5379        "1.00 Polish zlotys (PLZ) random",
5380        "1.00 Portuguese Escudo random",
5381        "1.00 Portuguese Guinea Escudo random",
5382        "1.00 Portuguese Guinea escudo random",
5383        "1.00 Portuguese Guinea escudos random",
5384        "1.00 Portuguese escudo random",
5385        "1.00 Portuguese escudos random",
5386        "1.00 Qatari Rial random",
5387        "1.00 Qatari rial random",
5388        "1.00 Qatari rials random",
5389        "1.00 RINET Funds random",
5390        "1.00 RINET Funds random",
5391        "1.00 Rhodesian Dollar random",
5392        "1.00 Rhodesian dollar random",
5393        "1.00 Rhodesian dollars random",
5394        "1.00 Romanian Leu random",
5395        "1.00 Romanian lei random",
5396        "1.00 Romanian leu random",
5397        "1.00 Russian Ruble (1991\\u20131998) random",
5398        "1.00 Russian Ruble random",
5399        "1.00 Russian ruble (1991\\u20131998) random",
5400        "1.00 Russian ruble random",
5401        "1.00 Russian rubles (1991\\u20131998) random",
5402        "1.00 Russian rubles random",
5403        "1.00 Rwandan Franc random",
5404        "1.00 Rwandan franc random",
5405        "1.00 Rwandan francs random",
5406        "1.00 Saint Helena Pound random",
5407        "1.00 Saint Helena pound random",
5408        "1.00 Saint Helena pounds random",
5409        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobra random",
5410        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobra random",
5411        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobras random",
5412        "1.00 Saudi Riyal random",
5413        "1.00 Saudi riyal random",
5414        "1.00 Saudi riyals random",
5415        "1.00 Serbian Dinar random",
5416        "1.00 Serbian dinar random",
5417        "1.00 Serbian dinars random",
5418        "1.00 Seychellois Rupee random",
5419        "1.00 Seychellois rupee random",
5420        "1.00 Seychellois rupees random",
5421        "1.00 Sierra Leonean Leone random",
5422        "1.00 Sierra Leonean leone random",
5423        "1.00 Sierra Leonean leones random",
5424        "1.00 Singapore Dollar random",
5425        "1.00 Singapore dollar random",
5426        "1.00 Singapore dollars random",
5427        "1.00 Slovak Koruna random",
5428        "1.00 Slovak koruna random",
5429        "1.00 Slovak korunas random",
5430        "1.00 Slovenian Tolar random",
5431        "1.00 Slovenian tolar random",
5432        "1.00 Slovenian tolars random",
5433        "1.00 Solomon Islands Dollar random",
5434        "1.00 Solomon Islands dollar random",
5435        "1.00 Solomon Islands dollars random",
5436        "1.00 Somali Shilling random",
5437        "1.00 Somali shilling random",
5438        "1.00 Somali shillings random",
5439        "1.00 South African Rand (financial) random",
5440        "1.00 South African Rand random",
5441        "1.00 South African rand (financial) random",
5442        "1.00 South African rand random",
5443        "1.00 South African rands (financial) random",
5444        "1.00 South African rand random",
5445        "1.00 South Korean Won random",
5446        "1.00 South Korean won random",
5447        "1.00 South Korean won random",
5448        "1.00 Soviet Rouble random",
5449        "1.00 Soviet rouble random",
5450        "1.00 Soviet roubles random",
5451        "1.00 Spanish Peseta (A account) random",
5452        "1.00 Spanish Peseta (convertible account) random",
5453        "1.00 Spanish Peseta random",
5454        "1.00 Spanish peseta (A account) random",
5455        "1.00 Spanish peseta (convertible account) random",
5456        "1.00 Spanish peseta random",
5457        "1.00 Spanish pesetas (A account) random",
5458        "1.00 Spanish pesetas (convertible account) random",
5459        "1.00 Spanish pesetas random",
5460        "1.00 Special Drawing Rights random",
5461        "1.00 Sri Lankan Rupee random",
5462        "1.00 Sri Lankan rupee random",
5463        "1.00 Sri Lankan rupees random",
5464        "1.00 Sudanese Pound random",
5465        "1.00 Sudanese pound random",
5466        "1.00 Sudanese pounds random",
5467        "1.00 Surinamese Dollar random",
5468        "1.00 Surinamese dollar random",
5469        "1.00 Surinamese dollars random",
5470        "1.00 Surinamese Guilder random",
5471        "1.00 Surinamese guilder random",
5472        "1.00 Surinamese guilders random",
5473        "1.00 Swazi Lilangeni random",
5474        "1.00 Swazi lilangeni random",
5475        "1.00 Swazi emalangeni random",
5476        "1.00 Swedish Krona random",
5477        "1.00 Swedish krona random",
5478        "1.00 Swedish kronor random",
5479        "1.00 Swiss Franc random",
5480        "1.00 Swiss franc random",
5481        "1.00 Swiss francs random",
5482        "1.00 Syrian Pound random",
5483        "1.00 Syrian pound random",
5484        "1.00 Syrian pounds random",
5485        "1.00 New Taiwan Dollar random",
5486        "1.00 New Taiwan dollar random",
5487        "1.00 New Taiwan dollars random",
5488        "1.00 Tajikistani Ruble random",
5489        "1.00 Tajikistani Somoni random",
5490        "1.00 Tajikistani ruble random",
5491        "1.00 Tajikistani rubles random",
5492        "1.00 Tajikistani somoni random",
5493        "1.00 Tajikistani somonis random",
5494        "1.00 Tanzanian Shilling random",
5495        "1.00 Tanzanian shilling random",
5496        "1.00 Tanzanian shillings random",
5497        "1.00 Testing Currency Code random",
5498        "1.00 Testing Currency Code random",
5499        "1.00 Thai Baht random",
5500        "1.00 Thai baht random",
5501        "1.00 Thai baht random",
5502        "1.00 Timorese Escudo random",
5503        "1.00 Timorese escudo random",
5504        "1.00 Timorese escudos random",
5505        "1.00 Trinidad and Tobago Dollar random",
5506        "1.00 Trinidad and Tobago dollar random",
5507        "1.00 Trinidad and Tobago dollars random",
5508        "1.00 Tunisian Dinar random",
5509        "1.00 Tunisian dinar random",
5510        "1.00 Tunisian dinars random",
5511        "1.00 Turkish Lira random",
5512        "1.00 Turkish Lira random",
5513        "1.00 Turkish lira random",
5514        "1.00 Turkmenistani Manat random",
5515        "1.00 Turkmenistani manat random",
5516        "1.00 Turkmenistani manat random",
5517        "1.00 US Dollar (Next day) random",
5518        "1.00 US Dollar (Same day) random",
5519        "1.00 US Dollar random",
5520        "1.00 US dollar (next day) random",
5521        "1.00 US dollar (same day) random",
5522        "1.00 US dollar random",
5523        "1.00 US dollars (next day) random",
5524        "1.00 US dollars (same day) random",
5525        "1.00 US dollars random",
5526        "1.00 Ugandan Shilling (1966\\u20131987) random",
5527        "1.00 Ugandan Shilling random",
5528        "1.00 Ugandan shilling (1966\\u20131987) random",
5529        "1.00 Ugandan shilling random",
5530        "1.00 Ugandan shillings (1966\\u20131987) random",
5531        "1.00 Ugandan shillings random",
5532        "1.00 Ukrainian Hryvnia random",
5533        "1.00 Ukrainian Karbovanets random",
5534        "1.00 Ukrainian hryvnia random",
5535        "1.00 Ukrainian hryvnias random",
5536        "1.00 Ukrainian karbovanets random",
5537        "1.00 Ukrainian karbovantsiv random",
5538        "1.00 Colombian Real Value Unit random",
5539        "1.00 United Arab Emirates Dirham random",
5540        "1.00 Unknown Currency random",
5541        "1.00 Uruguayan Peso (1975\\u20131993) random",
5542        "1.00 Uruguayan Peso random",
5543        "1.00 Uruguayan Peso (Indexed Units) random",
5544        "1.00 Uruguayan peso (1975\\u20131993) random",
5545        "1.00 Uruguayan peso (indexed units) random",
5546        "1.00 Uruguayan peso random",
5547        "1.00 Uruguayan pesos (1975\\u20131993) random",
5548        "1.00 Uruguayan pesos (indexed units) random",
5549        "1.00 Uzbekistan Som random",
5550        "1.00 Uzbekistan som random",
5551        "1.00 Uzbekistan som random",
5552        "1.00 Vanuatu Vatu random",
5553        "1.00 Vanuatu vatu random",
5554        "1.00 Vanuatu vatus random",
5555        "1.00 Venezuelan Bol\\u00edvar random",
5556        "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random",
5557        "1.00 Venezuelan bol\\u00edvar random",
5558        "1.00 Venezuelan bol\\u00edvars random",
5559        "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random",
5560        "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random",
5561        "1.00 Vietnamese Dong random",
5562        "1.00 Vietnamese dong random",
5563        "1.00 Vietnamese dong random",
5564        "1.00 WIR Euro random",
5565        "1.00 WIR Franc random",
5566        "1.00 WIR euro random",
5567        "1.00 WIR euros random",
5568        "1.00 WIR franc random",
5569        "1.00 WIR francs random",
5570        "1.00 Samoan Tala random",
5571        "1.00 Samoan tala random",
5572        "1.00 Samoan tala random",
5573        "1.00 Yemeni Dinar random",
5574        "1.00 Yemeni Rial random",
5575        "1.00 Yemeni dinar random",
5576        "1.00 Yemeni dinars random",
5577        "1.00 Yemeni rial random",
5578        "1.00 Yemeni rials random",
5579        "1.00 Yugoslavian Convertible Dinar (1990\\u20131992) random",
5580        "1.00 Yugoslavian Hard Dinar (1966\\u20131990) random",
5581        "1.00 Yugoslavian New Dinar (1994\\u20132002) random",
5582        "1.00 Yugoslavian convertible dinar (1990\\u20131992) random",
5583        "1.00 Yugoslavian convertible dinars (1990\\u20131992) random",
5584        "1.00 Yugoslavian hard dinar (1966\\u20131990) random",
5585        "1.00 Yugoslavian hard dinars (1966\\u20131990) random",
5586        "1.00 Yugoslavian new dinar (1994\\u20132002) random",
5587        "1.00 Yugoslavian new dinars (1994\\u20132002) random",
5588        "1.00 Zairean New Zaire (1993\\u20131998) random",
5589        "1.00 Zairean Zaire (1971\\u20131993) random",
5590        "1.00 Zairean new zaire (1993\\u20131998) random",
5591        "1.00 Zairean new zaires (1993\\u20131998) random",
5592        "1.00 Zairean zaire (1971\\u20131993) random",
5593        "1.00 Zairean zaires (1971\\u20131993) random",
5594        "1.00 Zambian Kwacha random",
5595        "1.00 Zambian kwacha random",
5596        "1.00 Zambian kwachas random",
5597        "1.00 Zimbabwean Dollar (1980\\u20132008) random",
5598        "1.00 Zimbabwean dollar (1980\\u20132008) random",
5599        "1.00 Zimbabwean dollars (1980\\u20132008) random",
5600        "1.00 euro random",
5601        "1.00 euros random",
5602        "1.00 Turkish lira (1922\\u20132005) random",
5603        "1.00 special drawing rights random",
5604        "1.00 Colombian real value unit random",
5605        "1.00 Colombian real value units random",
5606        "1.00 unknown currency random",
5607    };
5608
5609    const char* WRONG_DATA[] = {
5610        // Following are missing one last char in the currency name
5611        "usd1.00", // case sensitive
5612        "1.00 Nicaraguan Cordob",
5613        "1.00 Namibian Dolla",
5614        "1.00 Namibian dolla",
5615        "1.00 Nepalese Rupe",
5616        "1.00 Nepalese rupe",
5617        "1.00 Netherlands Antillean Guilde",
5618        "1.00 Netherlands Antillean guilde",
5619        "1.00 Dutch Guilde",
5620        "1.00 Dutch guilde",
5621        "1.00 Israeli New Sheqe",
5622        "1.00 New Zealand Dolla",
5623        "1.00 New Zealand dolla",
5624        "1.00 Nicaraguan cordob",
5625        "1.00 Nigerian Nair",
5626        "1.00 Nigerian nair",
5627        "1.00 North Korean Wo",
5628        "1.00 North Korean wo",
5629        "1.00 Norwegian Kron",
5630        "1.00 Norwegian kron",
5631        "1.00 US dolla",
5632        "1.00",
5633        "A1.00",
5634        "AD1.00",
5635        "AE1.00",
5636        "AF1.00",
5637        "AL1.00",
5638        "AM1.00",
5639        "AN1.00",
5640        "AO1.00",
5641        "AR1.00",
5642        "AT1.00",
5643        "AU1.00",
5644        "AW1.00",
5645        "AZ1.00",
5646        "Afghan Afghan1.00",
5647        "Afghan Afghani (1927\\u201320021.00",
5648        "Afl1.00",
5649        "Albanian Le1.00",
5650        "Algerian Dina1.00",
5651        "Andorran Peset1.00",
5652        "Angolan Kwanz1.00",
5653        "Angolan Kwanza (1977\\u201319901.00",
5654        "Angolan Readjusted Kwanza (1995\\u201319991.00",
5655        "Angolan New Kwanza (1990\\u201320001.00",
5656        "Argentine Austra1.00",
5657        "Argentine Pes1.00",
5658        "Argentine Peso (1983\\u201319851.00",
5659        "Armenian Dra1.00",
5660        "Aruban Flori1.00",
5661        "Australian Dolla1.00",
5662        "Austrian Schillin1.00",
5663        "Azerbaijani Mana1.00",
5664        "Azerbaijani Manat (1993\\u201320061.00",
5665        "B1.00",
5666        "BA1.00",
5667        "BB1.00",
5668        "BE1.00",
5669        "BG1.00",
5670        "BH1.00",
5671        "BI1.00",
5672        "BM1.00",
5673        "BN1.00",
5674        "BO1.00",
5675        "BR1.00",
5676        "BS1.00",
5677        "BT1.00",
5678        "BU1.00",
5679        "BW1.00",
5680        "BY1.00",
5681        "BZ1.00",
5682        "Bahamian Dolla1.00",
5683        "Bahraini Dina1.00",
5684        "Bangladeshi Tak1.00",
5685        "Barbadian Dolla1.00",
5686        "Bds1.00",
5687        "Belarusian New Ruble (1994\\u201319991.00",
5688        "Belarusian Rubl1.00",
5689        "Belgian Fran1.00",
5690        "Belgian Franc (convertible1.00",
5691        "Belgian Franc (financial1.00",
5692        "Belize Dolla1.00",
5693        "Bermudan Dolla1.00",
5694        "Bhutanese Ngultru1.00",
5695        "Bolivian Mvdo1.00",
5696        "Bolivian Pes1.00",
5697        "Bolivian Bolivian1.00",
5698        "Bosnia-Herzegovina Convertible Mar1.00",
5699        "Bosnia-Herzegovina Dina1.00",
5700        "Botswanan Pul1.00",
5701        "Brazilian Cruzad1.00",
5702        "Brazilian Cruzado Nov1.00",
5703        "Brazilian Cruzeir1.00",
5704        "Brazilian Cruzeiro (1990\\u201319931.00",
5705        "Brazilian New Cruzeiro (1967\\u201319861.00",
5706        "Brazilian Rea1.00",
5707        "British Pound Sterlin1.00",
5708        "Brunei Dolla1.00",
5709        "Bulgarian Hard Le1.00",
5710        "Bulgarian Le1.00",
5711        "Burmese Kya1.00",
5712        "Burundian Fran1.00",
5713        "C1.00",
5714        "CA1.00",
5715        "CD1.00",
5716        "CFA Franc BCEA1.00",
5717        "CFA Franc BEA1.00",
5718        "CFP Fran1.00",
5719        "CFP1.00",
5720        "CH1.00",
5721        "CL1.00",
5722        "CN1.00",
5723        "CO1.00",
5724        "CS1.00",
5725        "CU1.00",
5726        "CV1.00",
5727        "CY1.00",
5728        "CZ1.00",
5729        "Cambodian Rie1.00",
5730        "Canadian Dolla1.00",
5731        "Cape Verdean Escud1.00",
5732        "Cayman Islands Dolla1.00",
5733        "Chilean Pes1.00",
5734        "Chilean Unit of Accoun1.00",
5735        "Chinese Yua1.00",
5736        "Colombian Pes1.00",
5737        "Comoro Fran1.00",
5738        "Congolese Fran1.00",
5739        "Costa Rican Col\\u00f31.00",
5740        "Croatian Dina1.00",
5741        "Croatian Kun1.00",
5742        "Cuban Pes1.00",
5743        "Cypriot Poun1.00",
5744        "Czech Republic Korun1.00",
5745        "Czechoslovak Hard Korun1.00",
5746        "D1.00",
5747        "DD1.00",
5748        "DE1.00",
5749        "DJ1.00",
5750        "DK1.00",
5751        "DO1.00",
5752        "DZ1.00",
5753        "Danish Kron1.00",
5754        "German Mar1.00",
5755        "Djiboutian Fran1.00",
5756        "Dk1.00",
5757        "Dominican Pes1.00",
5758        "EC1.00",
5759        "EE1.00",
5760        "EG1.00",
5761        "EQ1.00",
5762        "ER1.00",
5763        "ES1.00",
5764        "ET1.00",
5765        "EU1.00",
5766        "East Caribbean Dolla1.00",
5767        "East German Ostmar1.00",
5768        "Ecuadorian Sucr1.00",
5769        "Ecuadorian Unit of Constant Valu1.00",
5770        "Egyptian Poun1.00",
5771        "Ekwel1.00",
5772        "Salvadoran Col\\u00f31.00",
5773        "Equatorial Guinean Ekwel1.00",
5774        "Eritrean Nakf1.00",
5775        "Es1.00",
5776        "Estonian Kroo1.00",
5777        "Ethiopian Bir1.00",
5778        "Eur1.00",
5779        "European Composite Uni1.00",
5780        "European Currency Uni1.00",
5781        "European Monetary Uni1.00",
5782        "European Unit of Account (XBC1.00",
5783        "European Unit of Account (XBD1.00",
5784        "F1.00",
5785        "FB1.00",
5786        "FI1.00",
5787        "FJ1.00",
5788        "FK1.00",
5789        "FR1.00",
5790        "Falkland Islands Poun1.00",
5791        "Fd1.00",
5792        "Fijian Dolla1.00",
5793        "Finnish Markk1.00",
5794        "Fr1.00",
5795        "French Fran1.00",
5796        "French Gold Fran1.00",
5797        "French UIC-Fran1.00",
5798        "G1.00",
5799        "GB1.00",
5800        "GE1.00",
5801        "GH1.00",
5802        "GI1.00",
5803        "GM1.00",
5804        "GN1.00",
5805        "GQ1.00",
5806        "GR1.00",
5807        "GT1.00",
5808        "GW1.00",
5809        "GY1.00",
5810        "Gambian Dalas1.00",
5811        "Georgian Kupon Lari1.00",
5812        "Georgian Lar1.00",
5813        "Ghanaian Ced1.00",
5814        "Ghanaian Cedi (1979\\u201320071.00",
5815        "Gibraltar Poun1.00",
5816        "Gol1.00",
5817        "Greek Drachm1.00",
5818        "Guatemalan Quetza1.00",
5819        "Guinean Fran1.00",
5820        "Guinean Syl1.00",
5821        "Guinea-Bissau Pes1.00",
5822        "Guyanaese Dolla1.00",
5823        "HK1.00",
5824        "HN1.00",
5825        "HR1.00",
5826        "HT1.00",
5827        "HU1.00",
5828        "Haitian Gourd1.00",
5829        "Honduran Lempir1.00",
5830        "Hong Kong Dolla1.00",
5831        "Hungarian Forin1.00",
5832        "I1.00",
5833        "IE1.00",
5834        "IL1.00",
5835        "IN1.00",
5836        "IQ1.00",
5837        "IR1.00",
5838        "IS1.00",
5839        "IT1.00",
5840        "Icelandic Kron1.00",
5841        "Indian Rupe1.00",
5842        "Indonesian Rupia1.00",
5843        "Iranian Ria1.00",
5844        "Iraqi Dina1.00",
5845        "Irish Poun1.00",
5846        "Israeli Poun1.00",
5847        "Italian Lir1.00",
5848        "J1.00",
5849        "JM1.00",
5850        "JO1.00",
5851        "JP1.00",
5852        "Jamaican Dolla1.00",
5853        "Japanese Ye1.00",
5854        "Jordanian Dina1.00",
5855        "K S1.00",
5856        "K1.00",
5857        "KE1.00",
5858        "KG1.00",
5859        "KH1.00",
5860        "KP1.00",
5861        "KR1.00",
5862        "KW1.00",
5863        "KY1.00",
5864        "KZ1.00",
5865        "Kazakhstani Teng1.00",
5866        "Kenyan Shillin1.00",
5867        "Kuwaiti Dina1.00",
5868        "Kyrgystani So1.00",
5869        "LA1.00",
5870        "LB1.00",
5871        "LK1.00",
5872        "LR1.00",
5873        "LT1.00",
5874        "LU1.00",
5875        "LV1.00",
5876        "LY1.00",
5877        "Laotian Ki1.00",
5878        "Latvian Lat1.00",
5879        "Latvian Rubl1.00",
5880        "Lebanese Poun1.00",
5881        "Lesotho Lot1.00",
5882        "Liberian Dolla1.00",
5883        "Libyan Dina1.00",
5884        "Lithuanian Lit1.00",
5885        "Lithuanian Talona1.00",
5886        "Luxembourgian Convertible Fran1.00",
5887        "Luxembourg Financial Fran1.00",
5888        "Luxembourgian Fran1.00",
5889        "MA1.00",
5890        "MD1.00",
5891        "MDe1.00",
5892        "MEX1.00",
5893        "MG1.00",
5894        "ML1.00",
5895        "MM1.00",
5896        "MN1.00",
5897        "MO1.00",
5898        "MR1.00",
5899        "MT1.00",
5900        "MU1.00",
5901        "MV1.00",
5902        "MW1.00",
5903        "MX1.00",
5904        "MY1.00",
5905        "MZ1.00",
5906        "Macanese Patac1.00",
5907        "Macedonian Dena1.00",
5908        "Malagasy Ariar1.00",
5909        "Malagasy Fran1.00",
5910        "Malawian Kwach1.00",
5911        "Malaysian Ringgi1.00",
5912        "Maldivian Rufiya1.00",
5913        "Malian Fran1.00",
5914        "Malot1.00",
5915        "Maltese Lir1.00",
5916        "Maltese Poun1.00",
5917        "Mauritanian Ouguiy1.00",
5918        "Mauritian Rupe1.00",
5919        "Mexican Pes1.00",
5920        "Mexican Silver Peso (1861\\u201319921.00",
5921        "Mexican Investment Uni1.00",
5922        "Moldovan Le1.00",
5923        "Mongolian Tugri1.00",
5924        "Moroccan Dirha1.00",
5925        "Moroccan Fran1.00",
5926        "Mozambican Escud1.00",
5927        "Mozambican Metica1.00",
5928        "Myanmar Kya1.00",
5929        "N1.00",
5930        "NA1.00",
5931        "NAf1.00",
5932        "NG1.00",
5933        "NI1.00",
5934        "NK1.00",
5935        "NL1.00",
5936        "NO1.00",
5937        "NP1.00",
5938        "NT1.00",
5939        "Namibian Dolla1.00",
5940        "Nepalese Rupe1.00",
5941        "Netherlands Antillean Guilde1.00",
5942        "Dutch Guilde1.00",
5943        "Israeli New Sheqe1.00",
5944        "New Zealand Dolla1.00",
5945        "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00",
5946        "Nicaraguan C\\u00f3rdob1.00",
5947        "Nigerian Nair1.00",
5948        "North Korean Wo1.00",
5949        "Norwegian Kron1.00",
5950        "Nr1.00",
5951        "OM1.00",
5952        "Old Mozambican Metica1.00",
5953        "Romanian Leu (1952\\u201320061.00",
5954        "Serbian Dinar (2002\\u201320061.00",
5955        "Sudanese Dinar (1992\\u201320071.00",
5956        "Sudanese Pound (1957\\u201319981.00",
5957        "Turkish Lira (1922\\u201320051.00",
5958        "Omani Ria1.00",
5959        "PA1.00",
5960        "PE1.00",
5961        "PG1.00",
5962        "PH1.00",
5963        "PK1.00",
5964        "PL1.00",
5965        "PT1.00",
5966        "PY1.00",
5967        "Pakistani Rupe1.00",
5968        "Palladiu1.00",
5969        "Panamanian Balbo1.00",
5970        "Papua New Guinean Kin1.00",
5971        "Paraguayan Guaran1.00",
5972        "Peruvian Int1.00",
5973        "Peruvian Sol (1863\\u201319651.00",
5974        "Peruvian Sol Nuev1.00",
5975        "Philippine Pes1.00",
5976        "Platinu1.00",
5977        "Polish Zlot1.00",
5978        "Polish Zloty (1950\\u201319951.00",
5979        "Portuguese Escud1.00",
5980        "Portuguese Guinea Escud1.00",
5981        "Pr1.00",
5982        "QA1.00",
5983        "Qatari Ria1.00",
5984        "RD1.00",
5985        "RH1.00",
5986        "RINET Fund1.00",
5987        "RS1.00",
5988        "RU1.00",
5989        "RW1.00",
5990        "Rb1.00",
5991        "Rhodesian Dolla1.00",
5992        "Romanian Le1.00",
5993        "Russian Rubl1.00",
5994        "Russian Ruble (1991\\u201319981.00",
5995        "Rwandan Fran1.00",
5996        "S1.00",
5997        "SA1.00",
5998        "SB1.00",
5999        "SC1.00",
6000        "SD1.00",
6001        "SE1.00",
6002        "SG1.00",
6003        "SH1.00",
6004        "SI1.00",
6005        "SK1.00",
6006        "SL R1.00",
6007        "SL1.00",
6008        "SO1.00",
6009        "ST1.00",
6010        "SU1.00",
6011        "SV1.00",
6012        "SY1.00",
6013        "SZ1.00",
6014        "Saint Helena Poun1.00",
6015        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobr1.00",
6016        "Saudi Riya1.00",
6017        "Serbian Dina1.00",
6018        "Seychellois Rupe1.00",
6019        "Sh1.00",
6020        "Sierra Leonean Leon1.00",
6021        "Silve1.00",
6022        "Singapore Dolla1.00",
6023        "Slovak Korun1.00",
6024        "Slovenian Tola1.00",
6025        "Solomon Islands Dolla1.00",
6026        "Somali Shillin1.00",
6027        "South African Ran1.00",
6028        "South African Rand (financial1.00",
6029        "South Korean Wo1.00",
6030        "Soviet Roubl1.00",
6031        "Spanish Peset1.00",
6032        "Spanish Peseta (A account1.00",
6033        "Spanish Peseta (convertible account1.00",
6034        "Special Drawing Right1.00",
6035        "Sri Lankan Rupe1.00",
6036        "Sudanese Poun1.00",
6037        "Surinamese Dolla1.00",
6038        "Surinamese Guilde1.00",
6039        "Swazi Lilangen1.00",
6040        "Swedish Kron1.00",
6041        "Swiss Fran1.00",
6042        "Syrian Poun1.00",
6043        "T S1.00",
6044        "TH1.00",
6045        "TJ1.00",
6046        "TM1.00",
6047        "TN1.00",
6048        "TO1.00",
6049        "TP1.00",
6050        "TR1.00",
6051        "TT1.00",
6052        "TW1.00",
6053        "TZ1.00",
6054        "New Taiwan Dolla1.00",
6055        "Tajikistani Rubl1.00",
6056        "Tajikistani Somon1.00",
6057        "Tanzanian Shillin1.00",
6058        "Testing Currency Cod1.00",
6059        "Thai Bah1.00",
6060        "Timorese Escud1.00",
6061        "Tongan Pa\\u20bbang1.00",
6062        "Trinidad and Tobago Dolla1.00",
6063        "Tunisian Dina1.00",
6064        "Turkish Lir1.00",
6065        "Turkmenistani Mana1.00",
6066        "U S1.00",
6067        "U1.00",
6068        "UA1.00",
6069        "UG1.00",
6070        "US Dolla1.00",
6071        "US Dollar (Next day1.00",
6072        "US Dollar (Same day1.00",
6073        "US1.00",
6074        "UY1.00",
6075        "UZ1.00",
6076        "Ugandan Shillin1.00",
6077        "Ugandan Shilling (1966\\u201319871.00",
6078        "Ukrainian Hryvni1.00",
6079        "Ukrainian Karbovanet1.00",
6080        "Colombian Real Value Uni1.00",
6081        "United Arab Emirates Dirha1.00",
6082        "Unknown Currenc1.00",
6083        "Ur1.00",
6084        "Uruguay Peso (1975\\u201319931.00",
6085        "Uruguay Peso Uruguay1.00",
6086        "Uruguay Peso (Indexed Units1.00",
6087        "Uzbekistan So1.00",
6088        "V1.00",
6089        "VE1.00",
6090        "VN1.00",
6091        "VU1.00",
6092        "Vanuatu Vat1.00",
6093        "Venezuelan Bol\\u00edva1.00",
6094        "Venezuelan Bol\\u00edvar Fuert1.00",
6095        "Vietnamese Don1.00",
6096        "WIR Eur1.00",
6097        "WIR Fran1.00",
6098        "WS1.00",
6099        "Samoa Tal1.00",
6100        "XA1.00",
6101        "XB1.00",
6102        "XC1.00",
6103        "XD1.00",
6104        "XE1.00",
6105        "XF1.00",
6106        "XO1.00",
6107        "XP1.00",
6108        "XR1.00",
6109        "XT1.00",
6110        "XX1.00",
6111        "YD1.00",
6112        "YE1.00",
6113        "YU1.00",
6114        "Yemeni Dina1.00",
6115        "Yemeni Ria1.00",
6116        "Yugoslavian Convertible Dina1.00",
6117        "Yugoslavian Hard Dinar (1966\\u201319901.00",
6118        "Yugoslavian New Dina1.00",
6119        "Z1.00",
6120        "ZA1.00",
6121        "ZM1.00",
6122        "ZR1.00",
6123        "ZW1.00",
6124        "Zairean New Zaire (1993\\u201319981.00",
6125        "Zairean Zair1.00",
6126        "Zambian Kwach1.00",
6127        "Zimbabwean Dollar (1980\\u201320081.00",
6128        "dra1.00",
6129        "lar1.00",
6130        "le1.00",
6131        "man1.00",
6132        "so1.00",
6133    };
6134
6135    Locale locale("en_US");
6136    for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) {
6137      UnicodeString formatted = ctou(DATA[i]);
6138      UErrorCode status = U_ZERO_ERROR;
6139      NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6140      if (numFmt != NULL && U_SUCCESS(status)) {
6141          ParsePosition parsePos;
6142          LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6143          if (parsePos.getIndex() > 0) {
6144              double doubleVal = currAmt->getNumber().getDouble(status);
6145              if ( doubleVal != 1.0 ) {
6146                  errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal);
6147              }
6148          } else {
6149              errln("Failed to parse as currency: " + formatted);
6150          }
6151      } else {
6152          dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6153          delete numFmt;
6154          break;
6155      }
6156      delete numFmt;
6157    }
6158
6159    for (uint32_t i=0; i<sizeof(WRONG_DATA)/sizeof(WRONG_DATA[0]); ++i) {
6160      UnicodeString formatted = ctou(WRONG_DATA[i]);
6161      UErrorCode status = U_ZERO_ERROR;
6162      NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6163      if (numFmt != NULL && U_SUCCESS(status)) {
6164          ParsePosition parsePos;
6165          LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6166          if (parsePos.getIndex() > 0) {
6167              double doubleVal = currAmt->getNumber().getDouble(status);
6168              errln("Parsed as currency, should not have: " + formatted + " -> " + doubleVal);
6169          }
6170      } else {
6171          dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6172          delete numFmt;
6173          break;
6174      }
6175      delete numFmt;
6176    }
6177}
6178
6179const char* attrString(int32_t);
6180
6181// UnicodeString s;
6182//  std::string ss;
6183//  std::cout << s.toUTF8String(ss)
6184void NumberFormatTest::expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount,
6185                                       const UnicodeString& str)  {
6186  UBool found[10];
6187  FieldPosition fp;
6188
6189  if (tupleCount > 10) {
6190    assertTrue("internal error, tupleCount too large", FALSE);
6191  } else {
6192    for (int i = 0; i < tupleCount; ++i) {
6193      found[i] = FALSE;
6194    }
6195  }
6196
6197  logln(str);
6198  while (iter.next(fp)) {
6199    UBool ok = FALSE;
6200    int32_t id = fp.getField();
6201    int32_t start = fp.getBeginIndex();
6202    int32_t limit = fp.getEndIndex();
6203
6204    // is there a logln using printf?
6205    char buf[128];
6206    sprintf(buf, "%24s %3d %3d %3d", attrString(id), id, start, limit);
6207    logln(buf);
6208
6209    for (int i = 0; i < tupleCount; ++i) {
6210      if (found[i]) {
6211        continue;
6212      }
6213      if (values[i*3] == id &&
6214          values[i*3+1] == start &&
6215          values[i*3+2] == limit) {
6216        found[i] = ok = TRUE;
6217        break;
6218      }
6219    }
6220
6221    assertTrue((UnicodeString)"found [" + id + "," + start + "," + limit + "]", ok);
6222  }
6223
6224  // check that all were found
6225  UBool ok = TRUE;
6226  for (int i = 0; i < tupleCount; ++i) {
6227    if (!found[i]) {
6228      ok = FALSE;
6229      assertTrue((UnicodeString) "missing [" + values[i*3] + "," + values[i*3+1] + "," + values[i*3+2] + "]", found[i]);
6230    }
6231  }
6232  assertTrue("no expected values were missing", ok);
6233}
6234
6235void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit,
6236                                       const UnicodeString& str)  {
6237  logln(str);
6238  assertTrue((UnicodeString)"id " + id + " == " + pos.getField(), id == pos.getField());
6239  assertTrue((UnicodeString)"begin " + start + " == " + pos.getBeginIndex(), start == pos.getBeginIndex());
6240  assertTrue((UnicodeString)"end " + limit + " == " + pos.getEndIndex(), limit == pos.getEndIndex());
6241}
6242
6243void NumberFormatTest::TestFieldPositionIterator() {
6244  // bug 7372
6245  UErrorCode status = U_ZERO_ERROR;
6246  FieldPositionIterator iter1;
6247  FieldPositionIterator iter2;
6248  FieldPosition pos;
6249
6250  DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(status);
6251  if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6252
6253  double num = 1234.56;
6254  UnicodeString str1;
6255  UnicodeString str2;
6256
6257  assertTrue((UnicodeString)"self==", iter1 == iter1);
6258  assertTrue((UnicodeString)"iter1==iter2", iter1 == iter2);
6259
6260  decFmt->format(num, str1, &iter1, status);
6261  assertTrue((UnicodeString)"iter1 != iter2", iter1 != iter2);
6262  decFmt->format(num, str2, &iter2, status);
6263  assertTrue((UnicodeString)"iter1 == iter2 (2)", iter1 == iter2);
6264  iter1.next(pos);
6265  assertTrue((UnicodeString)"iter1 != iter2 (2)", iter1 != iter2);
6266  iter2.next(pos);
6267  assertTrue((UnicodeString)"iter1 == iter2 (3)", iter1 == iter2);
6268
6269  // should format ok with no iterator
6270  str2.remove();
6271  decFmt->format(num, str2, NULL, status);
6272  assertEquals("null fpiter", str1, str2);
6273
6274  delete decFmt;
6275}
6276
6277void NumberFormatTest::TestFormatAttributes() {
6278  Locale locale("en_US");
6279  UErrorCode status = U_ZERO_ERROR;
6280  DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6281    if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6282  double val = 12345.67;
6283
6284  {
6285    int32_t expected[] = {
6286      UNUM_CURRENCY_FIELD, 0, 1,
6287      UNUM_GROUPING_SEPARATOR_FIELD, 3, 4,
6288      UNUM_INTEGER_FIELD, 1, 7,
6289      UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8,
6290      UNUM_FRACTION_FIELD, 8, 10,
6291    };
6292    int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
6293
6294    FieldPositionIterator posIter;
6295    UnicodeString result;
6296    decFmt->format(val, result, &posIter, status);
6297    expectPositions(posIter, expected, tupleCount, result);
6298  }
6299  {
6300    FieldPosition fp(UNUM_INTEGER_FIELD);
6301    UnicodeString result;
6302    decFmt->format(val, result, fp);
6303    expectPosition(fp, UNUM_INTEGER_FIELD, 1, 7, result);
6304  }
6305  {
6306    FieldPosition fp(UNUM_FRACTION_FIELD);
6307    UnicodeString result;
6308    decFmt->format(val, result, fp);
6309    expectPosition(fp, UNUM_FRACTION_FIELD, 8, 10, result);
6310  }
6311  delete decFmt;
6312
6313  decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_SCIENTIFIC, status);
6314  val = -0.0000123;
6315  {
6316    int32_t expected[] = {
6317      UNUM_SIGN_FIELD, 0, 1,
6318      UNUM_INTEGER_FIELD, 1, 2,
6319      UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3,
6320      UNUM_FRACTION_FIELD, 3, 5,
6321      UNUM_EXPONENT_SYMBOL_FIELD, 5, 6,
6322      UNUM_EXPONENT_SIGN_FIELD, 6, 7,
6323      UNUM_EXPONENT_FIELD, 7, 8
6324    };
6325    int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
6326
6327    FieldPositionIterator posIter;
6328    UnicodeString result;
6329    decFmt->format(val, result, &posIter, status);
6330    expectPositions(posIter, expected, tupleCount, result);
6331  }
6332  {
6333    FieldPosition fp(UNUM_INTEGER_FIELD);
6334    UnicodeString result;
6335    decFmt->format(val, result, fp);
6336    expectPosition(fp, UNUM_INTEGER_FIELD, 1, 2, result);
6337  }
6338  {
6339    FieldPosition fp(UNUM_FRACTION_FIELD);
6340    UnicodeString result;
6341    decFmt->format(val, result, fp);
6342    expectPosition(fp, UNUM_FRACTION_FIELD, 3, 5, result);
6343  }
6344  delete decFmt;
6345
6346  fflush(stderr);
6347}
6348
6349const char* attrString(int32_t attrId) {
6350  switch (attrId) {
6351    case UNUM_INTEGER_FIELD: return "integer";
6352    case UNUM_FRACTION_FIELD: return "fraction";
6353    case UNUM_DECIMAL_SEPARATOR_FIELD: return "decimal separator";
6354    case UNUM_EXPONENT_SYMBOL_FIELD: return "exponent symbol";
6355    case UNUM_EXPONENT_SIGN_FIELD: return "exponent sign";
6356    case UNUM_EXPONENT_FIELD: return "exponent";
6357    case UNUM_GROUPING_SEPARATOR_FIELD: return "grouping separator";
6358    case UNUM_CURRENCY_FIELD: return "currency";
6359    case UNUM_PERCENT_FIELD: return "percent";
6360    case UNUM_PERMILL_FIELD: return "permille";
6361    case UNUM_SIGN_FIELD: return "sign";
6362    default: return "";
6363  }
6364}
6365
6366//
6367//   Test formatting & parsing of big decimals.
6368//      API test, not a comprehensive test.
6369//      See DecimalFormatTest/DataDrivenTests
6370//
6371#define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \
6372                                                __FILE__, __LINE__, u_errorName(status));}
6373#define ASSERT_EQUALS(expected, actual) {if ((expected) != (actual)) \
6374                  errln("file %s, line %d: %s != %s", __FILE__, __LINE__, #expected, #actual);}
6375
6376static UBool operator != (const char *s1, UnicodeString &s2) {
6377    // This function lets ASSERT_EQUALS("literal", UnicodeString) work.
6378    UnicodeString us1(s1);
6379    return us1 != s2;
6380}
6381
6382void NumberFormatTest::TestDecimal() {
6383    {
6384        UErrorCode  status = U_ZERO_ERROR;
6385        Formattable f("12.345678999987654321E666", status);
6386        ASSERT_SUCCESS(status);
6387        StringPiece s = f.getDecimalNumber(status);
6388        ASSERT_SUCCESS(status);
6389        ASSERT_EQUALS("1.2345678999987654321E+667", s);
6390        //printf("%s\n", s.data());
6391    }
6392
6393    {
6394        UErrorCode status = U_ZERO_ERROR;
6395        Formattable f1("this is not a number", status);
6396        ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR, status);
6397    }
6398
6399    {
6400        UErrorCode status = U_ZERO_ERROR;
6401        Formattable f;
6402        f.setDecimalNumber("123.45", status);
6403        ASSERT_SUCCESS(status);
6404        ASSERT_EQUALS( Formattable::kDouble, f.getType());
6405        ASSERT_EQUALS(123.45, f.getDouble());
6406        ASSERT_EQUALS(123.45, f.getDouble(status));
6407        ASSERT_SUCCESS(status);
6408        ASSERT_EQUALS("123.45", f.getDecimalNumber(status));
6409        ASSERT_SUCCESS(status);
6410
6411        f.setDecimalNumber("4.5678E7", status);
6412        int32_t n;
6413        n = f.getLong();
6414        ASSERT_EQUALS(45678000, n);
6415
6416        status = U_ZERO_ERROR;
6417        f.setDecimalNumber("-123", status);
6418        ASSERT_SUCCESS(status);
6419        ASSERT_EQUALS( Formattable::kLong, f.getType());
6420        ASSERT_EQUALS(-123, f.getLong());
6421        ASSERT_EQUALS(-123, f.getLong(status));
6422        ASSERT_SUCCESS(status);
6423        ASSERT_EQUALS("-123", f.getDecimalNumber(status));
6424        ASSERT_SUCCESS(status);
6425
6426        status = U_ZERO_ERROR;
6427        f.setDecimalNumber("1234567890123", status);  // Number too big for 32 bits
6428        ASSERT_SUCCESS(status);
6429        ASSERT_EQUALS( Formattable::kInt64, f.getType());
6430        ASSERT_EQUALS(1234567890123LL, f.getInt64());
6431        ASSERT_EQUALS(1234567890123LL, f.getInt64(status));
6432        ASSERT_SUCCESS(status);
6433        ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status));
6434        ASSERT_SUCCESS(status);
6435    }
6436
6437    {
6438        UErrorCode status = U_ZERO_ERROR;
6439        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6440        if (U_FAILURE(status) || fmtr == NULL) {
6441            dataerrln("Unable to create NumberFormat");
6442        } else {
6443            UnicodeString formattedResult;
6444            StringPiece num("244444444444444444444444444444444444446.4");
6445            fmtr->format(num, formattedResult, NULL, status);
6446            ASSERT_SUCCESS(status);
6447            ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult);
6448            //std::string ss; std::cout << formattedResult.toUTF8String(ss);
6449            delete fmtr;
6450        }
6451    }
6452
6453    {
6454        // Check formatting a DigitList.  DigitList is internal, but this is
6455        // a critical interface that must work.
6456        UErrorCode status = U_ZERO_ERROR;
6457        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6458        if (U_FAILURE(status) || fmtr == NULL) {
6459            dataerrln("Unable to create NumberFormat");
6460        } else {
6461            UnicodeString formattedResult;
6462            DigitList dl;
6463            StringPiece num("123.4566666666666666666666666666666666621E+40");
6464            dl.set(num, status);
6465            ASSERT_SUCCESS(status);
6466            fmtr->format(dl, formattedResult, NULL, status);
6467            ASSERT_SUCCESS(status);
6468            ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult);
6469
6470            status = U_ZERO_ERROR;
6471            num.set("666.666");
6472            dl.set(num, status);
6473            FieldPosition pos(NumberFormat::FRACTION_FIELD);
6474            ASSERT_SUCCESS(status);
6475            formattedResult.remove();
6476            fmtr->format(dl, formattedResult, pos, status);
6477            ASSERT_SUCCESS(status);
6478            ASSERT_EQUALS("666.666", formattedResult);
6479            ASSERT_EQUALS(4, pos.getBeginIndex());
6480            ASSERT_EQUALS(7, pos.getEndIndex());
6481            delete fmtr;
6482        }
6483    }
6484
6485    {
6486        // Check a parse with a formatter with a multiplier.
6487        UErrorCode status = U_ZERO_ERROR;
6488        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT, status);
6489        if (U_FAILURE(status) || fmtr == NULL) {
6490            dataerrln("Unable to create NumberFormat");
6491        } else {
6492            UnicodeString input = "1.84%";
6493            Formattable result;
6494            fmtr->parse(input, result, status);
6495            ASSERT_SUCCESS(status);
6496            ASSERT_EQUALS(0, strcmp("0.0184", result.getDecimalNumber(status).data()));
6497            //std::cout << result.getDecimalNumber(status).data();
6498            delete fmtr;
6499        }
6500    }
6501
6502#if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6503    /*
6504     * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6505     * See #9463
6506     */
6507    {
6508        // Check that a parse returns a decimal number with full accuracy
6509        UErrorCode status = U_ZERO_ERROR;
6510        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6511        if (U_FAILURE(status) || fmtr == NULL) {
6512            dataerrln("Unable to create NumberFormat");
6513        } else {
6514            UnicodeString input = "1.002200044400088880000070000";
6515            Formattable result;
6516            fmtr->parse(input, result, status);
6517            ASSERT_SUCCESS(status);
6518            ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result.getDecimalNumber(status).data()));
6519            ASSERT_EQUALS(1.00220004440008888,   result.getDouble());
6520            //std::cout << result.getDecimalNumber(status).data();
6521            delete fmtr;
6522        }
6523    }
6524#endif
6525
6526}
6527
6528void NumberFormatTest::TestCurrencyFractionDigits() {
6529    UErrorCode status = U_ZERO_ERROR;
6530    UnicodeString text1, text2;
6531    double value = 99.12345;
6532
6533    // Create currenct instance
6534    NumberFormat* fmt = NumberFormat::createCurrencyInstance("ja_JP", status);
6535    if (U_FAILURE(status) || fmt == NULL) {
6536        dataerrln("Unable to create NumberFormat");
6537    } else {
6538        fmt->format(value, text1);
6539
6540        // Reset the same currency and format the test value again
6541        fmt->setCurrency(fmt->getCurrency(), status);
6542        ASSERT_SUCCESS(status);
6543        fmt->format(value, text2);
6544
6545        if (text1 != text2) {
6546            errln((UnicodeString)"NumberFormat::format() should return the same result - text1="
6547                + text1 + " text2=" + text2);
6548        }
6549        delete fmt;
6550    }
6551}
6552
6553void NumberFormatTest::TestExponentParse() {
6554
6555    UErrorCode status = U_ZERO_ERROR;
6556    Formattable result;
6557    ParsePosition parsePos(0);
6558
6559    // set the exponent symbol
6560    status = U_ZERO_ERROR;
6561    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status);
6562    if(U_FAILURE(status)) {
6563        dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)");
6564        return;
6565    }
6566
6567    // create format instance
6568    status = U_ZERO_ERROR;
6569    DecimalFormat fmt("#####", symbols, status);
6570    if(U_FAILURE(status)) {
6571        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
6572    }
6573
6574    // parse the text
6575    fmt.parse("5.06e-27", result, parsePos);
6576    if(result.getType() != Formattable::kDouble &&
6577       result.getDouble() != 5.06E-27 &&
6578       parsePos.getIndex() != 8
6579       )
6580    {
6581        errln("ERROR: parse failed - expected 5.06E-27, 8  - returned %d, %i",
6582              result.getDouble(), parsePos.getIndex());
6583    }
6584}
6585
6586void NumberFormatTest::TestExplicitParents() {
6587
6588    /* Test that number formats are properly inherited from es_419 */
6589    /* These could be subject to change if the CLDR data changes */
6590    static const char* parentLocaleTests[][2]= {
6591    /* locale ID */  /* expected */
6592    {"es_CO", "1.250,75" },
6593    {"es_CR", "1.250,75" },
6594    {"es_ES", "1.250,75" },
6595    {"es_GQ", "1.250,75" },
6596    {"es_MX", "1,250.75" },
6597    {"es_US", "1,250.75" },
6598    {"es_VE", "1.250,75" },
6599    };
6600
6601    UnicodeString s;
6602
6603    for(int i=0; i < (int)(sizeof(parentLocaleTests)/sizeof(parentLocaleTests[i])); i++){
6604        UErrorCode status = U_ZERO_ERROR;
6605        const char *localeID = parentLocaleTests[i][0];
6606        UnicodeString expected(parentLocaleTests[i][1], -1, US_INV);
6607        expected = expected.unescape();
6608        char loc[256]={0};
6609        uloc_canonicalize(localeID, loc, 256, &status);
6610        NumberFormat *fmt= NumberFormat::createInstance(Locale(loc), status);
6611        if(U_FAILURE(status)){
6612            dataerrln("Could not create number formatter for locale %s - %s",localeID, u_errorName(status));
6613            continue;
6614        }
6615        s.remove();
6616        fmt->format(1250.75, s);
6617        if(s!=expected){
6618            errln(UnicodeString("FAIL: Expected: ")+expected
6619                    + UnicodeString(" Got: ") + s
6620                    + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
6621        }
6622        if (U_FAILURE(status)){
6623            errln((UnicodeString)"FAIL: Status " + (int32_t)status);
6624        }
6625        delete fmt;
6626    }
6627
6628}
6629
6630/**
6631 * Test available numbering systems API.
6632 */
6633void NumberFormatTest::TestAvailableNumberingSystems() {
6634    UErrorCode status = U_ZERO_ERROR;
6635    StringEnumeration *availableNumberingSystems = NumberingSystem::getAvailableNames(status);
6636    CHECK_DATA(status, "NumberingSystem::getAvailableNames()")
6637
6638    int32_t nsCount = availableNumberingSystems->count(status);
6639    if ( nsCount < 36 ) {
6640        errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 36, got %d",nsCount);
6641    }
6642
6643    /* A relatively simple test of the API.  We call getAvailableNames() and cycle through */
6644    /* each name returned, attempting to create a numbering system based on that name and  */
6645    /* verifying that the name returned from the resulting numbering system is the same    */
6646    /* one that we initially thought.                                                      */
6647
6648    int32_t len;
6649    for ( int32_t i = 0 ; i < nsCount ; i++ ) {
6650        const char *nsname = availableNumberingSystems->next(&len,status);
6651        NumberingSystem* ns = NumberingSystem::createInstanceByName(nsname,status);
6652        if ( uprv_strcmp(nsname,ns->getName()) ) {
6653            errln("FAIL: Numbering system name didn't match for name = %s\n",nsname);
6654        }
6655
6656        delete ns;
6657    }
6658
6659    delete availableNumberingSystems;
6660}
6661
6662void
6663NumberFormatTest::Test9087(void)
6664{
6665    U_STRING_DECL(pattern,"#",1);
6666    U_STRING_INIT(pattern,"#",1);
6667
6668    U_STRING_DECL(infstr,"INF",3);
6669    U_STRING_INIT(infstr,"INF",3);
6670
6671    U_STRING_DECL(nanstr,"NAN",3);
6672    U_STRING_INIT(nanstr,"NAN",3);
6673
6674    UChar outputbuf[50] = {0};
6675    UErrorCode status = U_ZERO_ERROR;
6676    UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status);
6677    if ( U_FAILURE(status) ) {
6678        dataerrln("FAIL: error in unum_open() - %s", u_errorName(status));
6679        return;
6680    }
6681
6682    unum_setSymbol(fmt,UNUM_INFINITY_SYMBOL,infstr,3,&status);
6683    unum_setSymbol(fmt,UNUM_NAN_SYMBOL,nanstr,3,&status);
6684    if ( U_FAILURE(status) ) {
6685        errln("FAIL: error setting symbols");
6686    }
6687
6688    double inf = uprv_getInfinity();
6689
6690    unum_setAttribute(fmt,UNUM_ROUNDING_MODE,UNUM_ROUND_HALFEVEN);
6691    unum_setDoubleAttribute(fmt,UNUM_ROUNDING_INCREMENT,0);
6692
6693    UFieldPosition position = { 0, 0, 0};
6694    unum_formatDouble(fmt,inf,outputbuf,50,&position,&status);
6695
6696    if ( u_strcmp(infstr, outputbuf)) {
6697        errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf);
6698    }
6699
6700    unum_close(fmt);
6701}
6702
6703#include "dcfmtimp.h"
6704
6705void NumberFormatTest::TestFormatFastpaths() {
6706#if UCONFIG_FORMAT_FASTPATHS_49
6707    logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
6708        sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
6709    if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
6710        errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
6711    } else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
6712        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));
6713    }
6714#else
6715    infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
6716#endif
6717
6718    // get some additional case
6719    {
6720        UErrorCode status=U_ZERO_ERROR;
6721        DecimalFormat df(UnicodeString("0000",""),status);
6722        int64_t long_number = 1;
6723        UnicodeString expect = "0001";
6724        UnicodeString result;
6725        FieldPosition pos;
6726        df.format(long_number, result, pos);
6727        if(U_FAILURE(status)||expect!=result) {
6728            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
6729        } else {
6730            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
6731        }
6732    }
6733    {
6734        UErrorCode status=U_ZERO_ERROR;
6735        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6736        int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
6737        // uint8_t bits[8];
6738        // memcpy(bits,&long_number,8);
6739        // for(int i=0;i<8;i++) {
6740        //   logln("bits: %02X", (unsigned int)bits[i]);
6741        // }
6742        UnicodeString expect = "-9223372036854775808";
6743        UnicodeString result;
6744        FieldPosition pos;
6745        df.format(long_number, result, pos);
6746        if(U_FAILURE(status)||expect!=result) {
6747            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
6748        } else {
6749            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
6750        }
6751    }
6752    {
6753        UErrorCode status=U_ZERO_ERROR;
6754        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6755        int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
6756        // uint8_t bits[8];
6757        // memcpy(bits,&long_number,8);
6758        // for(int i=0;i<8;i++) {
6759        //   logln("bits: %02X", (unsigned int)bits[i]);
6760        // }
6761        UnicodeString expect = "9223372036854775807";
6762        UnicodeString result;
6763        FieldPosition pos;
6764        df.format(long_number, result, pos);
6765        if(U_FAILURE(status)||expect!=result) {
6766            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
6767        } else {
6768            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
6769        }
6770    }
6771    {
6772        UErrorCode status=U_ZERO_ERROR;
6773        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6774        int64_t long_number = 0;
6775        // uint8_t bits[8];
6776        // memcpy(bits,&long_number,8);
6777        // for(int i=0;i<8;i++) {
6778        //   logln("bits: %02X", (unsigned int)bits[i]);
6779        // }
6780        UnicodeString expect = "0000000000000000000";
6781        UnicodeString result;
6782        FieldPosition pos;
6783        df.format(long_number, result, pos);
6784        if(U_FAILURE(status)||expect!=result) {
6785            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
6786        } else {
6787            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
6788        }
6789    }
6790    {
6791        UErrorCode status=U_ZERO_ERROR;
6792        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6793        int64_t long_number = U_INT64_MIN + 1;
6794        UnicodeString expect = "-9223372036854775807";
6795        UnicodeString result;
6796        FieldPosition pos;
6797        df.format(long_number, result, pos);
6798        if(U_FAILURE(status)||expect!=result) {
6799            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
6800        } else {
6801            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
6802        }
6803    }
6804}
6805
6806
6807void NumberFormatTest::TestFormattableSize(void) {
6808  if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) {
6809    errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6810          sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6811  } else if(sizeof(FmtStackData) < UNUM_INTERNAL_STACKARRAY_SIZE) {
6812    logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6813        sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6814  } else {
6815    logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6816        sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6817  }
6818}
6819
6820UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line, Formattable &f) {
6821  UnicodeString fileLine = UnicodeString(file)+UnicodeString(":")+line+UnicodeString(": ");
6822
6823  UFormattable *u = f.toUFormattable();
6824  logln();
6825  if (u == NULL) {
6826    errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
6827    return FALSE;
6828  }
6829  logln("%s:%d: comparing Formattable with UFormattable", file, line);
6830  logln(fileLine + toString(f));
6831
6832  UErrorCode status = U_ZERO_ERROR;
6833  UErrorCode valueStatus = U_ZERO_ERROR;
6834  UFormattableType expectUType = UFMT_COUNT; // invalid
6835
6836  UBool triedExact = FALSE; // did we attempt an exact comparison?
6837  UBool exactMatch = FALSE; // was the exact comparison true?
6838
6839  switch( f.getType() ) {
6840  case Formattable::kDate:
6841    expectUType = UFMT_DATE;
6842    exactMatch = (f.getDate()==ufmt_getDate(u, &valueStatus));
6843    triedExact = TRUE;
6844    break;
6845  case Formattable::kDouble:
6846    expectUType = UFMT_DOUBLE;
6847    exactMatch = (f.getDouble()==ufmt_getDouble(u, &valueStatus));
6848    triedExact = TRUE;
6849    break;
6850  case Formattable::kLong:
6851    expectUType = UFMT_LONG;
6852    exactMatch = (f.getLong()==ufmt_getLong(u, &valueStatus));
6853    triedExact = TRUE;
6854    break;
6855  case Formattable::kString:
6856    expectUType = UFMT_STRING;
6857    {
6858      UnicodeString str;
6859      f.getString(str);
6860      int32_t len;
6861      const UChar* uch = ufmt_getUChars(u, &len, &valueStatus);
6862      if(U_SUCCESS(valueStatus)) {
6863        UnicodeString str2(uch, len);
6864        assertTrue("UChar* NULL-terminated", uch[len]==0);
6865        exactMatch = (str == str2);
6866      }
6867      triedExact = TRUE;
6868    }
6869    break;
6870  case Formattable::kArray:
6871    expectUType = UFMT_ARRAY;
6872    triedExact = TRUE;
6873    {
6874      int32_t count = ufmt_getArrayLength(u, &valueStatus);
6875      int32_t count2;
6876      const Formattable *array2 = f.getArray(count2);
6877      exactMatch = assertEquals(fileLine + " array count", count, count2);
6878
6879      if(exactMatch) {
6880        for(int i=0;U_SUCCESS(valueStatus) && i<count;i++) {
6881          UFormattable *uu = ufmt_getArrayItemByIndex(u, i, &valueStatus);
6882          if(*Formattable::fromUFormattable(uu) != (array2[i])) {
6883            errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file, line, i,
6884                  (const void*)Formattable::fromUFormattable(uu), (const void*)&(array2[i]));
6885            exactMatch = FALSE;
6886          } else {
6887            if(!testFormattableAsUFormattable("(sub item)",i,*Formattable::fromUFormattable(uu))) {
6888              exactMatch = FALSE;
6889            }
6890          }
6891        }
6892      }
6893    }
6894    break;
6895  case Formattable::kInt64:
6896    expectUType = UFMT_INT64;
6897    exactMatch = (f.getInt64()==ufmt_getInt64(u, &valueStatus));
6898    triedExact = TRUE;
6899    break;
6900  case Formattable::kObject:
6901    expectUType = UFMT_OBJECT;
6902    exactMatch = (f.getObject()==ufmt_getObject(u, &valueStatus));
6903    triedExact = TRUE;
6904    break;
6905  }
6906  UFormattableType uType = ufmt_getType(u, &status);
6907
6908  if(U_FAILURE(status)) {
6909    errln("%s:%d: Error calling ufmt_getType - %s", file, line, u_errorName(status));
6910    return FALSE;
6911  }
6912
6913  if(uType != expectUType) {
6914    errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file, line, (int) uType, (int) expectUType);
6915  }
6916
6917  if(triedExact) {
6918    if(U_FAILURE(valueStatus)) {
6919      errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file, line, u_errorName(valueStatus));
6920    } else if(!exactMatch) {
6921     errln("%s:%d: failed exact match for the Formattable type", file, line);
6922    } else {
6923      logln("%s:%d: exact match OK", file, line);
6924    }
6925  } else {
6926    logln("%s:%d: note, did not attempt exact match for this formattable type", file, line);
6927  }
6928
6929  if( assertEquals(fileLine + " isNumeric()", f.isNumeric(), ufmt_isNumeric(u))
6930      && f.isNumeric()) {
6931    UErrorCode convStatus = U_ZERO_ERROR;
6932
6933    if(uType != UFMT_INT64) { // may fail to compare
6934      assertTrue(fileLine + " as doubles ==", f.getDouble(convStatus)==ufmt_getDouble(u, &convStatus));
6935    }
6936
6937    if( assertSuccess(fileLine + " (numeric conversion status)", convStatus) ) {
6938      StringPiece fDecNum = f.getDecimalNumber(convStatus);
6939#if 1
6940      int32_t len;
6941      const char *decNumChars = ufmt_getDecNumChars(u, &len, &convStatus);
6942#else
6943      // copy version
6944      char decNumChars[200];
6945      int32_t len = ufmt_getDecNumChars(u, decNumChars, 200, &convStatus);
6946#endif
6947
6948      if( assertSuccess(fileLine + " (decNumbers conversion)", convStatus) ) {
6949        logln(fileLine + decNumChars);
6950        assertEquals(fileLine + " decNumChars length==", len, fDecNum.length());
6951        assertEquals(fileLine + " decNumChars digits", decNumChars, fDecNum.data());
6952      }
6953
6954      UErrorCode int64ConversionF = U_ZERO_ERROR;
6955      int64_t l = f.getInt64(int64ConversionF);
6956      UErrorCode int64ConversionU = U_ZERO_ERROR;
6957      int64_t r = ufmt_getInt64(u, &int64ConversionU);
6958
6959      if( (l==r)
6960          && ( uType != UFMT_INT64 ) // int64 better not overflow
6961          && (U_INVALID_FORMAT_ERROR==int64ConversionU)
6962          && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) {
6963        logln("%s:%d: OK: 64 bit overflow", file, line);
6964      } else {
6965        assertEquals(fileLine + " as int64 ==", l, r);
6966        assertSuccess(fileLine + " Formattable.getnt64()", int64ConversionF);
6967        assertSuccess(fileLine + " ufmt_getInt64()", int64ConversionU);
6968      }
6969    }
6970  }
6971  return exactMatch || !triedExact;
6972}
6973
6974void NumberFormatTest::TestUFormattable(void) {
6975  {
6976    // test that a default formattable is equal to Formattable()
6977    UErrorCode status = U_ZERO_ERROR;
6978    LocalUFormattablePointer defaultUFormattable(ufmt_open(&status));
6979    assertSuccess("calling umt_open", status);
6980    Formattable defaultFormattable;
6981    assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
6982               (defaultFormattable
6983                == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
6984    assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
6985               (defaultFormattable
6986                == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
6987    assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable",
6988               (defaultFormattable
6989                == *(Formattable::fromUFormattable(defaultFormattable.toUFormattable()))));
6990    assertTrue((UnicodeString)"comparing &Formattable() round tripped through UFormattable",
6991               ((&defaultFormattable)
6992                == Formattable::fromUFormattable(defaultFormattable.toUFormattable())));
6993    assertFalse((UnicodeString)"comparing &Formattable() with ufmt_open()",
6994               ((&defaultFormattable)
6995                == Formattable::fromUFormattable(defaultUFormattable.getAlias())));
6996    testFormattableAsUFormattable(__FILE__, __LINE__, defaultFormattable);
6997  }
6998  // test some random Formattables
6999  {
7000    Formattable f(ucal_getNow(), Formattable::kIsDate);
7001    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7002  }
7003  {
7004    Formattable f((double)1.61803398874989484820); // golden ratio
7005    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7006  }
7007  {
7008    Formattable f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
7009    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7010  }
7011  {
7012    Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/
7013    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7014  }
7015  {
7016    Formattable f("Hello world."); // should be invariant?
7017    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7018  }
7019  {
7020    UErrorCode status2 = U_ZERO_ERROR;
7021    Formattable f(StringPiece("73476730924573500000000.0"), status2); // weight of the moon, kg
7022    assertSuccess("Constructing a StringPiece", status2);
7023    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7024  }
7025  {
7026    UErrorCode status2 = U_ZERO_ERROR;
7027    UObject *obj = new Locale();
7028    Formattable f(obj);
7029    assertSuccess("Constructing a Formattable from a default constructed Locale()", status2);
7030    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
7031  }
7032  {
7033    const Formattable array[] = {
7034      Formattable(ucal_getNow(), Formattable::kIsDate),
7035      Formattable((int32_t)4),
7036      Formattable((double)1.234),
7037    };
7038
7039    Formattable fa(array, 3);
7040    testFormattableAsUFormattable(__FILE__, __LINE__, fa);
7041  }
7042}
7043
7044void NumberFormatTest::TestSignificantDigits(void) {
7045  double input[] = {
7046        0, 0,
7047        0.1, -0.1,
7048        123, -123,
7049        12345, -12345,
7050        123.45, -123.45,
7051        123.44501, -123.44501,
7052        0.001234, -0.001234,
7053        0.00000000123, -0.00000000123,
7054        0.0000000000000000000123, -0.0000000000000000000123,
7055        1.2, -1.2,
7056        0.0000000012344501, -0.0000000012344501,
7057        123445.01, -123445.01,
7058        12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
7059    };
7060    const char* expected[] = {
7061        "0.00", "0.00",
7062        "0.100", "-0.100",
7063        "123", "-123",
7064        "12345", "-12345",
7065        "123.45", "-123.45",
7066        "123.45", "-123.45",
7067        "0.001234", "-0.001234",
7068        "0.00000000123", "-0.00000000123",
7069        "0.0000000000000000000123", "-0.0000000000000000000123",
7070        "1.20", "-1.20",
7071        "0.0000000012345", "-0.0000000012345",
7072        "123450", "-123450",
7073        "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
7074    };
7075
7076    UErrorCode status = U_ZERO_ERROR;
7077    Locale locale("en_US");
7078    LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7079            NumberFormat::createInstance(locale, status)));
7080    CHECK_DATA(status,"NumberFormat::createInstance")
7081
7082    numberFormat->setSignificantDigitsUsed(TRUE);
7083    numberFormat->setMinimumSignificantDigits(3);
7084    numberFormat->setMaximumSignificantDigits(5);
7085    numberFormat->setGroupingUsed(false);
7086
7087    UnicodeString result;
7088    UnicodeString expectedResult;
7089    for (unsigned int i = 0; i < sizeof(input)/sizeof(double); ++i) {
7090        numberFormat->format(input[i], result);
7091        UnicodeString expectedResult(expected[i]);
7092        if (result != expectedResult) {
7093          errln((UnicodeString)"Expected: '" + expectedResult + "' got '" + result);
7094        }
7095        result.remove();
7096    }
7097}
7098
7099void NumberFormatTest::TestShowZero() {
7100    UErrorCode status = U_ZERO_ERROR;
7101    Locale locale("en_US");
7102    LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7103            NumberFormat::createInstance(locale, status)));
7104    CHECK_DATA(status, "NumberFormat::createInstance")
7105
7106    numberFormat->setSignificantDigitsUsed(TRUE);
7107    numberFormat->setMaximumSignificantDigits(3);
7108
7109    UnicodeString result;
7110    numberFormat->format(0.0, result);
7111    if (result != "0") {
7112        errln((UnicodeString)"Expected: 0, got " + result);
7113    }
7114}
7115
7116void NumberFormatTest::TestBug9936() {
7117    UErrorCode status = U_ZERO_ERROR;
7118    Locale locale("en_US");
7119    LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>(
7120            NumberFormat::createInstance(locale, status)));
7121    if (U_FAILURE(status)) {
7122        dataerrln("File %s, Line %d: status = %s.\n", __FILE__, __LINE__, u_errorName(status));
7123        return;
7124    }
7125
7126    if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7127        errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7128    }
7129    numberFormat->setSignificantDigitsUsed(TRUE);
7130    if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7131        errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7132    }
7133
7134    numberFormat->setSignificantDigitsUsed(FALSE);
7135    if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7136        errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7137    }
7138
7139    numberFormat->setMinimumSignificantDigits(3);
7140    if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7141        errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7142    }
7143
7144    numberFormat->setSignificantDigitsUsed(FALSE);
7145    numberFormat->setMaximumSignificantDigits(6);
7146    if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7147        errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7148    }
7149
7150}
7151
7152void NumberFormatTest::TestParseNegativeWithFaLocale() {
7153    UErrorCode status = U_ZERO_ERROR;
7154    DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("fa", status);
7155    CHECK_DATA(status, "NumberFormat::createInstance")
7156    test->setLenient(TRUE);
7157    Formattable af;
7158    ParsePosition ppos;
7159    UnicodeString value("\\u200e-0,5");
7160    value = value.unescape();
7161    test->parse(value, af, ppos);
7162    if (ppos.getIndex() == 0) {
7163        errln("Expected -0,5 to parse for Farsi.");
7164    }
7165    delete test;
7166}
7167
7168void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() {
7169    UErrorCode status = U_ZERO_ERROR;
7170    DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("en", status);
7171    CHECK_DATA(status, "NumberFormat::createInstance")
7172    test->setLenient(TRUE);
7173    Formattable af;
7174    ParsePosition ppos;
7175    UnicodeString value("\\u208B0.5");
7176    value = value.unescape();
7177    test->parse(value, af, ppos);
7178    if (ppos.getIndex() == 0) {
7179        errln(UnicodeString("Expected ") + value + UnicodeString(" to parse."));
7180    }
7181    delete test;
7182}
7183
7184void NumberFormatTest::TestCustomCurrencySignAndSeparator() {
7185    UErrorCode status = U_ZERO_ERROR;
7186    DecimalFormatSymbols custom(Locale::getUS(), status);
7187    CHECK(status, "DecimalFormatSymbols constructor");
7188
7189    custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "*");
7190    custom.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, "^");
7191    custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, ":");
7192
7193    UnicodeString pat(" #,##0.00");
7194    pat.insert(0, (UChar)0x00A4);
7195
7196    DecimalFormat fmt(pat, custom, status);
7197    CHECK(status, "DecimalFormat constructor");
7198
7199    UnicodeString numstr("* 1^234:56");
7200    expect2(fmt, (Formattable)((double)1234.56), numstr);
7201}
7202
7203typedef struct {
7204    const char *   locale;
7205    UBool          lenient;
7206    UnicodeString  numString;
7207    double         value;
7208} SignsAndMarksItem;
7209
7210
7211void NumberFormatTest::TestParseSignsAndMarks() {
7212    const SignsAndMarksItem items[] = {
7213        // locale               lenient numString                                                       value
7214        { "en",                 FALSE,  CharsToUnicodeString("12"),                                      12 },
7215        { "en",                 TRUE,   CharsToUnicodeString("12"),                                      12 },
7216        { "en",                 FALSE,  CharsToUnicodeString("-23"),                                    -23 },
7217        { "en",                 TRUE,   CharsToUnicodeString("-23"),                                    -23 },
7218        { "en",                 TRUE,   CharsToUnicodeString("- 23"),                                   -23 },
7219        { "en",                 FALSE,  CharsToUnicodeString("\\u200E-23"),                             -23 },
7220        { "en",                 TRUE,   CharsToUnicodeString("\\u200E-23"),                             -23 },
7221        { "en",                 TRUE,   CharsToUnicodeString("\\u200E- 23"),                            -23 },
7222
7223        { "en@numbers=arab",    FALSE,  CharsToUnicodeString("\\u0663\\u0664"),                          34 },
7224        { "en@numbers=arab",    TRUE,   CharsToUnicodeString("\\u0663\\u0664"),                          34 },
7225        { "en@numbers=arab",    FALSE,  CharsToUnicodeString("-\\u0664\\u0665"),                        -45 },
7226        { "en@numbers=arab",    TRUE,   CharsToUnicodeString("-\\u0664\\u0665"),                        -45 },
7227        { "en@numbers=arab",    TRUE,   CharsToUnicodeString("- \\u0664\\u0665"),                       -45 },
7228        { "en@numbers=arab",    FALSE,  CharsToUnicodeString("\\u200F-\\u0664\\u0665"),                 -45 },
7229        { "en@numbers=arab",    TRUE,   CharsToUnicodeString("\\u200F-\\u0664\\u0665"),                 -45 },
7230        { "en@numbers=arab",    TRUE,   CharsToUnicodeString("\\u200F- \\u0664\\u0665"),                -45 },
7231
7232        { "en@numbers=arabext", FALSE,  CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7233        { "en@numbers=arabext", TRUE,   CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7234        { "en@numbers=arabext", FALSE,  CharsToUnicodeString("-\\u06F6\\u06F7"),                        -67 },
7235        { "en@numbers=arabext", TRUE,   CharsToUnicodeString("-\\u06F6\\u06F7"),                        -67 },
7236        { "en@numbers=arabext", TRUE,   CharsToUnicodeString("- \\u06F6\\u06F7"),                       -67 },
7237        { "en@numbers=arabext", FALSE,  CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
7238        { "en@numbers=arabext", TRUE,   CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
7239        { "en@numbers=arabext", TRUE,   CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"),         -67 },
7240
7241        { "he",                 FALSE,  CharsToUnicodeString("12"),                                      12 },
7242        { "he",                 TRUE,   CharsToUnicodeString("12"),                                      12 },
7243        { "he",                 FALSE,  CharsToUnicodeString("-23"),                                    -23 },
7244        { "he",                 TRUE,   CharsToUnicodeString("-23"),                                    -23 },
7245        { "he",                 TRUE,   CharsToUnicodeString("- 23"),                                   -23 },
7246        { "he",                 FALSE,  CharsToUnicodeString("\\u200E-23"),                             -23 },
7247        { "he",                 TRUE,   CharsToUnicodeString("\\u200E-23"),                             -23 },
7248        { "he",                 TRUE,   CharsToUnicodeString("\\u200E- 23"),                            -23 },
7249
7250        { "ar",                 FALSE,  CharsToUnicodeString("\\u0663\\u0664"),                          34 },
7251        { "ar",                 TRUE,   CharsToUnicodeString("\\u0663\\u0664"),                          34 },
7252        { "ar",                 FALSE,  CharsToUnicodeString("-\\u0664\\u0665"),                        -45 },
7253        { "ar",                 TRUE,   CharsToUnicodeString("-\\u0664\\u0665"),                        -45 },
7254        { "ar",                 TRUE,   CharsToUnicodeString("- \\u0664\\u0665"),                       -45 },
7255        { "ar",                 FALSE,  CharsToUnicodeString("\\u200F-\\u0664\\u0665"),                 -45 },
7256        { "ar",                 TRUE,   CharsToUnicodeString("\\u200F-\\u0664\\u0665"),                 -45 },
7257        { "ar",                 TRUE,   CharsToUnicodeString("\\u200F- \\u0664\\u0665"),                -45 },
7258
7259        { "ar_MA",              FALSE,  CharsToUnicodeString("12"),                                      12 },
7260        { "ar_MA",              TRUE,   CharsToUnicodeString("12"),                                      12 },
7261        { "ar_MA",              FALSE,  CharsToUnicodeString("-23"),                                    -23 },
7262        { "ar_MA",              TRUE,   CharsToUnicodeString("-23"),                                    -23 },
7263        { "ar_MA",              TRUE,   CharsToUnicodeString("- 23"),                                   -23 },
7264        { "ar_MA",              FALSE,  CharsToUnicodeString("\\u200E-23"),                             -23 },
7265        { "ar_MA",              TRUE,   CharsToUnicodeString("\\u200E-23"),                             -23 },
7266        { "ar_MA",              TRUE,   CharsToUnicodeString("\\u200E- 23"),                            -23 },
7267
7268        { "fa",                 FALSE,  CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7269        { "fa",                 TRUE,   CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7270        { "fa",                 FALSE,  CharsToUnicodeString("\\u2212\\u06F6\\u06F7"),                  -67 },
7271        { "fa",                 TRUE,   CharsToUnicodeString("\\u2212\\u06F6\\u06F7"),                  -67 },
7272        { "fa",                 TRUE,   CharsToUnicodeString("\\u2212 \\u06F6\\u06F7"),                 -67 },
7273        { "fa",                 FALSE,  CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"),    -67 },
7274        { "fa",                 TRUE,   CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"),    -67 },
7275        { "fa",                 TRUE,   CharsToUnicodeString("\\u200E\\u2212\\u200E \\u06F6\\u06F7"),   -67 },
7276
7277        { "ps",                 FALSE,  CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7278        { "ps",                 TRUE,   CharsToUnicodeString("\\u06F5\\u06F6"),                          56 },
7279        { "ps",                 FALSE,  CharsToUnicodeString("-\\u06F6\\u06F7"),                        -67 },
7280        { "ps",                 TRUE,   CharsToUnicodeString("-\\u06F6\\u06F7"),                        -67 },
7281        { "ps",                 TRUE,   CharsToUnicodeString("- \\u06F6\\u06F7"),                       -67 },
7282        { "ps",                 FALSE,  CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
7283        { "ps",                 TRUE,   CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
7284        { "ps",                 TRUE,   CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"),         -67 },
7285        { "ps",                 FALSE,  CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"),                 -67 },
7286        { "ps",                 TRUE,   CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"),                 -67 },
7287        { "ps",                 TRUE,   CharsToUnicodeString("-\\u200E \\u06F6\\u06F7"),                -67 },
7288        // terminator
7289        { NULL,                 0,      UnicodeString(""),                                                0 },
7290    };
7291
7292    const SignsAndMarksItem * itemPtr;
7293    for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
7294        UErrorCode status = U_ZERO_ERROR;
7295        NumberFormat *numfmt = NumberFormat::createInstance(Locale(itemPtr->locale), status);
7296        if (U_SUCCESS(status)) {
7297            numfmt->setLenient(itemPtr->lenient);
7298            Formattable fmtobj;
7299            ParsePosition ppos;
7300            numfmt->parse(itemPtr->numString, fmtobj, ppos);
7301            if (ppos.getIndex() == itemPtr->numString.length()) {
7302                double parsedValue = fmtobj.getDouble(status);
7303                if (U_FAILURE(status) || parsedValue != itemPtr->value) {
7304                    errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives value " + parsedValue);
7305                }
7306            } else {
7307                errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives position " + ppos.getIndex());
7308            }
7309        } else {
7310            dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr->locale, u_errorName(status));
7311        }
7312        delete numfmt;
7313    }
7314}
7315
7316typedef struct {
7317  DecimalFormat::ERoundingMode mode;
7318  double value;
7319  UnicodeString expected;
7320} Test10419Data;
7321
7322
7323// Tests that rounding works right when fractional digits is set to 0.
7324void NumberFormatTest::Test10419RoundingWith0FractionDigits() {
7325    const Test10419Data items[] = {
7326        { DecimalFormat::kRoundCeiling, 1.488,  "2"},
7327        { DecimalFormat::kRoundDown, 1.588,  "1"},
7328        { DecimalFormat::kRoundFloor, 1.888,  "1"},
7329        { DecimalFormat::kRoundHalfDown, 1.5,  "1"},
7330        { DecimalFormat::kRoundHalfEven, 2.5,  "2"},
7331        { DecimalFormat::kRoundHalfUp, 2.5,  "3"},
7332        { DecimalFormat::kRoundUp, 1.5,  "2"},
7333    };
7334    UErrorCode status = U_ZERO_ERROR;
7335    LocalPointer<DecimalFormat> decfmt((DecimalFormat *) NumberFormat::createInstance(Locale("en_US"), status));
7336    if (U_FAILURE(status)) {
7337        dataerrln("Failure creating DecimalFormat %s", u_errorName(status));
7338        return;
7339    }
7340    for (int32_t i = 0; i < (int32_t) (sizeof(items) / sizeof(items[0])); ++i) {
7341        decfmt->setRoundingMode(items[i].mode);
7342        decfmt->setMaximumFractionDigits(0);
7343        UnicodeString actual;
7344        if (items[i].expected != decfmt->format(items[i].value, actual)) {
7345            errln("Expected " + items[i].expected + ", got " + actual);
7346        }
7347    }
7348}
7349
7350void NumberFormatTest::Test10468ApplyPattern() {
7351    // Padding char of fmt is now 'a'
7352    UErrorCode status = U_ZERO_ERROR;
7353    DecimalFormat fmt("'I''ll'*a###.##", status);
7354
7355    if (U_FAILURE(status)) {
7356        errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
7357        return;
7358    }
7359
7360    if (fmt.getPadCharacterString() != UnicodeString("a")) {
7361        errln("Padding character should be 'a'.");
7362        return;
7363    }
7364
7365    // Padding char of fmt ought to be '*' since that is the default and no
7366    // explicit padding char is specified in the new pattern.
7367    fmt.applyPattern("AA#,##0.00ZZ", status);
7368
7369    // Oops this still prints 'a' even though we changed the pattern.
7370    if (fmt.getPadCharacterString() != UnicodeString("*")) {
7371        errln("applyPattern did not clear padding character.");
7372    }
7373}
7374
7375void NumberFormatTest::TestRoundingScientific10542() {
7376    UErrorCode status = U_ZERO_ERROR;
7377    DecimalFormat format("0.00E0", status);
7378    if (U_FAILURE(status)) {
7379        errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
7380        return;
7381    }
7382
7383    DecimalFormat::ERoundingMode roundingModes[] = {
7384            DecimalFormat::kRoundCeiling,
7385            DecimalFormat::kRoundDown,
7386            DecimalFormat::kRoundFloor,
7387            DecimalFormat::kRoundHalfDown,
7388            DecimalFormat::kRoundHalfEven,
7389            DecimalFormat::kRoundHalfUp,
7390            DecimalFormat::kRoundUp};
7391    const char *descriptions[] = {
7392            "Round Ceiling",
7393            "Round Down",
7394            "Round Floor",
7395            "Round half down",
7396            "Round half even",
7397            "Round half up",
7398            "Round up"};
7399
7400    {
7401        double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
7402        // The order of these expected values correspond to the order of roundingModes and the order of values.
7403        const char *expected[] = {
7404                "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3",
7405                "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7406                "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7407                "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3",
7408                "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7409                "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7410                "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"};
7411        verifyRounding(
7412                format,
7413                values,
7414                expected,
7415                roundingModes,
7416                descriptions,
7417                (int32_t) (sizeof(values) / sizeof(values[0])),
7418                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7419    }
7420    {
7421        double values[] = {-3006.0, -3005, -3004, 3014, 3015, 3016};
7422        // The order of these expected values correspond to the order of roundingModes and the order of values.
7423        const char *expected[] = {
7424                "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3",
7425                "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3",
7426                "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3",
7427                "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3",
7428                "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7429                "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7430                "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"};
7431        verifyRounding(
7432                format,
7433                values,
7434                expected,
7435                roundingModes,
7436                descriptions,
7437                (int32_t) (sizeof(values) / sizeof(values[0])),
7438                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7439    }
7440/* Commented out for now until we decide how rounding to zero should work, +0 vs. -0
7441    {
7442        double values[] = {0.0, -0.0};
7443        // The order of these expected values correspond to the order of roundingModes and the order of values.
7444        const char *expected[] = {
7445                "0.00E0", "-0.00E0",
7446                "0.00E0", "-0.00E0",
7447                "0.00E0", "-0.00E0",
7448                "0.00E0", "-0.00E0",
7449                "0.00E0", "-0.00E0",
7450                "0.00E0", "-0.00E0",
7451                "0.00E0", "-0.00E0"};
7452        verifyRounding(
7453                format,
7454                values,
7455                expected,
7456                roundingModes,
7457                descriptions,
7458                (int32_t) (sizeof(values) / sizeof(values[0])),
7459                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7460    }
7461*/
7462    {
7463
7464        double values[] = {1e25, 1e25 + 1e15, 1e25 - 1e15};
7465        // The order of these expected values correspond to the order of roundingModes and the order of values.
7466        const char *expected[] = {
7467                "1.00E25", "1.01E25", "1.00E25",
7468                "1.00E25", "1.00E25", "9.99E24",
7469                "1.00E25", "1.00E25", "9.99E24",
7470                "1.00E25", "1.00E25", "1.00E25",
7471                "1.00E25", "1.00E25", "1.00E25",
7472                "1.00E25", "1.00E25", "1.00E25",
7473                "1.00E25", "1.01E25", "1.00E25"};
7474        verifyRounding(
7475                format,
7476                values,
7477                expected,
7478                roundingModes,
7479                descriptions,
7480                (int32_t) (sizeof(values) / sizeof(values[0])),
7481                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7482        }
7483    {
7484        double values[] = {-1e25, -1e25 + 1e15, -1e25 - 1e15};
7485        // The order of these expected values correspond to the order of roundingModes and the order of values.
7486        const char *expected[] = {
7487                "-1.00E25", "-9.99E24", "-1.00E25",
7488                "-1.00E25", "-9.99E24", "-1.00E25",
7489                "-1.00E25", "-1.00E25", "-1.01E25",
7490                "-1.00E25", "-1.00E25", "-1.00E25",
7491                "-1.00E25", "-1.00E25", "-1.00E25",
7492                "-1.00E25", "-1.00E25", "-1.00E25",
7493                "-1.00E25", "-1.00E25", "-1.01E25"};
7494        verifyRounding(
7495                format,
7496                values,
7497                expected,
7498                roundingModes,
7499                descriptions,
7500                (int32_t) (sizeof(values) / sizeof(values[0])),
7501                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7502        }
7503    {
7504        double values[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35};
7505        // The order of these expected values correspond to the order of roundingModes and the order of values.
7506        const char *expected[] = {
7507                "1.00E-25", "1.01E-25", "1.00E-25",
7508                "1.00E-25", "1.00E-25", "9.99E-26",
7509                "1.00E-25", "1.00E-25", "9.99E-26",
7510                "1.00E-25", "1.00E-25", "1.00E-25",
7511                "1.00E-25", "1.00E-25", "1.00E-25",
7512                "1.00E-25", "1.00E-25", "1.00E-25",
7513                "1.00E-25", "1.01E-25", "1.00E-25"};
7514        verifyRounding(
7515                format,
7516                values,
7517                expected,
7518                roundingModes,
7519                descriptions,
7520                (int32_t) (sizeof(values) / sizeof(values[0])),
7521                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7522        }
7523    {
7524        double values[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35};
7525        // The order of these expected values correspond to the order of roundingModes and the order of values.
7526        const char *expected[] = {
7527                "-1.00E-25", "-9.99E-26", "-1.00E-25",
7528                "-1.00E-25", "-9.99E-26", "-1.00E-25",
7529                "-1.00E-25", "-1.00E-25", "-1.01E-25",
7530                "-1.00E-25", "-1.00E-25", "-1.00E-25",
7531                "-1.00E-25", "-1.00E-25", "-1.00E-25",
7532                "-1.00E-25", "-1.00E-25", "-1.00E-25",
7533                "-1.00E-25", "-1.00E-25", "-1.01E-25"};
7534        verifyRounding(
7535                format,
7536                values,
7537                expected,
7538                roundingModes,
7539                descriptions,
7540                (int32_t) (sizeof(values) / sizeof(values[0])),
7541                (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0])));
7542    }
7543}
7544
7545void NumberFormatTest::TestZeroScientific10547() {
7546    UErrorCode status = U_ZERO_ERROR;
7547    DecimalFormat fmt("0.00E0", status);
7548    if (!assertSuccess("Formt creation", status)) {
7549        return;
7550    }
7551    UnicodeString out;
7552    fmt.format(-0.0, out);
7553    assertEquals("format", "-0.00E0", out);
7554}
7555
7556void NumberFormatTest::verifyRounding(
7557        DecimalFormat& format,
7558        const double *values,
7559        const char * const *expected,
7560        const DecimalFormat::ERoundingMode *roundingModes,
7561        const char * const *descriptions,
7562        int32_t valueSize,
7563        int32_t roundingModeSize) {
7564    for (int32_t i = 0; i < roundingModeSize; ++i) {
7565        format.setRoundingMode(roundingModes[i]);
7566        for (int32_t j = 0; j < valueSize; j++) {
7567            UnicodeString currentExpected(expected[i * valueSize + j]);
7568            currentExpected = currentExpected.unescape();
7569            UnicodeString actual;
7570            format.format(values[j], actual);
7571            if (currentExpected != actual) {
7572                char buffer[256];
7573                sprintf(
7574                        buffer,
7575                        "For %s value %f, expected ",
7576                        descriptions[i],
7577                        values[j]);
7578                errln(UnicodeString(buffer) + currentExpected + ", got " + actual);
7579            }
7580        }
7581    }
7582}
7583
7584void NumberFormatTest::TestAccountingCurrency() {
7585    UErrorCode status = U_ZERO_ERROR;
7586    UNumberFormatStyle style = UNUM_CURRENCY_ACCOUNTING;
7587
7588    expect(NumberFormat::createInstance("en_US", style, status),
7589        (Formattable)1234.5, "$1,234.50", TRUE, status);
7590    expect(NumberFormat::createInstance("en_US", style, status),
7591        (Formattable)-1234.5, "($1,234.50)", TRUE, status);
7592    expect(NumberFormat::createInstance("en_US", style, status),
7593        (Formattable)0, "$0.00", TRUE, status);
7594    expect(NumberFormat::createInstance("en_US", style, status),
7595        (Formattable)-0.2, "($0.20)", TRUE, status);
7596    expect(NumberFormat::createInstance("ja_JP", style, status),
7597        (Formattable)10000, UnicodeString("\\uFFE510,000").unescape(), TRUE, status);
7598    expect(NumberFormat::createInstance("ja_JP", style, status),
7599        (Formattable)-1000.5, UnicodeString("(\\uFFE51,000)").unescape(), FALSE, status);
7600    expect(NumberFormat::createInstance("de_DE", style, status),
7601        (Formattable)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE, status);
7602}
7603
7604// for #5186
7605void NumberFormatTest::TestEquality() {
7606    UErrorCode status = U_ZERO_ERROR;
7607    DecimalFormatSymbols* symbols = new DecimalFormatSymbols(Locale("root"), status);
7608    if (U_FAILURE(status)) {
7609    	dataerrln("Fail: can't create DecimalFormatSymbols for root");
7610    	return;
7611    }
7612    UnicodeString pattern("#,##0.###");
7613    DecimalFormat* fmtBase = new DecimalFormat(pattern, symbols, status);
7614    if (U_FAILURE(status)) {
7615    	dataerrln("Fail: can't create DecimalFormat using root symbols");
7616    	return;
7617    }
7618
7619    DecimalFormat* fmtClone = (DecimalFormat*)fmtBase->clone();
7620    fmtClone->setFormatWidth(fmtBase->getFormatWidth() + 32);
7621    if (*fmtClone == *fmtBase) {
7622        errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
7623    }
7624    delete fmtClone;
7625
7626    delete fmtBase;
7627}
7628
7629#endif /* #if !UCONFIG_NO_FORMATTING */
7630