1/***********************************************************************
2 * Copyright (c) 1997-2012, International Business Machines Corporation
3 * and others. All Rights Reserved.
4 ***********************************************************************/
5
6#include "unicode/utypes.h"
7
8#if !UCONFIG_NO_FORMATTING
9
10#include "numrgts.h"
11
12#include <float.h> // DBL_MIN, DBL_MAX
13#include <stdio.h>
14
15#include "unicode/dcfmtsym.h"
16#include "unicode/decimfmt.h"
17#include "unicode/locid.h"
18#include "unicode/resbund.h"
19#include "unicode/calendar.h"
20#include "unicode/datefmt.h"
21#include "unicode/ucurr.h"
22#include "putilimp.h"
23
24class MyNumberFormatTest : public NumberFormat
25{
26public:
27
28    virtual UClassID getDynamicClassID(void) const;
29
30    virtual UnicodeString& format(    double            number,
31                    UnicodeString&        toAppendTo,
32                    FieldPositionIterator* posIter,
33                    UErrorCode& status) const
34    {
35        return NumberFormat::format(number, toAppendTo, posIter, status);
36    }
37
38    /* Just keep this here to make some of the compilers happy */
39    virtual UnicodeString& format(const Formattable& obj,
40                                  UnicodeString& toAppendTo,
41                                  FieldPosition& pos,
42                                  UErrorCode& status) const
43    {
44        return NumberFormat::format(obj, toAppendTo, pos, status);
45    }
46
47    /* Just use one of the format functions */
48    virtual UnicodeString& format(    double            /* number */,
49                    UnicodeString&        toAppendTo,
50                    FieldPosition&        /* pos */) const
51    {
52        toAppendTo = "";
53        return toAppendTo;
54    }
55
56    /*
57    public Number parse(String text, ParsePosition parsePosition)
58    { return new Integer(0); }
59    */
60
61    /* Just use one of the parse functions */
62    virtual void parse(    const UnicodeString&    /* text */,
63            Formattable&            result,
64            ParsePosition&          /* parsePosition */) const
65    {
66        result.setLong((int32_t)0);
67    }
68
69    virtual void parse(    const UnicodeString&    text,
70            Formattable&            result,
71            UErrorCode&            status) const
72    {
73        NumberFormat::parse(text, result, status);
74    }
75    virtual Format* clone() const
76    { return NULL; }
77
78    virtual UnicodeString& format(int32_t,
79                UnicodeString& foo,
80                FieldPosition&) const
81    { return foo.remove(); }
82
83    virtual UnicodeString& format(int64_t,
84                UnicodeString& foo,
85                FieldPosition&) const
86    { return foo.remove(); }
87
88    virtual void applyPattern(const UnicodeString&, UParseError&, UErrorCode&){
89    }
90};
91
92int32_t gMyNumberFormatTestClassID;
93UClassID MyNumberFormatTest::getDynamicClassID()  const
94{
95    return (UClassID)&gMyNumberFormatTestClassID;
96}
97
98
99// *****************************************************************************
100// class NumberFormatRegressionTest
101// *****************************************************************************
102
103#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
104
105void
106NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
107{
108    // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
109    switch (index) {
110        CASE(0,Test4075713);
111        CASE(1,Test4074620);
112        CASE(2,Test4088161);
113        CASE(3,Test4087245);
114        CASE(4,Test4087535);
115        CASE(5,Test4088503);
116        CASE(6,Test4066646);
117        CASE(7,Test4059870);
118        CASE(8,Test4083018);
119        CASE(9,Test4071492);
120        CASE(10,Test4086575);
121        CASE(11,Test4068693);
122        CASE(12,Test4069754);
123        CASE(13,Test4087251);
124        CASE(14,Test4090489);
125        CASE(15,Test4090504);
126        CASE(16,Test4095713);
127        CASE(17,Test4092561);
128        CASE(18,Test4092480);
129        CASE(19,Test4087244);
130        CASE(20,Test4070798);
131        CASE(21,Test4071005);
132        CASE(22,Test4071014);
133        CASE(23,Test4071859);
134        CASE(24,Test4093610);
135        CASE(25,Test4098741);
136        CASE(26,Test4074454);
137        CASE(27,Test4099404);
138        CASE(28,Test4101481);
139        CASE(29,Test4052223);
140        CASE(30,Test4061302);
141        CASE(31,Test4062486);
142        CASE(32,Test4108738);
143        CASE(33,Test4106658);
144        CASE(34,Test4106662);
145        CASE(35,Test4114639);
146        CASE(36,Test4106664);
147        CASE(37,Test4106667);
148        CASE(38,Test4110936);
149        CASE(39,Test4122840);
150        CASE(40,Test4125885);
151        CASE(41,Test4134034);
152        CASE(42,Test4134300);
153        CASE(43,Test4140009);
154        CASE(44,Test4141750);
155        CASE(45,Test4145457);
156        CASE(46,Test4147295);
157        CASE(47,Test4147706);
158        CASE(48,Test4162198);
159        CASE(49,Test4162852);
160        CASE(50,Test4167494);
161        CASE(51,Test4170798);
162        CASE(52,Test4176114);
163        CASE(53,Test4179818);
164        CASE(54,Test4212072);
165        CASE(55,Test4216742);
166        CASE(56,Test4217661);
167        CASE(57,Test4161100);
168        CASE(58,Test4243011);
169        CASE(59,Test4243108);
170        CASE(60,TestJ691);
171        CASE(61,Test8199);
172        CASE(62,Test9109);
173        CASE(63,Test9780);
174        CASE(64,Test9677);
175
176        default: name = ""; break;
177    }
178}
179
180UBool
181NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const Locale& l, UBool possibleDataError)
182{
183    if(U_FAILURE(status)) {
184        if (possibleDataError) {
185            dataerrln(UnicodeString("FAIL: ", "") + msg
186                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
187        } else {
188            errcheckln(status, UnicodeString("FAIL: ", "") + msg
189                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
190        }
191        return TRUE;
192    }
193
194    return FALSE;
195}
196
197UBool
198NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError)
199{
200    if(U_FAILURE(status)) {
201        if (possibleDataError) {
202            dataerrln(UnicodeString("FAIL: ", "") + msg
203                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
204        } else {
205            errcheckln(status, UnicodeString("FAIL: ", "") + msg
206                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
207        }
208        return TRUE;
209    }
210
211    return FALSE;
212}
213
214UBool
215NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError)
216{
217    if(U_FAILURE(status)) {
218        if (possibleDataError) {
219            dataerrln(UnicodeString("FAIL: ", "") + msg
220                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
221        } else {
222            errcheckln(status, UnicodeString("FAIL: ", "") + msg
223                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
224        }
225        return TRUE;
226    }
227
228    return FALSE;
229}
230
231/**
232 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
233 */
234inline UnicodeString str(const char *input)
235{
236  return CharsToUnicodeString(input);
237}
238
239/* @bug 4075713
240 * NumberFormat.equals comparing with null should always return false.
241 */
242// {sfb} kind of silly in C++, just checking for new success
243void NumberFormatRegressionTest::Test4075713(void)
244{
245    //try {
246        MyNumberFormatTest *tmp = new MyNumberFormatTest();
247        if(tmp != NULL)
248            logln("NumberFormat.equals passed");
249    /*} catch (NullPointerException e) {
250        errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
251    }*/
252
253    delete tmp;
254}
255
256/* @bug 4074620
257 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
258 * flag is different.
259 */
260void NumberFormatRegressionTest::Test4074620(void)
261{
262
263    MyNumberFormatTest *nf1 = new MyNumberFormatTest();
264    MyNumberFormatTest *nf2 = new MyNumberFormatTest();
265
266    nf1->setGroupingUsed(FALSE);
267    nf2->setGroupingUsed(TRUE);
268
269    if(nf1 == nf2)
270        errln("Test for bug 4074620 failed");
271    else
272        logln("Test for bug 4074620 passed.");
273
274    delete nf1;
275    delete nf2;
276}
277
278
279/* @bug 4088161
280 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
281 */
282
283void NumberFormatRegressionTest::Test4088161 (void)
284{
285    UErrorCode status = U_ZERO_ERROR;
286    DecimalFormat *df = new DecimalFormat(status);
287    if (!failure(status, "new DecimalFormat", "")) {
288        double d = 100;
289        df->setMinimumFractionDigits(0);
290        df->setMaximumFractionDigits(16);
291        UnicodeString sBuf1;
292        FieldPosition fp1(0);
293        logln(UnicodeString("d = ") + d);
294        logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
295
296        logln(" format(d) = '" + df->format(d, sBuf1, fp1) + "'");
297        df->setMaximumFractionDigits(17);
298        UnicodeString sBuf2;
299        FieldPosition fp2(0);
300        logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
301        sBuf2 = df->format(d, sBuf2, fp2);
302        if(sBuf2 != "100")
303            errln(" format(d) = '" + sBuf2 + "'");
304    }
305
306    delete df;
307}
308
309/* @bug 4087245
310 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
311 * DecimalFormat(String, DecimalFormatSymbols).
312 */
313void NumberFormatRegressionTest::Test4087245 (void)
314{
315    UErrorCode status = U_ZERO_ERROR;
316    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(status);
317    failure(status, "new DecimalFormatSymbols", "");
318    // {sfb} One note about this test: if you pass in a pointer
319    // to the symbols, they are adopted and this test will fail,
320    // even though that is the correct behavior.  To test the cloning
321    // of the symbols, it is necessary to pass in a reference to the symbols
322    DecimalFormat *df = new DecimalFormat("#,##0.0", *symbols, status);
323    failure(status, "new DecimalFormat with symbols", "");
324    int32_t n = 123;
325    UnicodeString buf1;
326    UnicodeString buf2;
327    FieldPosition pos(FieldPosition::DONT_CARE);
328    logln(UnicodeString("format(") + n + ") = " +
329        df->format(n, buf1, pos));
330    symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString((UChar)0x70)); // change value of field
331    logln(UnicodeString("format(") + n + ") = " +
332        df->format(n, buf2, pos));
333    if(buf1 != buf2)
334        errln("Test for bug 4087245 failed");
335
336    delete df;
337    delete symbols;
338}
339
340/* @bug 4087535
341 * DecimalFormat.format() incorrectly formats 0.0
342 */
343void NumberFormatRegressionTest::Test4087535 (void)
344{
345    UErrorCode status = U_ZERO_ERROR;
346    DecimalFormat *df = new DecimalFormat(status);
347    failure(status, "new DecimalFormat", "");
348    df->setMinimumIntegerDigits(0);
349
350    double n = 0;
351    UnicodeString buffer;
352    FieldPosition pos(FieldPosition::DONT_CARE);
353    buffer = df->format(n, buffer, pos);
354    if (buffer.length() == 0)
355        errln(/*n + */": '" + buffer + "'");
356    n = 0.1;
357    buffer = df->format(n, buffer, pos);
358    if (buffer.length() == 0)
359        errln(/*n + */": '" + buffer + "'");
360
361    delete df;
362}
363
364/* @bug 4088503
365 * DecimalFormat.format fails when groupingSize is set to 0.
366 */
367// {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
368void NumberFormatRegressionTest::Test4088503 (void)
369{
370    UErrorCode status = U_ZERO_ERROR;
371    DecimalFormat *df = new DecimalFormat(status);
372    failure(status, "new DecimalFormat", "");
373    df->setGroupingSize(0);
374    UnicodeString sBuf;
375    FieldPosition fp(FieldPosition::DONT_CARE);
376    //try {
377        logln(df->format((int32_t)123, sBuf, fp));
378        //if(fp == FieldPosition(0))
379        //    errln("Test for bug 4088503 failed.");
380    /*} catch (Exception foo) {
381        errln("Test for bug 4088503 failed.");
382    }*/
383    delete df;
384
385}
386/* @bug 4066646
387 * NumberFormat.getCurrencyInstance is wrong.
388 */
389void NumberFormatRegressionTest::Test4066646 (void)
390{
391    assignFloatValue(2.04f);
392    assignFloatValue(2.03f);
393    assignFloatValue(2.02f);
394    assignFloatValue(0.0f);
395}
396
397float
398NumberFormatRegressionTest::assignFloatValue(float returnfloat)
399{
400    logln(UnicodeString(" VALUE ") + returnfloat);
401    UErrorCode status = U_ZERO_ERROR;
402    NumberFormat *nfcommon =  NumberFormat::createCurrencyInstance(Locale::getUS(), status);
403    if (failure(status, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE)){
404        delete nfcommon;
405        return returnfloat;
406    }
407    nfcommon->setGroupingUsed(FALSE);
408
409    UnicodeString stringValue;
410    stringValue = nfcommon->format(returnfloat, stringValue);
411    logln(" DISPLAYVALUE " + stringValue);
412    Formattable result;
413    nfcommon->parse(stringValue, result, status);
414    failure(status, "nfcommon->parse", Locale::getUS());
415    float floatResult = (float) (result.getType() == Formattable::kDouble
416                                        ? result.getDouble() : result.getLong());
417    if( uprv_fabs(floatResult - returnfloat) > 0.0001)
418    //String stringValue = nfcommon.format(returnfloat).substring(1);
419    //if (Float.valueOf(stringValue).floatValue() != returnfloat)
420        errln(UnicodeString("FAIL: expected ") + returnfloat + ", got " + floatResult + " (" + stringValue+")");
421
422    delete nfcommon;
423    return returnfloat;
424} // End Of assignFloatValue()
425
426/* @bug 4059870
427 * DecimalFormat throws exception when parsing "0"
428 */
429void NumberFormatRegressionTest::Test4059870(void)
430{
431    UErrorCode status = U_ZERO_ERROR;
432    DecimalFormat *format = new DecimalFormat("00", status);
433    failure(status, "new Decimalformat", Locale::getUS());
434    //try {
435        Formattable result;
436        UnicodeString str;
437        format->parse(UnicodeString("0"), result, status);
438        failure(status, "format->parse", Locale::getUS());
439
440    /*}
441    catch (Exception e) {
442        errln("Test for bug 4059870 failed : " + e);
443    }*/
444
445    delete format;
446}
447/* @bug 4083018
448 * DecimalFormatSymbol.equals should always return false when
449 * comparing with null.
450 */
451// {sfb} this is silly in C++
452void NumberFormatRegressionTest::Test4083018 (void)
453{
454    UErrorCode status = U_ZERO_ERROR;
455    DecimalFormatSymbols *dfs = new DecimalFormatSymbols(status);
456    failure(status, "new DecimalFormatSymbols", Locale::getUS());
457    //try {
458        if (dfs != NULL)
459            logln("Test Passed!");
460        else
461            errln("Test for bug 4083018 failed");
462    /*} catch (Exception foo) {
463        errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
464    }*/
465
466    delete dfs;
467}
468
469/* @bug 4071492
470 * DecimalFormat does not round up correctly.
471 */
472void NumberFormatRegressionTest::Test4071492 (void)
473{
474    double x = 0.00159999;
475    UErrorCode status = U_ZERO_ERROR;
476    NumberFormat *nf = NumberFormat::createInstance(status);
477    if (failure(status, "NumberFormat::createInstance", Locale::getUS(), TRUE)) {
478        delete nf;
479        return;
480    }
481    nf->setMaximumFractionDigits(4);
482    UnicodeString out;
483    FieldPosition pos(FieldPosition::DONT_CARE);
484    out = nf->format(x, out, pos);
485    logln("0.00159999 formats with 4 fractional digits to " + out);
486    UnicodeString expected("0.0016");
487    if (out != expected)
488        errln("FAIL: Expected " + expected);
489
490    delete nf;
491}
492
493/* @bug 4086575
494 * A space as a group separator for localized pattern causes
495 * wrong format.  WorkAround : use non-breaking space.
496 */
497void NumberFormatRegressionTest::Test4086575(void)
498{
499    UErrorCode status = U_ZERO_ERROR;
500    NumberFormat *nf1 = NumberFormat::createInstance(Locale::getFrance(), status);
501
502    // TODO: There is not a good way to find out that the creation of this number format has
503    // failed. Major rewiring of format construction proposed.
504    if(U_FAILURE(status)) {
505      dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status));
506      delete nf1;
507      return;
508    }
509    failure(status, "NumberFormat::createInstance", Locale::getFrance());
510
511    // C++ workaround to make sure cast works
512    DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1);
513    if(nf == NULL) {
514        errln("NumberFormat::createInstance returned incorrect type.");
515        return;
516    }
517
518    UnicodeString temp;
519    logln("nf toPattern1: " + nf->toPattern(temp));
520    logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp));
521
522    // No group separator
523    logln("...applyLocalizedPattern ###,00;(###,00) ");
524    nf->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status);
525    failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
526    logln("nf toPattern2: " + nf->toPattern(temp));
527    logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
528
529    FieldPosition pos(FieldPosition::DONT_CARE);
530    logln("nf: " + nf->format((int32_t)1234, temp, pos)); // 1234,00
531    logln("nf: " + nf->format((int32_t)-1234, temp, pos)); // (1234,00)
532
533    // Space as group separator
534
535    logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
536    // nbsp = \u00a0
537    //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
538    UChar patChars[] = {
539             0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
540        0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
541    };
542    UnicodeString pat(patChars, 19, 19);
543    nf->applyLocalizedPattern(pat, status);
544    failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
545    logln("nf toPattern2: " + nf->toPattern(temp));
546    logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
547    UnicodeString buffer;
548    buffer = nf->format((int32_t)1234, buffer, pos);
549    //if (buffer != UnicodeString("1\u00a0234,00"))
550    UChar c[] = {
551        0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
552    };
553    UnicodeString cc(c, 8, 8);
554    if (buffer != cc)
555        errln("nf : " + buffer); // Expect 1 234,00
556
557    buffer.remove();
558    buffer = nf->format((int32_t)-1234, buffer, pos);
559    UChar c1[] = {
560        0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
561    };
562    UnicodeString cc1(c1, 10, 10);
563    if (buffer != cc1)
564        errln("nf : " + buffer); // Expect (1 234,00)
565
566    // Erroneously prints:
567    // 1234,00 ,
568    // (1234,00 ,)
569
570    delete nf1;
571}
572/* @bug 4068693
573 * DecimalFormat.parse returns wrong value
574 */
575// {sfb} slightly converted into a round-trip test, since in C++
576// there is no Double.toString()
577void NumberFormatRegressionTest::Test4068693(void)
578{
579    logln("----- Test Application -----");
580    ParsePosition pos(0);
581    UErrorCode status = U_ZERO_ERROR;
582    DecimalFormat *df = new DecimalFormat(status);
583    if(U_FAILURE(status)) {
584      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
585      delete df;
586      return;
587    }
588    failure(status, "new DecimalFormat");
589    Formattable d;
590    //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
591    df->parse(UnicodeString("123.55456"), d, pos);
592    //if (!d.toString().equals("123.55456")) {
593    UnicodeString dstr;
594    df->setMaximumFractionDigits(999);
595    df->setMaximumIntegerDigits(999);
596    FieldPosition fp(FieldPosition::DONT_CARE);
597    dstr = df->format(d.getDouble(), dstr, fp);
598    if (dstr != UnicodeString("123.55456")) {
599        errln(UnicodeString("Result -> ") + d.getDouble());
600    }
601
602    delete df;
603}
604
605/* @bug 4069754, 4067878
606 * null pointer thrown when accessing a deserialized DecimalFormat
607 * object.
608 */
609// {sfb} doesn't apply in C++
610void NumberFormatRegressionTest::Test4069754(void)
611{
612/*    try {
613        myformat it = new myformat();
614        logln(it.Now());
615        FileOutputStream ostream = new FileOutputStream("t.tmp");
616        ObjectOutputStream p = new ObjectOutputStream(ostream);
617        p.writeObject(it);
618        ostream.close();
619        logln("Saved ok.");
620
621        FileInputStream istream = new FileInputStream("t.tmp");
622        ObjectInputStream p2 = new ObjectInputStream(istream);
623        myformat it2 = (myformat)p2.readObject();
624        logln(it2.Now());
625        istream.close();
626        logln("Loaded ok.");
627    } catch (Exception foo) {
628        errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
629    }
630*/}
631
632/* @bug 4087251
633 * DecimalFormat.applyPattern(String) allows illegal patterns
634 */
635void NumberFormatRegressionTest::Test4087251 (void)
636{
637    UErrorCode status = U_ZERO_ERROR;
638    DecimalFormat *df = new DecimalFormat(status);
639    if(U_FAILURE(status)) {
640      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
641      delete df;
642      return;
643    }
644    failure(status, "new DecimalFormat");
645    //try {
646        df->applyPattern(UnicodeString("#.#.#"), status);
647        if( ! U_FAILURE(status))
648            errln("df->applyPattern with illegal pattern didn't fail");
649        UnicodeString temp;
650        logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
651        //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
652    /*} catch (IllegalArgumentException e) {
653        logln("Caught Illegal Argument Error !");
654    }*/
655    // Second test; added 5/11/98 when reported to fail on 1.2b3
656    //try {
657        df->applyPattern("#0.0#0#0", status);
658        if( ! U_FAILURE(status))
659            errln("df->applyPattern with illegal pattern didn't fail");
660        logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
661        //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
662    /*} catch (IllegalArgumentException e) {
663        logln("Ok - IllegalArgumentException for #0.0#0#0");
664    }*/
665
666    delete df;
667}
668
669/* @bug 4090489
670 * DecimalFormat.format() loses precision
671 */
672void NumberFormatRegressionTest::Test4090489 (void)
673{
674// {sfb} sprintf doesn't correctly handle the double, so there is nothing
675// that NumberFormat can do.  For some reason, it does not format the last 1.
676
677/*    UErrorCode status = U_ZERO_ERROR;
678    DecimalFormat *df = new DecimalFormat(status);
679    failure(status, "new DecimalFormat");
680    df->setMinimumFractionDigits(10);
681    df->setMaximumFractionDigits(999);
682    df->setGroupingUsed(FALSE);
683    double d = 1.000000000000001E7;
684    //BigDecimal bd = new BigDecimal(d);
685    UnicodeString sb;
686    FieldPosition fp(0);
687    logln(UnicodeString("d = ") + d);
688    //logln("BigDecimal.toString():  " + bd.toString());
689    df->format(d, sb, fp);
690    if (sb != "10000000.0000000100") {
691        errln("DecimalFormat.format(): " + sb);
692    }
693*/
694}
695
696/* @bug 4090504
697 * DecimalFormat.format() loses precision
698 */
699void NumberFormatRegressionTest::Test4090504 (void)
700{
701    double d = 1;
702    logln(UnicodeString("d = ") + d);
703    UErrorCode status = U_ZERO_ERROR;
704    DecimalFormat *df = new DecimalFormat(status);
705    if(U_FAILURE(status)) {
706      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
707      delete df;
708      return;
709    }
710    failure(status, "new DecimalFormat");
711    UnicodeString sb;
712    FieldPosition fp(FieldPosition::DONT_CARE);
713    //try {
714        for (int i = 17; i <= 20; i++) {
715            df->setMaximumFractionDigits(i);
716            //sb = new StringBuffer("");
717            fp.setField(0);
718            logln(UnicodeString("  getMaximumFractionDigits() = ") + i);
719            logln(UnicodeString("  formated: ") + df->format(d, sb, fp));
720        }
721    /*} catch (Exception foo) {
722        errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
723    }*/
724
725    delete df;
726}
727/* @bug 4095713
728 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
729 */
730void NumberFormatRegressionTest::Test4095713 (void)
731{
732    UErrorCode status = U_ZERO_ERROR;
733    DecimalFormat *df = new DecimalFormat(status);
734    if(U_FAILURE(status)) {
735      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
736      delete df;
737      return;
738    }
739    failure(status, "new DecimalFormat");
740    UnicodeString str("0.1234");
741    double d1 = 0.1234;
742    //Double d1 = new Double(str);
743    //Double d2 = (Double) df.parse(str, new ParsePosition(0));
744    Formattable d2;
745    ParsePosition pp(0);
746    df->parse(str, d2, pp);
747    logln(UnicodeString("") + d1);
748    if (d2.getDouble() != d1)
749        errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2.getDouble());
750    delete df;
751}
752
753/* @bug 4092561
754 * DecimalFormat.parse() fails when multiplier is not set to 1
755 */
756// {sfb} not sure what to do with this one
757void NumberFormatRegressionTest::Test4092561 (void)
758{
759    UErrorCode status = U_ZERO_ERROR;
760    DecimalFormat *df = new DecimalFormat(status);
761    if(U_FAILURE(status)) {
762      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
763      delete df;
764      return;
765    }
766    failure(status, "new DecimalFormat");
767
768    // {sfb} going to cheat here and use sprintf ??
769
770    /*UnicodeString str = Long.toString(Long.MIN_VALUE);
771    logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
772    df.setMultiplier(100);
773    Number num = df.parse(str, new ParsePosition(0));
774    if (num.doubleValue() != -9.223372036854776E16)
775        errln("Bug 4092561 test failed when multiplier is set to not 1.");
776*/
777    delete df;
778}
779
780/* @bug 4092480
781 * DecimalFormat: Negative format ignored.
782 */
783void NumberFormatRegressionTest::Test4092480 (void)
784{
785    UErrorCode status = U_ZERO_ERROR;
786    DecimalFormat *dfFoo = new DecimalFormat(UnicodeString("000"), status);
787    if(U_FAILURE(status)) {
788      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
789      delete dfFoo;
790      return;
791    }
792    failure(status, "new DecimalFormat");
793
794    //try {
795        dfFoo->applyPattern("0000;-000", status);
796        failure(status, "dfFoo->applyPattern");
797        UnicodeString temp;
798        if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
799            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
800        FieldPosition pos(FieldPosition::DONT_CARE);
801        logln(dfFoo->format((int32_t)42, temp, pos));
802        logln(dfFoo->format((int32_t)-42, temp, pos));
803        dfFoo->applyPattern("000;-000", status);
804        failure(status, "dfFoo->applyPattern");
805        if (dfFoo->toPattern(temp) != UnicodeString("#000"))
806            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
807        logln(dfFoo->format((int32_t)42,temp, pos));
808        logln(dfFoo->format((int32_t)-42, temp, pos));
809
810        dfFoo->applyPattern("000;-0000", status);
811        failure(status, "dfFoo->applyPattern");
812        if (dfFoo->toPattern(temp) != UnicodeString("#000"))
813            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
814        logln(dfFoo->format((int32_t)42, temp, pos));
815        logln(dfFoo->format((int32_t)-42, temp, pos));
816
817        dfFoo->applyPattern("0000;-000", status);
818        failure(status, "dfFoo->applyPattern");
819        if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
820            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
821        logln(dfFoo->format((int32_t)42, temp, pos));
822        logln(dfFoo->format((int32_t)-42, temp, pos));
823    /*} catch (Exception foo) {
824        errln("Message " + foo.getMessage());
825    }*/
826
827    delete dfFoo;
828}
829/* @bug 4087244
830 * NumberFormat.getCurrencyInstance() produces format that uses
831 * decimal separator instead of monetary decimal separator.
832 *
833 * Rewrote this test not to depend on the actual pattern.  Pattern should
834 * never contain the monetary separator!  Decimal separator in pattern is
835 * interpreted as monetary separator if currency symbol is seen!
836 */
837void NumberFormatRegressionTest::Test4087244 (void) {
838    UErrorCode status = U_ZERO_ERROR;
839    char loc[256] = {0};
840    uloc_canonicalize("pt_PT_PREEURO", loc, 256, &status);
841    Locale *de = new Locale(loc);
842    NumberFormat *nf = NumberFormat::createCurrencyInstance(*de, status);
843    if(U_FAILURE(status)) {
844      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
845      delete nf;
846      return;
847    }
848    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
849    if(df == NULL) {
850        errln("expected DecimalFormat!");
851        return;
852    }
853    const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols();
854    UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
855    UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
856    if (decSep == monSep) {
857        errln("ERROR in test: want decimal sep != monetary sep");
858        return;
859    }
860    df->setMinimumIntegerDigits(1);
861    df->setMinimumFractionDigits(2);
862    UnicodeString str;
863    FieldPosition pos;
864    df->format(1.23, str, pos);
865    UnicodeString monStr("1x23");
866    monStr.replace((int32_t)1, 1, monSep);
867    UnicodeString decStr("1x23");
868    decStr.replace((int32_t)1, 1, decSep);
869    if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {
870        logln(UnicodeString("OK: 1.23 -> \"") + str + "\" contains \"" +
871              monStr + "\" and not \"" + decStr + '"');
872    } else {
873        errln(UnicodeString("FAIL: 1.23 -> \"") + str + "\", should contain \"" +
874              monStr +
875              "\" and not \"" + decStr + '"');
876    }
877    delete de;
878    delete nf;
879}
880/* @bug 4070798
881 * Number format data rounding errors for locale FR
882 */
883void NumberFormatRegressionTest::Test4070798 (void)
884{
885    NumberFormat *formatter;
886    UnicodeString tempString;
887
888    /* User error :
889    String expectedDefault = "-5\u00a0789,987";
890    String expectedCurrency = "5\u00a0789,98\u00a0F";
891    String expectedPercent = "-578\u00a0998%";
892    */
893    UChar chars1 [] = {
894        0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
895    };
896    UChar chars2 [] = {
897        0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
898    };
899    UChar chars3 [] = {
900        0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
901    };
902    UnicodeString expectedDefault(chars1, 10, 10);
903    UnicodeString expectedCurrency(chars2, 10, 10);
904    UnicodeString expectedPercent(chars3, 10, 10);
905
906    UErrorCode status = U_ZERO_ERROR;
907    char loc[256]={0};
908    int len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
909    formatter = NumberFormat::createInstance(Locale(loc), status);
910    if(U_FAILURE(status)) {
911      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
912      delete formatter;
913      return;
914    }
915    failure(status, "NumberFormat::createNumberInstance", loc);
916    tempString = formatter->format (-5789.9876, tempString);
917
918    if (tempString == expectedDefault) {
919        logln ("Bug 4070798 default test passed.");
920    } else {
921        errln(UnicodeString("Failed:") +
922        " Expected " + expectedDefault +
923        " Received " + tempString );
924    }
925    delete formatter;
926    len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
927    formatter = NumberFormat::createCurrencyInstance(loc, status);
928    failure(status, "NumberFormat::createCurrencyInstance", loc);
929    tempString.remove();
930    tempString = formatter->format( 5789.9876, tempString );
931
932    if (tempString == expectedCurrency) {
933        logln ("Bug 4070798 currency test passed.");
934    } else {
935        errln(UnicodeString("Failed:") +
936        " Expected " + expectedCurrency +
937        " Received " + tempString );
938    }
939    delete formatter;
940
941    uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
942    formatter = NumberFormat::createPercentInstance(Locale(loc), status);
943    failure(status, "NumberFormat::createPercentInstance", loc);
944    tempString.remove();
945    tempString = formatter->format (-5789.9876, tempString);
946
947    if (tempString == expectedPercent) {
948        logln ("Bug 4070798 percentage test passed.");
949    } else {
950        errln(UnicodeString("Failed:") +
951        " Expected " + expectedPercent +
952        " Received " + tempString );
953    }
954
955    delete formatter;
956}
957/* @bug 4071005
958 * Data rounding errors for French (Canada) locale
959 */
960void NumberFormatRegressionTest::Test4071005 (void)
961{
962    NumberFormat *formatter;
963    UnicodeString tempString;
964    /* User error :
965    String expectedDefault = "-5\u00a0789,987";
966    String expectedCurrency = "5\u00a0789,98\u00a0$";
967    String expectedPercent = "-578\u00a0998%";
968    */
969    UChar chars1 [] = {
970        0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
971    };
972    UChar chars2 [] = {
973        0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
974    };
975    UChar chars3 [] = {
976        0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
977    };
978    UnicodeString expectedDefault(chars1, 10, 10);
979    UnicodeString expectedCurrency(chars2, 10, 10);
980    UnicodeString expectedPercent(chars3, 10, 10);
981
982    UErrorCode status = U_ZERO_ERROR;
983    formatter = NumberFormat::createInstance(Locale::getCanadaFrench(), status);
984    if (failure(status, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE)){
985        delete formatter;
986        return;
987    };
988    tempString = formatter->format (-5789.9876, tempString);
989
990    if (tempString == expectedDefault) {
991        logln ("Bug 4071005 default test passed.");
992    } else {
993        errln(UnicodeString("Failed:") +
994        " Expected " + expectedDefault +
995        " Received " + tempString );
996    }
997    delete formatter;
998
999    formatter = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
1000    failure(status, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
1001    tempString.remove();
1002    tempString = formatter->format( 5789.9876, tempString );
1003
1004    if (tempString == expectedCurrency) {
1005        logln ("Bug 4071005 currency test assed.");
1006    } else {
1007        errln(UnicodeString("Failed:") +
1008        " Expected " + expectedCurrency +
1009        " Received " + tempString );
1010    }
1011    delete formatter;
1012
1013    formatter = NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status);
1014    failure(status, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
1015    tempString.remove();
1016    tempString = formatter->format (-5789.9876, tempString);
1017
1018    if (tempString == expectedPercent) {
1019        logln ("Bug 4071005 percentage test passed.");
1020    } else {
1021        errln(UnicodeString("Failed:") +
1022        " Expected " + expectedPercent +
1023        " Received " + tempString );
1024    }
1025
1026    delete formatter;
1027}
1028
1029/* @bug 4071014
1030 * Data rounding errors for German (Germany) locale
1031 */
1032void NumberFormatRegressionTest::Test4071014 (void)
1033{
1034    NumberFormat *formatter;
1035    UnicodeString tempString;
1036    /* user error :
1037    String expectedDefault = "-5.789,987";
1038    String expectedCurrency = "5.789,98 DEM";
1039    String expectedPercent = "-578.998%";
1040    */
1041    UnicodeString expectedDefault("-5.789,988");
1042    UnicodeString expectedCurrency("5.789,99\\u00A0DEM");
1043    UnicodeString expectedPercent("-578.999\\u00A0%");
1044
1045    expectedCurrency = expectedCurrency.unescape();
1046    expectedPercent = expectedPercent.unescape();
1047
1048    UErrorCode status = U_ZERO_ERROR;
1049    char loc[256]={0};
1050    uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
1051    formatter = NumberFormat::createInstance(Locale(loc), status);
1052    if (failure(status, "NumberFormat::createNumberInstance", loc, TRUE)){
1053        delete formatter;
1054        return;
1055    }
1056    tempString.remove();
1057    tempString = formatter->format (-5789.9876, tempString);
1058
1059    if (tempString == expectedDefault) {
1060        logln ("Bug 4071014 default test passed.");
1061    } else {
1062        errln(UnicodeString("Failed:") +
1063        " Expected " + expectedDefault +
1064        " Received " + tempString );
1065    }
1066    delete formatter;
1067    uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
1068    formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
1069    failure(status, "NumberFormat::createCurrencyInstance", loc);
1070    tempString.remove();
1071    tempString = formatter->format( 5789.9876, tempString );
1072
1073    if (tempString == expectedCurrency) {
1074        logln ("Bug 4071014 currency test assed.");
1075    } else {
1076        errln(UnicodeString("Failed:") +
1077        " Expected " + expectedCurrency +
1078        " Received " + tempString );
1079    }
1080    delete formatter;
1081
1082    formatter = NumberFormat::createPercentInstance(Locale::getGermany(), status);
1083    failure(status, "NumberFormat::createPercentInstance", Locale::getGermany());
1084    tempString.remove();
1085    tempString = formatter->format (-5789.9876, tempString);
1086
1087    if (tempString == expectedPercent) {
1088        logln ("Bug 4071014 percentage test passed.");
1089    } else {
1090        errln(UnicodeString("Failed:") +
1091        " Expected " + expectedPercent +
1092        " Received " + tempString );
1093    }
1094
1095    delete formatter;
1096}
1097/* @bug 4071859
1098 * Data rounding errors for Italian locale number formats
1099 */
1100void NumberFormatRegressionTest::Test4071859 (void)
1101{
1102    NumberFormat *formatter;
1103    UnicodeString tempString;
1104    /* user error :
1105    String expectedDefault = "-5.789,987";
1106    String expectedCurrency = "-L.\\u00A05.789,98";
1107    String expectedPercent = "-578.998%";
1108    */
1109    UnicodeString expectedDefault("-5.789,988");
1110    UnicodeString expectedCurrency("-ITL\\u00A05.790", -1, US_INV);
1111    UnicodeString expectedPercent("-578.999%");
1112    expectedCurrency = expectedCurrency.unescape();
1113
1114    UErrorCode status = U_ZERO_ERROR;
1115    char loc[256]={0};
1116    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1117    formatter = NumberFormat::createInstance(Locale(loc), status);
1118    if (failure(status, "NumberFormat::createNumberInstance", TRUE)){
1119        delete formatter;
1120        return;
1121    };
1122    tempString = formatter->format (-5789.9876, tempString);
1123
1124    if (tempString == expectedDefault) {
1125        logln ("Bug 4071859 default test passed.");
1126    } else {
1127        errln(UnicodeString("Failed:") +
1128        " Expected " + expectedDefault +
1129        " Received " + tempString );
1130    }
1131    delete formatter;
1132    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1133    formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
1134    failure(status, "NumberFormat::createCurrencyInstance");
1135    tempString.remove();
1136    tempString = formatter->format( -5789.9876, tempString );
1137
1138    if (tempString == expectedCurrency) {
1139        logln ("Bug 4071859 currency test assed.");
1140    } else {
1141        errln(UnicodeString("Failed:") +
1142        " Expected " + expectedCurrency +
1143        " Received " + tempString );
1144    }
1145    delete formatter;
1146    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1147    formatter = NumberFormat::createPercentInstance(Locale(loc), status);
1148    failure(status, "NumberFormat::createPercentInstance");
1149    tempString.remove();
1150    tempString = formatter->format (-5789.9876, tempString);
1151
1152    if (tempString == expectedPercent) {
1153        logln ("Bug 4071859 percentage test passed.");
1154    } else {
1155        errln(UnicodeString("Failed:") +
1156        " Expected " + expectedPercent +
1157        " Received " + tempString );
1158    }
1159
1160    delete formatter;
1161}
1162/* @bug 4071859
1163 * Test rounding for nearest even.
1164 */
1165void NumberFormatRegressionTest::Test4093610(void)
1166{
1167    UErrorCode status = U_ZERO_ERROR;
1168    DecimalFormat *df = new DecimalFormat("#0.#", status);
1169    if (!failure(status, "new DecimalFormat")) {
1170        UnicodeString s("12.4");
1171        roundingTest(df, 12.35, s);
1172        roundingTest(df, 12.45, s);
1173        s = "12.5";
1174        roundingTest(df, 12.452,s);
1175        s = "12.6";
1176        roundingTest(df, 12.55, s);
1177        roundingTest(df, 12.65, s);
1178        s = "12.7";
1179        roundingTest(df, 12.652,s);
1180        s = "12.8";
1181        roundingTest(df, 12.75, s);
1182        roundingTest(df, 12.752,s);
1183        roundingTest(df, 12.85, s);
1184        s = "12.9";
1185        roundingTest(df, 12.852,s);
1186        s = "13";
1187        roundingTest(df, 12.95, s);
1188        roundingTest(df, 12.952,s);
1189    }
1190
1191    delete df;
1192}
1193
1194void NumberFormatRegressionTest::roundingTest(DecimalFormat *df, double x, UnicodeString& expected)
1195{
1196    UnicodeString out;
1197    FieldPosition pos(FieldPosition::DONT_CARE);
1198    out = df->format(x, out, pos);
1199    logln(UnicodeString("") + x + " formats with 1 fractional digits to " + out);
1200    if (out != expected)
1201        errln("FAIL: Expected " + expected);
1202}
1203/* @bug 4098741
1204 * Tests the setMaximumFractionDigits limit.
1205 */
1206void NumberFormatRegressionTest::Test4098741(void)
1207{
1208    //try {
1209    UErrorCode status = U_ZERO_ERROR;
1210    NumberFormat *fmt = NumberFormat::createPercentInstance(status);
1211    if (U_FAILURE(status)) {
1212        dataerrln("Error calling NumberFormat::createPercentInstance");
1213        delete fmt;
1214        return;
1215    }
1216
1217        fmt->setMaximumFractionDigits(20);
1218        UnicodeString temp;
1219        logln(fmt->format(.001, temp));
1220    /*} catch (Exception foo) {
1221        errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1222    }*/
1223    delete fmt;
1224}
1225/* @bug 4074454
1226 * Tests illegal pattern exception.
1227 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1228 * Part2 has been fixed.
1229 */
1230void NumberFormatRegressionTest::Test4074454(void)
1231{
1232    //try {
1233    UErrorCode status = U_ZERO_ERROR;
1234    DecimalFormat *fmt = new DecimalFormat("#,#00.00;-#.#", status);
1235    if(U_FAILURE(status)) {
1236      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1237      delete fmt;
1238      return;
1239    }
1240    failure(status, "new DecimalFormat");
1241      logln("Inconsistent negative pattern is fine.");
1242        DecimalFormat *newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status);
1243        failure(status, "new DecimalFormat");
1244        UnicodeString tempString;
1245        FieldPosition pos(FieldPosition::DONT_CARE);
1246        tempString = newFmt->format(3456.78, tempString, pos);
1247        if (tempString != UnicodeString("3,456.78 p'ieces"))
1248            dataerrln("Failed!  3456.78 p'ieces expected, but got : " + tempString);
1249    /*} catch (Exception foo) {
1250        errln("An exception was thrown for any inconsistent negative pattern.");
1251    }*/
1252
1253    delete fmt;
1254    delete newFmt;
1255}
1256/* @bug 4099404
1257 * Tests all different comments.
1258 * Response to some comments :
1259 * [1] DecimalFormat.parse API documentation is more than just one line.
1260 * This is not a reproducable doc error in 116 source code.
1261 * [2] See updated javadoc.
1262 * [3] Fixed.
1263 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1264 * a null object will be returned.  The unchanged parse position also
1265 * reflects an error.
1266 * NumberFormat.parse(String) : If parsing fails, an ParseException
1267 * will be thrown.
1268 * See updated javadoc for more details.
1269 * [5] See updated javadoc.
1270 * [6] See updated javadoc.
1271 * [7] This is a correct behavior if the DateFormat object is linient.
1272 * Otherwise, an IllegalArgumentException will be thrown when formatting
1273 * "January 35".  See GregorianCalendar class javadoc for more details.
1274 */
1275void NumberFormatRegressionTest::Test4099404(void)
1276{
1277    //try {
1278        UErrorCode status = U_ZERO_ERROR;
1279        DecimalFormat *fmt = new DecimalFormat(UnicodeString("000.0#0"), status);
1280        if(! U_FAILURE(status))
1281            errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1282    /*} catch (Exception foo) {
1283        logln("Bug 4099404 pattern \"000.0#0\" passed");
1284    }*/
1285    delete fmt;
1286    fmt = 0;
1287        //try {
1288        fmt = new DecimalFormat(UnicodeString("0#0.000"), status);
1289        if( !U_FAILURE(status))
1290           errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1291    /*} catch (Exception foo) {
1292        logln("Bug 4099404 pattern \"0#0.000\" passed");
1293    }*/
1294
1295    delete fmt;
1296}
1297/* @bug 4101481
1298 * DecimalFormat.applyPattern doesn't set minimum integer digits
1299 */
1300void NumberFormatRegressionTest::Test4101481(void)
1301{
1302    UErrorCode status = U_ZERO_ERROR;
1303    DecimalFormat *sdf = new DecimalFormat(UnicodeString("#,##0"), status);
1304    if(U_FAILURE(status)) {
1305      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1306      delete sdf;
1307      return;
1308    }
1309    failure(status, "new DecimalFormat");
1310    if (sdf->getMinimumIntegerDigits() != 1)
1311        errln(UnicodeString("Minimum integer digits : ") + sdf->getMinimumIntegerDigits());
1312    delete sdf;
1313}
1314/* @bug 4052223 (API addition request A27)
1315 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1316 */
1317void NumberFormatRegressionTest::Test4052223(void)
1318{
1319    //try {
1320    UErrorCode status = U_ZERO_ERROR;
1321        DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,#00.00"), status);
1322        if(U_FAILURE(status)) {
1323          errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1324          delete fmt;
1325          return;
1326        }
1327        failure(status, "new DecimalFormat");
1328        Formattable num;
1329        fmt->parse(UnicodeString("abc3"), num, status);
1330        if(! U_FAILURE(status))
1331            errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\".  Got ") /*+ num*/);
1332    /*} catch (ParseException foo) {
1333        logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1334    }*/
1335    delete fmt;
1336}
1337/* @bug 4061302
1338 * API tests for API addition request A9.
1339 */
1340void NumberFormatRegressionTest::Test4061302(void)
1341{
1342    UErrorCode status = U_ZERO_ERROR;
1343    DecimalFormatSymbols *fmt = new DecimalFormatSymbols(status);
1344    failure(status, "new DecimalFormatSymbols");
1345    UnicodeString currency(fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
1346    UnicodeString intlCurrency(fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1347    UnicodeString monDecSeparator(fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
1348    if (currency == UnicodeString("") ||
1349        intlCurrency == UnicodeString("") ||
1350        monDecSeparator == UnicodeString(""))
1351    {
1352        errln("getCurrencySymbols failed, got empty string.");
1353    }
1354    UnicodeString monDecSeparatorStr;
1355    monDecSeparatorStr.append(monDecSeparator);
1356    logln((UnicodeString)"Before set ==> Currency : " + currency +(UnicodeString)" Intl Currency : " + intlCurrency + (UnicodeString)" Monetary Decimal Separator : " + monDecSeparatorStr);
1357    fmt->setSymbol(DecimalFormatSymbols::kCurrencySymbol, UnicodeString("XYZ"));
1358    fmt->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, UnicodeString("ABC"));
1359    fmt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString((UChar)0x002A/*'*'*/));
1360    currency = fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
1361    intlCurrency = fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
1362    monDecSeparator = fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1363    if (currency != UnicodeString("XYZ") ||
1364        intlCurrency != UnicodeString("ABC") ||
1365        monDecSeparator != UnicodeString((UChar)0x002A/*'*'*/)) {
1366        errln("setCurrencySymbols failed.");
1367    }
1368    monDecSeparatorStr.remove();
1369    monDecSeparatorStr.append(monDecSeparator);
1370    logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparatorStr);
1371
1372    delete fmt;
1373}
1374/* @bug 4062486
1375 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1376 * FieldPosition.getEndIndex.
1377 */
1378void NumberFormatRegressionTest::Test4062486(void)
1379{
1380    UErrorCode status = U_ZERO_ERROR;
1381    DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,##0.00"), status);
1382    failure(status, "new DecimalFormat");
1383    UnicodeString formatted;
1384    FieldPosition field(0);
1385    double num = 1234.5;
1386    fmt->format(num, formatted, field);
1387    if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)
1388        errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1389    field.setBeginIndex(7);
1390    field.setEndIndex(4);
1391    if (field.getBeginIndex() != 7 && field.getEndIndex() != 4)
1392        errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1393
1394    delete fmt;
1395}
1396
1397/* @bug 4108738
1398 * DecimalFormat.parse incorrectly works with a group separator.
1399 */
1400void NumberFormatRegressionTest::Test4108738(void)
1401{
1402    UErrorCode status = U_ZERO_ERROR;
1403    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getUS(), status);
1404    failure(status, "new DecimalFormatSymbols");
1405    DecimalFormat *df = new DecimalFormat("#,##0.###", syms, status);
1406    if(U_FAILURE(status)) {
1407      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1408      delete df;
1409      return;
1410    }
1411    failure(status, "new DecimalFormat");
1412    UnicodeString text("1.222,111");
1413    Formattable num;
1414    ParsePosition pp(0);
1415    df->parse(text, num, pp);
1416
1417    // {sfb} how to do this (again) ?
1418    // shouldn't just be another round-trip test, should it?
1419    UnicodeString temp;
1420    FieldPosition pos(FieldPosition::DONT_CARE);
1421    temp = df->format(num.getDouble(), temp, pos);
1422    //if (!num.toString().equals("1.222"))
1423    if (temp != UnicodeString("1.222"))
1424        //errln("\"" + text + "\"  is parsed as " + num);
1425        errln("\"" + text + "\"  is parsed as " + temp);
1426    text = UnicodeString("1.222x111");
1427    pp = ParsePosition(0);
1428    df->parse(text, num, pp);
1429    temp.remove();
1430    temp = df->format(num.getDouble(), temp, pos);
1431    //if (!num.toString().equals("1.222"))
1432    if (temp != UnicodeString("1.222"))
1433        errln("\"" + text + "\"  is parsed as " + temp);
1434
1435    delete df;
1436}
1437
1438/* @bug 4106658
1439 * DecimalFormat.format() incorrectly formats negative doubles.
1440 */
1441void NumberFormatRegressionTest::Test4106658(void)
1442{
1443    UErrorCode status = U_ZERO_ERROR;
1444    DecimalFormat *df = new DecimalFormat(status); // Corrected; see 4147706
1445    if(U_FAILURE(status)) {
1446      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1447      delete df;
1448      return;
1449    }
1450    failure(status, "new DecimalFormat");
1451    volatile double d1 = 0.0;   // volatile to prevent code optimization
1452    double d2 = -0.0001;
1453    UnicodeString buffer;
1454    UnicodeString temp;
1455    FieldPosition pos(FieldPosition::DONT_CARE);
1456
1457#if U_PLATFORM == U_PF_HPUX
1458    d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
1459#else
1460    d1 *= -1.0; // Some compilers have a problem with defining -0.0
1461#endif
1462    logln("pattern: \"" + df->toPattern(temp) + "\"");
1463    df->format(d1, buffer, pos);
1464    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1465        errln(UnicodeString("") + d1 + "      is formatted as " + buffer);
1466    buffer.remove();
1467    df->format(d2, buffer, pos);
1468    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1469        errln(UnicodeString("") + d2 + "      is formatted as " + buffer);
1470
1471    delete df;
1472}
1473
1474/* @bug 4106662
1475 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1476 */
1477void NumberFormatRegressionTest::Test4106662(void)
1478{
1479    UErrorCode status = U_ZERO_ERROR;
1480    DecimalFormat *df = new DecimalFormat(status);
1481    if(U_FAILURE(status)) {
1482      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1483      delete df;
1484      return;
1485    }
1486    failure(status, "new DecimalFormat");
1487    UnicodeString text("x");
1488    ParsePosition pos1(0), pos2(0);
1489
1490    UnicodeString temp;
1491    logln("pattern: \"" + df->toPattern(temp) + "\"");
1492    Formattable num;
1493    df->parse(text, num, pos1);
1494    if (pos1 == ParsePosition(0)/*num != null*/) {
1495        errln(UnicodeString("Test Failed: \"") + text + "\" is parsed as " /*+ num*/);
1496    }
1497    delete df;
1498    df = new DecimalFormat(UnicodeString("$###.00"), status);
1499    failure(status, "new DecimalFormat");
1500    df->parse(UnicodeString("$"), num, pos2);
1501    if (pos2 == ParsePosition(0) /*num != null*/){
1502        errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1503    }
1504
1505    delete df;
1506}
1507
1508/* @bug 4114639 (duplicate of 4106662)
1509 * NumberFormat.parse doesn't return null
1510 */
1511void NumberFormatRegressionTest::Test4114639(void)
1512{
1513    UErrorCode status = U_ZERO_ERROR;
1514    NumberFormat *format = NumberFormat::createInstance(status);
1515    if(U_FAILURE(status)) {
1516      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
1517      delete format;
1518      return;
1519    }
1520    failure(status, "NumberFormat::createInstance");
1521    UnicodeString text("time 10:x");
1522    ParsePosition pos(8);
1523    Formattable result;
1524    format->parse(text, result, pos);
1525    if (/*result != null*/pos.getErrorIndex() != 8)
1526        errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1527
1528    delete format;
1529}
1530
1531/* @bug 4106664
1532 * TODO: this test does not work because we need to use a 64 bit number and a
1533 * a double only MAY only have 52 bits of precision.
1534 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1535 */
1536void NumberFormatRegressionTest::Test4106664(void)
1537{
1538    UErrorCode status = U_ZERO_ERROR;
1539    DecimalFormat *df = new DecimalFormat(status);
1540    if(U_FAILURE(status)) {
1541      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1542      delete df;
1543      return;
1544    }
1545    failure(status, "new DecimalFormat");
1546    // {sfb} long in java is 64 bits
1547    /*long*/double n = 1234567890123456.0;
1548    /*int*/int32_t m = 12345678;
1549    // {sfb} will this work?
1550    //BigInteger bigN = BigInteger.valueOf(n);
1551    //bigN = bigN.multiply(BigInteger.valueOf(m));
1552    double bigN = n * m;
1553    df->setMultiplier(m);
1554    df->setGroupingUsed(FALSE);
1555    UnicodeString temp;
1556    FieldPosition pos(FieldPosition::DONT_CARE);
1557    logln("formated: " +
1558        df->format(n, temp, pos));
1559
1560    char buf [128];
1561    sprintf(buf, "%g", bigN);
1562    //logln("expected: " + bigN.toString());
1563    logln(UnicodeString("expected: ") + buf);
1564
1565    delete df;
1566}
1567/* @bug 4106667 (duplicate of 4106658)
1568 * DecimalFormat.format incorrectly formats -0.0.
1569 */
1570void NumberFormatRegressionTest::Test4106667(void)
1571{
1572    UErrorCode status = U_ZERO_ERROR;
1573    DecimalFormat *df = new DecimalFormat(status);
1574    if(U_FAILURE(status)) {
1575      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1576      delete df;
1577      return;
1578    }
1579    failure(status, "new DecimalFormat");
1580    UChar foo [] = { 0x002B };
1581    UnicodeString bar(foo, 1, 1);
1582    volatile double d = 0.0;   // volatile to prevent code optimization
1583    UnicodeString temp;
1584    UnicodeString buffer;
1585    FieldPosition pos(FieldPosition::DONT_CARE);
1586
1587    logln("pattern: \"" + df->toPattern(temp) + "\"");
1588#if U_PLATFORM == U_PF_HPUX
1589    d = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
1590#else
1591    d *= -1.0; // Some compilers have a problem with defining -0.0
1592#endif
1593    df->setPositivePrefix(/*"+"*/bar);
1594    df->format(d, buffer, pos);
1595    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1596        errln(/*d + */UnicodeString("  is formatted as ") + buffer);
1597
1598    delete df;
1599}
1600
1601/* @bug 4110936
1602 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1603 */
1604#if U_PLATFORM == U_PF_OS390
1605#   define MAX_INT_DIGITS 70
1606#else
1607#   define MAX_INT_DIGITS 128
1608#endif
1609
1610void NumberFormatRegressionTest::Test4110936(void)
1611{
1612    UErrorCode status = U_ZERO_ERROR;
1613    NumberFormat *nf = NumberFormat::createInstance(status);
1614    if(U_FAILURE(status)) {
1615      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
1616      delete nf;
1617      return;
1618    }
1619    failure(status, "NumberFormat::createInstance");
1620    nf->setMaximumIntegerDigits(MAX_INT_DIGITS);
1621    logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1622    if (nf->getMaximumIntegerDigits() != MAX_INT_DIGITS)
1623        errln(UnicodeString("getMaximumIntegerDigits() returns ") +
1624            nf->getMaximumIntegerDigits());
1625
1626    delete nf;
1627}
1628
1629/* @bug 4122840
1630 * Locale data should use generic currency symbol
1631 *
1632 * 1) Make sure that all currency formats use the generic currency symbol.
1633 * 2) Make sure we get the same results using the generic symbol or a
1634 *    hard-coded one.
1635 */
1636void NumberFormatRegressionTest::Test4122840(void)
1637{
1638    int32_t count = 0;
1639    const Locale *locales = Locale::getAvailableLocales(count);
1640
1641    for (int i = 0; i < count; i++) {
1642        UErrorCode status = U_ZERO_ERROR;
1643        ResourceBundle *rb = new ResourceBundle(
1644            NULL/*"java.text.resources.LocaleElements"*/,
1645            locales[i], status);
1646        failure(status, "new ResourceBundle");
1647        ResourceBundle numPat = rb->getWithFallback("NumberElements", status);
1648        failure(status, "rb.get(NumberElements)");
1649        numPat = numPat.getWithFallback("latn",status);
1650        failure(status, "rb.get(latn)");
1651        numPat = numPat.getWithFallback("patterns",status);
1652        failure(status, "rb.get(patterns)");
1653        numPat = numPat.getWithFallback("currencyFormat",status);
1654        failure(status, "rb.get(currencyFormat)");
1655       //
1656        // Get the currency pattern for this locale.  We have to fish it
1657        // out of the ResourceBundle directly, since DecimalFormat.toPattern
1658        // will return the localized symbol, not \00a4
1659        //
1660        UnicodeString pattern = numPat.getString(status);
1661        failure(status, "rb->getString()");
1662
1663        UChar fo[] = { 0x00A4 };
1664        UnicodeString foo(fo, 1, 1);
1665
1666        //if (pattern.indexOf("\u00A4") == -1 ) {
1667        if (pattern.indexOf(foo) == -1 ) {
1668            errln(UnicodeString("Currency format for ") + UnicodeString(locales[i].getName()) +
1669                    " does not contain generic currency symbol:" +
1670                    pattern );
1671        }
1672
1673        // Create a DecimalFormat using the pattern we got and format a number
1674        DecimalFormatSymbols *symbols = new DecimalFormatSymbols(locales[i], status);
1675        failure(status, "new DecimalFormatSymbols");
1676        DecimalFormat *fmt1 = new DecimalFormat(pattern, *symbols, status);
1677        failure(status, "new DecimalFormat");
1678
1679        UnicodeString result1;
1680        FieldPosition pos(FieldPosition::DONT_CARE);
1681        result1 = fmt1->format(1.111, result1, pos);
1682
1683        //
1684        // Now substitute in the locale's currency symbol and create another
1685        // pattern.  We have to skip locales where the currency symbol
1686        // contains decimal separators, because that confuses things
1687        //
1688        UChar ba[] = { 0x002E/*'.'*/ };
1689        UnicodeString bar(ba, 1, 1);
1690
1691        if (symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).indexOf(bar) == -1) {
1692            // {sfb} Also, switch the decimal separator to the monetary decimal
1693            // separator to mimic the behavior of a currency format
1694            symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol,
1695                symbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
1696
1697            UnicodeString buf(pattern);
1698            for (int j = 0; j < buf.length(); j++) {
1699                if (buf[j] == 0x00a4 ) {
1700                    if(buf[j + 1] == 0x00a4) {
1701                        // {sfb} added to support double currency marker (intl currency sign)
1702                        buf.replace(j, /*j+*/2, symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1703                        j += symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol).length();
1704                    }
1705                    else {
1706                        buf.replace(j, /*j+*/1, symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
1707                        j += symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).length() - 1;
1708                    }
1709                }
1710            }
1711
1712            DecimalFormat *fmt2 = new DecimalFormat(buf, *symbols, status);
1713            failure(status, "new DecimalFormat");
1714
1715            // Get the currency (if there is one) so we can set the rounding and fraction
1716            const UChar *currency = fmt1->getCurrency();
1717            if (*currency != 0) {
1718                double rounding = ucurr_getRoundingIncrement(currency, &status);
1719                int32_t frac = ucurr_getDefaultFractionDigits(currency, &status);
1720                if (U_SUCCESS(status)) {
1721                    fmt2->setRoundingIncrement(rounding);
1722                    fmt2->setMinimumFractionDigits(frac);
1723                    fmt2->setMaximumFractionDigits(frac);
1724                }
1725                else {
1726                    failure(status, "Fetching currency rounding/fractions");
1727                }
1728            }
1729
1730            UnicodeString result2;
1731            fmt2->format(1.111, result2, pos);
1732
1733            if (result1 != result2) {
1734                errln("Results for " + (UnicodeString)(locales[i].getName()) + " differ: " +
1735                        result1 + " vs " + result2);
1736            }
1737
1738            delete fmt2;
1739        }
1740
1741        delete rb;
1742        delete fmt1;
1743        delete symbols;
1744    }
1745}
1746
1747/* @bug 4125885
1748 * DecimalFormat.format() delivers wrong string.
1749 */
1750void NumberFormatRegressionTest::Test4125885(void)
1751{
1752    UErrorCode status = U_ZERO_ERROR;
1753    double rate = 12.34;
1754    DecimalFormat *formatDec = new DecimalFormat ("000.00", status);
1755    if(U_FAILURE(status)) {
1756      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1757      delete formatDec;
1758      return;
1759    }
1760    failure(status, "new DecimalFormat");
1761    UnicodeString temp;
1762    logln("toPattern: " + formatDec->toPattern(temp));
1763    UnicodeString rateString;
1764    FieldPosition pos(FieldPosition::DONT_CARE);
1765    rateString = formatDec->format(rate, rateString, pos);
1766    if (rateString != UnicodeString("012.34"))
1767        errln("result : " + rateString + " expected : 012.34");
1768    rate = 0.1234;
1769    delete formatDec;// = null;
1770    formatDec = new DecimalFormat ("+000.00%;-000.00%", status);
1771    failure(status, "new DecimalFormat");
1772    logln("toPattern: " + formatDec->toPattern(temp));
1773    rateString.remove();
1774    rateString = formatDec->format(rate, rateString, pos);
1775    if (rateString != UnicodeString("+012.34%"))
1776        errln("result : " + rateString + " expected : +012.34%");
1777
1778    delete formatDec;
1779}
1780
1781/**
1782 * @bug 4134034
1783 * DecimalFormat produces extra zeros when formatting numbers.
1784 */
1785void NumberFormatRegressionTest::Test4134034(void)
1786{
1787    UErrorCode status = U_ZERO_ERROR;
1788    DecimalFormat *nf = new DecimalFormat("##,###,###.00", status);
1789    if (!failure(status, "new DecimalFormat")) {
1790        UnicodeString f;
1791        FieldPosition pos(FieldPosition::DONT_CARE);
1792        f = nf->format(9.02, f, pos);
1793        if (f == UnicodeString("9.02"))
1794            logln(f + " ok");
1795        else
1796            errln("9.02 -> " + f + "; want 9.02");
1797
1798        f.remove();
1799        f = nf->format((int32_t)0, f, pos);
1800        if (f == UnicodeString(".00"))
1801            logln(f + " ok");
1802        else
1803            errln("0 -> " + f + "; want .00");
1804    }
1805
1806    delete nf;
1807}
1808
1809/**
1810 * @bug 4134300
1811 * CANNOT REPRODUCE - This bug could not be reproduced.  It may be
1812 * a duplicate of 4134034.
1813 *
1814 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1815 * Possibly related to bug 4125885.
1816 *
1817 * This class demonstrates a regression in version 1.1.6
1818 * of DecimalFormat class.
1819 *
1820 * 1.1.6 Results
1821 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1822 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1823 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1824 * Value 1.2 Format #0.0# Result '1.2'
1825 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1826 *
1827 * 1.1.5 Results
1828 * Value 1.2 Format #.00 Result '1.20'
1829 * Value 1.2 Format 0.00 Result '1.20'
1830 * Value 1.2 Format 00.00 Result '01.20'
1831 * Value 1.2 Format #0.0# Result '1.2'
1832 * Value 1.2 Format #0.00 Result '1.20'
1833 */
1834void NumberFormatRegressionTest::Test4134300(void) {
1835    UnicodeString DATA [] = {
1836     // Pattern      Expected string
1837        UnicodeString("#.00"),      UnicodeString("1.20"),
1838        UnicodeString("0.00"),      UnicodeString("1.20"),
1839        UnicodeString("00.00"),     UnicodeString("01.20"),
1840        UnicodeString("#0.0#"),     UnicodeString("1.2"),
1841        UnicodeString("#0.00"),     UnicodeString("1.20")
1842    };
1843
1844    for (int i=0; i< 10; i+=2) {
1845        UnicodeString result;
1846        UErrorCode status = U_ZERO_ERROR;
1847        DecimalFormat *df = new DecimalFormat(DATA[i], status);
1848        if (!failure(status, "new DecimalFormat")) {
1849            FieldPosition pos(FieldPosition::DONT_CARE);
1850            result = df->format(1.2, result, pos);
1851            if (result != DATA[i+1]) {
1852                errln("Fail: 1.2 x " + DATA[i] + " = " + result +
1853                      "; want " + DATA[i+1]);
1854            }
1855            else {
1856                logln("Ok: 1.2 x " + DATA[i] + " = " + result);
1857            }
1858        }
1859
1860        delete df;
1861    }
1862}
1863
1864/**
1865 * @bug 4140009
1866 * Empty pattern produces double negative prefix.
1867 */
1868void NumberFormatRegressionTest::Test4140009(void)
1869{
1870    UErrorCode status = U_ZERO_ERROR;
1871    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
1872    failure(status, "new DecimalFormatSymbols");
1873    DecimalFormat *f = new DecimalFormat(UnicodeString(""), syms, status);
1874    if (!failure(status, "new DecimalFormat")) {
1875        UnicodeString s;
1876        FieldPosition pos(FieldPosition::DONT_CARE);
1877        s = f->format(123.456, s, pos);
1878        if (s != UnicodeString("123.456"))
1879            errln("Fail: Format empty pattern x 123.456 => " + s);
1880        s.remove();
1881        s = f->format(-123.456, s, pos);
1882        if (s != UnicodeString("-123.456"))
1883            errln("Fail: Format empty pattern x -123.456 => " + s);
1884    }
1885    delete f;
1886}
1887
1888/**
1889 * @bug 4141750
1890 * BigDecimal numbers get their fractions truncated by NumberFormat.
1891 */
1892// {sfb} not pertinent in C++ ??
1893void NumberFormatRegressionTest::Test4141750(void) {
1894    /*try {
1895        UnicodeString str("12345.67");
1896        BigDecimal bd = new BigDecimal(str);
1897        String sd = NumberFormat.getInstance(Locale.US).format(bd);
1898        if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1899    }
1900    catch (Exception e) {
1901        errln(e.toString());
1902        e.printStackTrace();
1903    }*/
1904}
1905
1906/**
1907 * @bug 4145457
1908 * DecimalFormat toPattern() doesn't quote special characters or handle
1909 * single quotes.
1910 */
1911void NumberFormatRegressionTest::Test4145457() {
1912    //try {
1913    UErrorCode status = U_ZERO_ERROR;
1914    NumberFormat *nff = NumberFormat::createInstance(status);
1915    if (failure(status, "NumberFormat::createInstance", TRUE)){
1916        delete nff;
1917        return;
1918    };
1919    DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff);
1920    if(nf == NULL) {
1921        errln("DecimalFormat needed to continue");
1922        return;
1923    }
1924
1925    DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols();
1926    sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027);
1927    nf->setDecimalFormatSymbols(*sym);
1928    double pi = 3.14159;
1929
1930    UnicodeString PATS [] = {
1931        UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1932    };
1933
1934    for (int32_t i=0; i<2; ++i) {
1935        nf->applyPattern(PATS[i], status);
1936        failure(status, "nf->applyPattern");
1937        UnicodeString out;
1938        FieldPosition pos(FieldPosition::DONT_CARE);
1939        out = nf->format(pi, out, pos);
1940        UnicodeString pat;
1941        pat = nf->toPattern(pat);
1942        Formattable num;
1943        ParsePosition pp(0);
1944        nf->parse(out, num, pp);
1945        double val = num.getDouble();
1946
1947        nf->applyPattern(pat, status);
1948        failure(status, "nf->applyPattern");
1949        UnicodeString out2;
1950        out2 = nf->format(pi, out2, pos);
1951        UnicodeString pat2;
1952        pat2 = nf->toPattern(pat2);
1953        pp.setIndex(0);
1954        nf->parse(out2, num, pp);
1955        double val2 = num.getDouble();
1956
1957        if (pat != pat2)
1958            errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +
1959                pat + "\" vs. \"" + pat2 + "\"");
1960        else
1961            logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"');
1962
1963        if (val == val2 && out == out2) {
1964            logln(UnicodeString("Ok ") + pi + " x \"" + PATS[i] + "\" -> \"" +
1965                out + "\" -> " + val + " -> \"" +
1966                out2 + "\" -> " + val2);
1967        }
1968        else {
1969            errln(UnicodeString("Fail ") + pi + " x \"" + PATS[i] + "\" -> \"" +
1970                out + "\" -> " + val + " -> \"" +
1971                out2 + "\" -> " + val2);
1972        }
1973    }
1974    /*}
1975    catch (ParseException e) {
1976        errln("Fail: " + e);
1977        e.printStackTrace();
1978    }*/
1979
1980    delete nff;
1981}
1982
1983/**
1984 * @bug 4147295
1985 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1986 * CANNOT REPRODUCE
1987 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1988 */
1989void NumberFormatRegressionTest::Test4147295(void)
1990{
1991    UErrorCode status = U_ZERO_ERROR;
1992    DecimalFormat *sdf = new DecimalFormat(status);
1993    UnicodeString pattern("#,###");
1994    logln("Applying pattern \"" + pattern + "\"");
1995    sdf->applyPattern(pattern, status);
1996    if (!failure(status, "sdf->applyPattern")) {
1997        int minIntDig = sdf->getMinimumIntegerDigits();
1998        if (minIntDig != 0) {
1999            errln("Test failed");
2000            errln(UnicodeString(" Minimum integer digits : ") + minIntDig);
2001            UnicodeString temp;
2002            errln(UnicodeString(" new pattern: ") + sdf->toPattern(temp));
2003        } else {
2004            logln("Test passed");
2005            logln(UnicodeString(" Minimum integer digits : ") + minIntDig);
2006        }
2007    }
2008    delete sdf;
2009}
2010
2011/**
2012 * @bug 4147706
2013 * DecimalFormat formats -0.0 as +0.0
2014 * See also older related bug 4106658, 4106667
2015 */
2016void NumberFormatRegressionTest::Test4147706(void)
2017{
2018    UErrorCode status = U_ZERO_ERROR;
2019    DecimalFormat *df = new DecimalFormat("#,##0.0##", status);
2020    failure(status, "new DecimalFormat");
2021    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
2022    if (!failure(status, "new DecimalFormatSymbols")) {
2023        UnicodeString f1;
2024        UnicodeString f2, temp;
2025        FieldPosition pos(FieldPosition::DONT_CARE);
2026        volatile double d1 = 0.0;   // volatile to prevent code optimization
2027        double d2 = -0.0001;
2028
2029#if U_PLATFORM == U_PF_HPUX
2030        d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
2031#else
2032        d1 *= -1.0; // Some compilers have a problem with defining -0.0
2033#endif
2034        df->adoptDecimalFormatSymbols(syms);
2035        f1 = df->format(d1, f1, pos);
2036        f2 = df->format(d2, f2, pos);
2037        if (f1 != UnicodeString("-0.0")) {
2038            errln(UnicodeString("") + d1 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f1 + '"');
2039        }
2040        if (f2 != UnicodeString("-0.0")) {
2041            errln(UnicodeString("") + d2 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f2 + '"');
2042        }
2043    }
2044
2045    delete df;
2046}
2047
2048
2049// Not applicable, since no serialization in C++
2050/*class myformat implements Serializable
2051{
2052DateFormat _dateFormat = DateFormat.getDateInstance();
2053
2054public String Now()
2055{
2056    GregorianCalendar calendar = new GregorianCalendar();
2057    Date t = calendar.getTime();
2058    String nowStr = _dateFormat.format(t);
2059    return nowStr;
2060}
2061}*/
2062
2063/**
2064 * @bug 4162198
2065 * NumberFormat cannot format Double.MAX_VALUE
2066 */
2067// TODO: make this test actually test something
2068void
2069NumberFormatRegressionTest::Test4162198(void)
2070{
2071    // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
2072    double dbl = INT32_MAX * 1000.0;
2073    UErrorCode status = U_ZERO_ERROR;
2074    NumberFormat *f = NumberFormat::createInstance(status);
2075    if(U_FAILURE(status)) {
2076        dataerrln("Couldn't create number format - %s", u_errorName(status));
2077        return;
2078    }
2079    f->setMaximumFractionDigits(INT32_MAX);
2080    f->setMaximumIntegerDigits(INT32_MAX);
2081    UnicodeString s;
2082    f->format(dbl,s);
2083    logln(UnicodeString("The number ") + dbl + " formatted to " + s);
2084    Formattable n;
2085    //try {
2086    f->parse(s, n, status);
2087    if(U_FAILURE(status))
2088        errln("Couldn't parse!");
2089    //} catch (java.text.ParseException e) {
2090    //    errln("Caught a ParseException:");
2091    //    e.printStackTrace();
2092    //}
2093
2094    //logln("The string " + s + " parsed as " + n);
2095
2096    // {dlf} The old code assumes n is a double, but it isn't any more...
2097    // Formattable apparently does not and never did interconvert... too bad.
2098    //if(n.getDouble() != dbl) {
2099    //    errln("Round trip failure");
2100    //}
2101    if (n.getInt64() != dbl) {
2102        errln("Round trip failure");
2103    }
2104
2105    delete f;
2106}
2107
2108/**
2109 * @bug 4162852
2110 * NumberFormat does not parse negative zero.
2111 */
2112void
2113NumberFormatRegressionTest::Test4162852(void)
2114{
2115    UErrorCode status = U_ZERO_ERROR;
2116    for(int32_t i=0; i < 2; ++i) {
2117        NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status)
2118            : NumberFormat::createPercentInstance(status);
2119        if(U_FAILURE(status)) {
2120            dataerrln("Couldn't create number format - %s", u_errorName(status));
2121            return;
2122        }
2123        double d = 0.0;
2124        d *= -1.0;
2125        UnicodeString s;
2126        f->format(d, s);
2127        Formattable n;
2128        f->parse(s, n, status);
2129        if(U_FAILURE(status))
2130            errln("Couldn't parse!");
2131        double e = n.getDouble();
2132        logln(UnicodeString("") +
2133              d + " -> " +
2134              '"' + s + '"' + " -> " + e);
2135#if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400
2136        if (e != 0.0) {
2137#else
2138        if (e != 0.0 || 1.0/e > 0.0) {
2139#endif
2140            logln("Failed to parse negative zero");
2141        }
2142        delete f;
2143    }
2144}
2145
2146static double _u_abs(double a) { return a<0?-a:a; }
2147
2148/**
2149 * May 17 1999 sync up - liu
2150 * @bug 4167494
2151 * NumberFormat truncates data
2152 */
2153void NumberFormatRegressionTest::Test4167494(void) {
2154    UErrorCode status = U_ZERO_ERROR;
2155    NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
2156    if (failure(status, "NumberFormat::createInstance", TRUE)){
2157        delete fmt;
2158        return;
2159    };
2160
2161    double a = DBL_MAX * 0.99; // DBL_MAX itself overflows to +Inf
2162    UnicodeString s;
2163    fmt->format(a, s);
2164    Formattable num;
2165    fmt->parse(s, num, status);
2166    failure(status, "Parse");
2167    if (num.getType() == Formattable::kDouble &&
2168        _u_abs(num.getDouble() - a) / a < 0.01) { // RT within 1%
2169        logln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
2170              toString(num) + " ok");
2171    } else {
2172        errln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
2173              toString(num) + " FAIL");
2174    }
2175
2176    // We don't test Double.MIN_VALUE because the locale data for the US
2177    // currently doesn't specify enough digits to display Double.MIN_VALUE.
2178    // This is correct for now; however, we leave this here as a reminder
2179    // in case we want to address this later.
2180
2181    delete fmt;
2182}
2183
2184/**
2185 * May 17 1999 sync up - liu
2186 * @bug 4170798
2187 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2188 */
2189void NumberFormatRegressionTest::Test4170798(void) {
2190    UErrorCode status = U_ZERO_ERROR;
2191    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2192    if (failure(status, "NumberFormat::createInstance", TRUE)){
2193        delete nf;
2194        return;
2195    };
2196    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
2197    if(df == NULL) {
2198        errln("DecimalFormat needed to continue");
2199        return;
2200    }
2201    df->setParseIntegerOnly(TRUE);
2202    Formattable n;
2203    ParsePosition pos(0);
2204    df->parse("-0.0", n, pos);
2205    if (n.getType() != Formattable::kLong
2206        || n.getLong() != 0) {
2207        errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n));
2208    }
2209    delete nf;
2210}
2211
2212/**
2213 * May 17 1999 sync up - liu
2214 * toPattern only puts the first grouping separator in.
2215 */
2216void NumberFormatRegressionTest::Test4176114(void) {
2217    const char* DATA[] = {
2218        "00", "#00",
2219        "000", "#000", // No grouping
2220        "#000", "#000", // No grouping
2221        "#,##0", "#,##0",
2222        "#,000", "#,000",
2223        "0,000", "#0,000",
2224        "00,000", "#00,000",
2225        "000,000", "#,000,000",
2226        "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2227    };
2228    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2229    UErrorCode status = U_ZERO_ERROR;
2230    UnicodeString s;
2231    for (int i=0; i<DATA_length; i+=2) {
2232        DecimalFormat df(DATA[i], status);
2233        if (!failure(status, "DecimalFormat constructor")) {
2234            df.toPattern(s);
2235            UnicodeString exp(DATA[i+1]);
2236            if (s != exp) {
2237                errln(UnicodeString("FAIL: ") + DATA[i] + " -> " +
2238                      s + ", want " + exp);
2239            }
2240        }
2241    }
2242}
2243
2244/**
2245 * May 17 1999 sync up - liu
2246 * @bug 4179818
2247 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2248 */
2249void NumberFormatRegressionTest::Test4179818(void) {
2250    const char* DATA[] = {
2251        // Input  Pattern  Expected output
2252        "1.2511", "#.#",   "1.3",
2253        "1.2501", "#.#",   "1.3",
2254        "0.9999", "#",     "1",
2255    };
2256    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2257    double DOUBLE[] = {
2258        1.2511,
2259        1.2501,
2260        0.9999,
2261    };
2262    UErrorCode status = U_ZERO_ERROR;
2263    DecimalFormatSymbols sym(Locale::getUS(), status);
2264    failure(status, "Construct DecimalFormatSymbols");
2265    DecimalFormat fmt("#", sym, status);
2266    if (!failure(status, "Construct DecimalFormat")) {
2267        for (int i=0; i<DATA_length; i+=3) {
2268            double in = DOUBLE[i/3];
2269            UnicodeString pat(DATA[i+1]);
2270            UnicodeString exp(DATA[i+2]);
2271            fmt.applyPattern(pat, status);
2272            failure(status, "applyPattern");
2273            UnicodeString out;
2274            FieldPosition pos;
2275            fmt.format(in, out, pos);
2276            if (out == exp) {
2277                logln(UnicodeString("Ok: ") + in + " x " + pat + " = " + out);
2278            } else {
2279                errln(UnicodeString("FAIL: ") + in + " x  " + pat + " = " + out +
2280                      ", expected " + exp);
2281            }
2282        }
2283    }
2284}
2285
2286/**
2287 * May 17 1999 sync up - liu
2288 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2289 * This includes the minus sign, currency symbol, international currency
2290 * symbol, percent, and permille.  This is filed as bugs 4212072 and
2291 * 4212073.
2292 */
2293void NumberFormatRegressionTest::Test4212072(void) {
2294    UErrorCode status = U_ZERO_ERROR;
2295    DecimalFormatSymbols sym(Locale::getUS(), status);
2296
2297    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2298    DecimalFormat fmt(UnicodeString("#"), sym, status);
2299    if(failure(status, "DecimalFormat ct", Locale::getUS())) {
2300        return;
2301    }
2302
2303    UnicodeString s;
2304    FieldPosition pos;
2305
2306    sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x5e);
2307    fmt.setDecimalFormatSymbols(sym);
2308    s.remove();
2309    if (fmt.format((int32_t)-1, s, pos) != UNICODE_STRING("^1", 2)) {
2310        errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s +
2311              ", exp ^1");
2312    }
2313    s.remove();
2314    if (fmt.getNegativePrefix(s) != UnicodeString((UChar)0x5e)) {
2315        errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2316              s + ", exp ^");
2317    }
2318    sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x2d);
2319
2320    fmt.applyPattern(UnicodeString("#%"), status);
2321    failure(status, "applyPattern percent");
2322    sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x5e);
2323    fmt.setDecimalFormatSymbols(sym);
2324    s.remove();
2325    if (fmt.format(0.25, s, pos) != UNICODE_STRING("25^", 3)) {
2326        errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s +
2327              ", exp 25^");
2328    }
2329    s.remove();
2330    if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
2331        errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2332              s + ", exp ^");
2333    }
2334    sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x25);
2335
2336    fmt.applyPattern(str("#\\u2030"), status);
2337    failure(status, "applyPattern permill");
2338    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x5e);
2339    fmt.setDecimalFormatSymbols(sym);
2340    s.remove();
2341    if (fmt.format(0.25, s, pos) != UNICODE_STRING("250^", 4)) {
2342        errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s +
2343              ", exp 250^");
2344    }
2345    s.remove();
2346    if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
2347        errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2348              s + ", exp ^");
2349    }
2350    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x2030);
2351
2352    fmt.applyPattern(str("\\u00A4#.00"), status);
2353    failure(status, "applyPattern currency");
2354    sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "usd");
2355    fmt.setDecimalFormatSymbols(sym);
2356    s.remove();
2357    if (fmt.format(12.5, s, pos) != UnicodeString("usd12.50")) {
2358        errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s +
2359              ", exp usd12.50");
2360    }
2361    s.remove();
2362    if (fmt.getPositivePrefix(s) != UnicodeString("usd")) {
2363        errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2364              s + ", exp usd");
2365    }
2366    sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "$");
2367
2368    fmt.applyPattern(str("\\u00A4\\u00A4#.00"), status);
2369    failure(status, "applyPattern intl currency");
2370    sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "DOL");
2371    fmt.setDecimalFormatSymbols(sym);
2372    s.remove();
2373    if (fmt.format(12.5, s, pos) != UnicodeString("DOL12.50")) {
2374        errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s +
2375              ", exp DOL12.50");
2376    }
2377    s.remove();
2378    if (fmt.getPositivePrefix(s) != UnicodeString("DOL")) {
2379        errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2380              s + ", exp DOL");
2381    }
2382    sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "USD");
2383
2384    // Since the pattern logic has changed, make sure that patterns round
2385    // trip properly.  Test stream in/out integrity too.
2386    int32_t n;
2387    const Locale* avail = NumberFormat::getAvailableLocales(n);
2388    static const char* type[] = {
2389        "",
2390        "$ ",
2391        "% ",
2392    };
2393    for (int i=0; i<n; ++i) {
2394        for (int j=0; j<3; ++j) {
2395            status = U_ZERO_ERROR;
2396            NumberFormat *nf;
2397            switch (j) {
2398            case 0:
2399                nf = NumberFormat::createInstance(avail[i], status);
2400                failure(status, "createInstance", avail[i]);
2401                break;
2402            case 1:
2403                nf = NumberFormat::createCurrencyInstance(avail[i], status);
2404                failure(status, "createCurrencyInstance", avail[i]);
2405                break;
2406            default:
2407                nf = NumberFormat::createPercentInstance(avail[i], status);
2408                failure(status, "createPercentInstance", avail[i]);
2409                break;
2410            }
2411            if (U_FAILURE(status)) {
2412                continue;
2413            }
2414            DecimalFormat *df = (DecimalFormat*) nf;
2415
2416            // Test toPattern/applyPattern round trip
2417            UnicodeString pat;
2418            df->toPattern(pat);
2419            DecimalFormatSymbols symb(avail[i], status);
2420            failure(status, "Construct DecimalFormatSymbols", avail[i]);
2421            DecimalFormat f2(pat, symb, status);
2422            if (failure(status,
2423                        UnicodeString("Construct DecimalFormat(") + pat + ")")) {
2424                continue;
2425            }
2426            if (*df != f2) {
2427                UnicodeString l, p;
2428                errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
2429                      " -> \"" + pat +
2430                      "\" -> \"" + f2.toPattern(p) + "\"");
2431            } else {
2432                UnicodeString l, p;
2433                logln(UnicodeString("PASS: ") + type[j] + avail[i].getDisplayName(l) +
2434                      " -> \"" + pat +
2435                      "\"");
2436            }
2437
2438            // Test toLocalizedPattern/applyLocalizedPattern round trip
2439            df->toLocalizedPattern(pat);
2440            f2.applyLocalizedPattern(pat, status);
2441            failure(status,
2442                    UnicodeString("applyLocalizedPattern(") + pat + ")", avail[i]);
2443            if (U_FAILURE(status)) {
2444                continue;
2445            }
2446
2447            // Make sure we set the currency attributes appropriately
2448            if (j == 1) {   // Currency format
2449                f2.setCurrency(f2.getCurrency(), status);
2450            }
2451            failure(status,
2452                    UnicodeString("setCurrency() for (") + pat + ")", avail[i]);
2453            if (U_FAILURE(status)) {
2454                continue;
2455            }
2456
2457            if (*df != f2) {
2458                UnicodeString l, p;
2459                errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
2460                      " -> localized \"" + pat +
2461                      "\" -> \"" + f2.toPattern(p) + "\"");
2462            }
2463
2464            delete nf;
2465
2466            // Test writeObject/readObject round trip
2467            // NOT ON ICU -- Java only
2468        }
2469    }
2470}
2471
2472/**
2473 * May 17 1999 sync up - liu
2474 * DecimalFormat.parse() fails for mulipliers 2^n.
2475 */
2476void NumberFormatRegressionTest::Test4216742(void) {
2477    UErrorCode status = U_ZERO_ERROR;
2478    DecimalFormat *fmt = (DecimalFormat*) NumberFormat::createInstance(Locale::getUS(), status);
2479    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2480        delete fmt;
2481        return;
2482    };
2483    int32_t DATA[] = { INT32_MIN, INT32_MAX, -100000000, 100000000 };
2484    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2485    for (int i=0; i<DATA_length; ++i) {
2486        UnicodeString str((UnicodeString)"" + DATA[i]);
2487        for (int m = 1; m <= 100; m++) {
2488            fmt->setMultiplier(m);
2489            Formattable num;
2490            fmt->parse(str, num, status);
2491            failure(status, "parse", Locale::getUS());
2492            if (num.getType() != Formattable::kLong &&
2493                num.getType() != Formattable::kDouble) {
2494                errln(UnicodeString("FAIL: Wanted number, got ") +
2495                      toString(num));
2496            } else {
2497                double d = num.getType() == Formattable::kDouble ?
2498                    num.getDouble() : (double) num.getLong();
2499                if ((d > 0) != (DATA[i] > 0)) {
2500                    errln(UnicodeString("\"") + str + "\" parse(x " +
2501                          fmt->getMultiplier() +
2502                          ") => " + toString(num));
2503                }
2504            }
2505        }
2506    }
2507    delete fmt;
2508}
2509
2510/**
2511 * May 17 1999 sync up - liu
2512 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2513 * digits.
2514 */
2515void NumberFormatRegressionTest::Test4217661(void) {
2516    const double D[] = {  0.001, 1.001, 0.006,  1.006 };
2517    const char*  S[] = { "0",   "1",   "0.01", "1.01" };
2518    int D_length = (int)(sizeof(D) / sizeof(D[0]));
2519    UErrorCode status = U_ZERO_ERROR;
2520    NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
2521    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2522        delete fmt;
2523        return;
2524    };
2525    fmt->setMaximumFractionDigits(2);
2526    for (int i=0; i<D_length; i++) {
2527        UnicodeString s;
2528        fmt->format(D[i], s);
2529        if (s != UnicodeString(S[i])) {
2530            errln(UnicodeString("FAIL: Got ") + s + ", exp " + S[i]);
2531        }
2532    }
2533    delete fmt;
2534}
2535
2536/**
2537 * alphaWorks upgrade
2538 */
2539void NumberFormatRegressionTest::Test4161100(void) {
2540    UErrorCode status = U_ZERO_ERROR;
2541    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2542    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2543        delete nf;
2544        return;
2545    };
2546    nf->setMinimumFractionDigits(1);
2547    nf->setMaximumFractionDigits(1);
2548    double a = -0.09;
2549    UnicodeString s;
2550    nf->format(a, s);
2551    UnicodeString pat;
2552    logln(UnicodeString() + a + " x " +
2553          ((DecimalFormat*) nf)->toPattern(pat) + " = " + s);
2554    if (s != UnicodeString("-0.1")) {
2555        errln("FAIL");
2556    }
2557    delete nf;
2558}
2559
2560/**
2561 * June 16 1999 sync up - liu
2562 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2563 */
2564void NumberFormatRegressionTest::Test4243011(void) {
2565    UErrorCode status = U_ZERO_ERROR;
2566    DecimalFormatSymbols sym(Locale::getUS(), status);
2567    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2568    DecimalFormat fmt(UnicodeString("0."), sym, status);
2569
2570    if (!failure(status, "DecimalFormat ct", Locale::getUS())) {
2571        const double NUM[] = {  -2.5,  -1.5,  -0.5,  0.5,  1.5,  2.5,  3.5,  4.5 };
2572        const char*  STR[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2573        int32_t N = (int32_t)(sizeof(NUM) / sizeof(NUM[0]));
2574
2575        for (int32_t i=0; i<N; ++i) {
2576            UnicodeString str;
2577            UnicodeString exp(STR[i]);
2578            FieldPosition pos;
2579            fmt.format(NUM[i], str, pos);
2580            if (str == exp) {
2581                logln(UnicodeString("Ok   ") + NUM[i] + " x 0. = " + str);
2582            } else {
2583                errln(UnicodeString("FAIL ") + NUM[i] + " x 0. = " + str +
2584                      ", want " + exp);
2585            }
2586        }
2587    }
2588}
2589
2590/**
2591 * June 16 1999 sync up - liu
2592 * format(0.0) gives "0.1" if preceded by parse("99.99").
2593 * (Regression in 1.2.2 RC1)
2594 */
2595void NumberFormatRegressionTest::Test4243108(void) {
2596    UErrorCode status = U_ZERO_ERROR;
2597    DecimalFormatSymbols sym(Locale::getUS(), status);
2598    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2599    DecimalFormat fmt(UnicodeString("#.#"), sym, status);
2600    if (failure(status, "DecimalFormat ct", Locale::getUS())) {
2601        return;
2602    }
2603
2604    UnicodeString str;
2605    FieldPosition pos;
2606
2607    fmt.format(0.0, str, pos);
2608    UnicodeString exp("0");
2609    if (str == exp) {
2610        logln(UnicodeString("Ok   0.0 x #.# = ") + str);
2611    } else {
2612        errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
2613              ", want " + exp);
2614    }
2615
2616    str = "99.99";
2617    Formattable val;
2618    fmt.parse(str, val, status);
2619    failure(status, "DecimalFormat.parse(99.99)", Locale::getUS());
2620    if (val.getType() == Formattable::kDouble &&
2621        val.getDouble() == 99.99) {
2622        logln(UnicodeString("Ok   99.99 / #.# = ") + toString(val));
2623    } else {
2624        errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val) +
2625              ", want " + 99.99);
2626    }
2627
2628    str.remove();
2629    fmt.format(0.0, str, pos);
2630    if (str == exp) {
2631        logln(UnicodeString("Ok   0.0 x #.# = ") + str);
2632    } else {
2633        errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
2634              ", want " + exp);
2635    }
2636}
2637
2638
2639/**
2640 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2641 * NumberFormat objects.
2642 */
2643void NumberFormatRegressionTest::TestJ691(void) {
2644    UErrorCode status = U_ZERO_ERROR;
2645    Locale loc("fr", "CH");
2646
2647    // set up the input date string & expected output
2648    UnicodeString udt("11.10.2000", "");
2649    UnicodeString exp("11.10.00", "");
2650
2651    // create a Calendar for this locale
2652    Calendar *cal = Calendar::createInstance(loc, status);
2653    if (U_FAILURE(status)) {
2654        dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString)u_errorName(status));
2655        return;
2656    }
2657
2658    // create a NumberFormat for this locale
2659    NumberFormat *nf = NumberFormat::createInstance(loc, status);
2660    if (U_FAILURE(status)) {
2661        dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
2662        return;
2663    }
2664
2665    // *** Here's the key: We don't want to have to do THIS:
2666    // nf->setParseIntegerOnly(TRUE);
2667
2668    // create the DateFormat
2669    DateFormat *df = DateFormat::createDateInstance(DateFormat::kShort, loc);
2670    if (U_FAILURE(status)) {
2671        errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
2672        return;
2673    }
2674
2675    df->adoptCalendar(cal);
2676    df->adoptNumberFormat(nf);
2677
2678    // set parsing to lenient & parse
2679    df->setLenient(TRUE);
2680    UDate ulocdat = df->parse(udt, status);
2681
2682    // format back to a string
2683    UnicodeString outString;
2684    df->format(ulocdat, outString);
2685
2686    if (outString != exp) {
2687        errln("FAIL: " + udt + " => " + outString);
2688    }
2689
2690    delete df;
2691}
2692
2693//---------------------------------------------------------------------------
2694//
2695//   Error Checking / Reporting macros
2696//
2697//---------------------------------------------------------------------------
2698#define TEST_CHECK_STATUS(status) \
2699    if (U_FAILURE(status)) {\
2700        errln("File %s, Line %d.  status=%s\n", __FILE__, __LINE__, u_errorName(status));\
2701        return;\
2702    }
2703
2704#define TEST_ASSERT(expr) \
2705    if ((expr)==FALSE) {\
2706        errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\
2707    }
2708
2709
2710// Ticket 8199:  Parse failure for numbers in the range of 1E10 - 1E18
2711
2712void NumberFormatRegressionTest::Test8199(void) {
2713    UErrorCode status = U_ZERO_ERROR;
2714    NumberFormat *nf = NumberFormat::createInstance(Locale::getEnglish(), status);
2715    if (nf == NULL) {
2716        dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)");
2717        return;
2718    }
2719    TEST_CHECK_STATUS(status);
2720
2721    // Note:  Retrieving parsed values from a Formattable as a reduced-precision type
2722    //        should always truncate, no other rounding scheme.
2723
2724    UnicodeString numStr = "1000000000.6";   // 9 zeroes
2725    Formattable val;
2726    nf->parse(numStr, val, status);
2727    TEST_CHECK_STATUS(status);
2728    TEST_ASSERT(Formattable::kDouble == val.getType());
2729    TEST_ASSERT(1000000000 == val.getInt64(status));
2730    TEST_CHECK_STATUS(status);
2731    TEST_ASSERT(1000000000.6 == val.getDouble(status));
2732    TEST_CHECK_STATUS(status);
2733
2734    numStr = "100000000000000001.1";   // approx 1E17, parses as a double rather
2735                                       //   than int64 because of the fraction
2736                                       //   even though int64 is more precise.
2737    nf->parse(numStr, val, status);
2738    TEST_CHECK_STATUS(status);
2739    TEST_ASSERT(Formattable::kDouble == val.getType());
2740    TEST_ASSERT(100000000000000001LL == val.getInt64(status));
2741    TEST_CHECK_STATUS(status);
2742    TEST_ASSERT(100000000000000000.0 == val.getDouble(status));
2743    TEST_CHECK_STATUS(status);
2744
2745    numStr = "1E17";  // Parses with the internal decimal number having non-zero exponent
2746    nf->parse(numStr, val, status);
2747    TEST_CHECK_STATUS(status);
2748    TEST_ASSERT(Formattable::kInt64 == val.getType());
2749    TEST_ASSERT(100000000000000000LL == val.getInt64());
2750    TEST_ASSERT(1.0E17 == val.getDouble(status));
2751    TEST_CHECK_STATUS(status);
2752
2753    numStr = "9223372036854775807";  // largest int64_t
2754    nf->parse(numStr, val, status);
2755    TEST_CHECK_STATUS(status);
2756    TEST_ASSERT(Formattable::kInt64 == val.getType());
2757    TEST_ASSERT(9223372036854775807LL == val.getInt64());
2758    // In the following check, note that a substantial range of integers will
2759    //    convert to the same double value.  There are also platform variations
2760    //    in the rounding at compile time of double constants.
2761    TEST_ASSERT(9223372036854775808.0 >= val.getDouble(status));
2762    TEST_ASSERT(9223372036854774700.0 <= val.getDouble(status));
2763    TEST_CHECK_STATUS(status);
2764
2765    numStr = "-9223372036854775808";  // smallest int64_t
2766    nf->parse(numStr, val, status);
2767    TEST_CHECK_STATUS(status);
2768    TEST_ASSERT(Formattable::kInt64 == val.getType());
2769    // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant.
2770    TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64());
2771    TEST_ASSERT(-9223372036854775808.0 == val.getDouble(status));
2772    TEST_CHECK_STATUS(status);
2773
2774    numStr = "9223372036854775808";  // largest int64_t + 1
2775    nf->parse(numStr, val, status);
2776    TEST_CHECK_STATUS(status);
2777    TEST_ASSERT(Formattable::kDouble == val.getType());
2778    TEST_ASSERT(9223372036854775807LL == val.getInt64(status));
2779    TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
2780    status = U_ZERO_ERROR;
2781    TEST_ASSERT(9223372036854775810.0 == val.getDouble(status));
2782    TEST_CHECK_STATUS(status);
2783
2784    numStr = "-9223372036854775809";  // smallest int64_t - 1
2785    nf->parse(numStr, val, status);
2786    TEST_CHECK_STATUS(status);
2787    TEST_ASSERT(Formattable::kDouble == val.getType());
2788    // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status));  // spurious compiler warnings
2789    TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64(status));
2790    TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
2791    status = U_ZERO_ERROR;
2792    TEST_ASSERT(-9223372036854775810.0 == val.getDouble(status));
2793    TEST_CHECK_STATUS(status);
2794
2795    // Test values near the limit of where doubles can represent all integers.
2796    // The implementation strategy of getInt64() changes at this boundary.
2797    // Strings to be parsed include a decimal fraction to force them to be
2798    //   parsed as doubles rather than ints.  The fraction is discarded
2799    //   from the parsed double value because it is beyond what can be represented.
2800
2801    status = U_ZERO_ERROR;
2802    numStr = "9007199254740991.1";  // largest 53 bit int
2803    nf->parse(numStr, val, status);
2804    TEST_CHECK_STATUS(status);
2805    // printf("getInt64() returns %lld\n", val.getInt64(status));
2806    TEST_ASSERT(Formattable::kDouble == val.getType());
2807    TEST_ASSERT(9007199254740991LL == val.getInt64(status));
2808    TEST_ASSERT(9007199254740991.0 == val.getDouble(status));
2809    TEST_CHECK_STATUS(status);
2810
2811    status = U_ZERO_ERROR;
2812    numStr = "9007199254740992.1";  // 54 bits for the int part.
2813    nf->parse(numStr, val, status);
2814    TEST_CHECK_STATUS(status);
2815    TEST_ASSERT(Formattable::kDouble == val.getType());
2816    TEST_ASSERT(9007199254740992LL == val.getInt64(status));
2817    TEST_ASSERT(9007199254740992.0 == val.getDouble(status));
2818    TEST_CHECK_STATUS(status);
2819
2820    status = U_ZERO_ERROR;
2821    numStr = "9007199254740993.1";  // 54 bits for the int part.  Double will round
2822    nf->parse(numStr, val, status); //    the ones digit, putting it up to ...994
2823    TEST_CHECK_STATUS(status);
2824    TEST_ASSERT(Formattable::kDouble == val.getType());
2825    TEST_ASSERT(9007199254740993LL == val.getInt64(status));
2826    TEST_ASSERT(9007199254740994.0 == val.getDouble(status));
2827    TEST_CHECK_STATUS(status);
2828
2829    delete nf;
2830}
2831
2832void NumberFormatRegressionTest::Test9109(void) {
2833    UErrorCode status = U_ZERO_ERROR;
2834    Formattable val;
2835    ParsePosition pos;
2836    DecimalFormat fmt("+##", status);
2837    fmt.setLenient(TRUE);
2838
2839    if (U_FAILURE(status)) {
2840        dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status));
2841    }
2842
2843    UnicodeString text("123");
2844    int32_t expected = 123;
2845    int32_t expos = 3;
2846
2847    fmt.parse(text, val, pos);
2848    if (pos.getErrorIndex() >= 0) {
2849        errln(UnicodeString("Parse failure at ") + pos.getErrorIndex());
2850    } else if (val.getLong() != 123) {
2851        errln(UnicodeString("Incorrect parse result: ") + val.getLong() + " expected: " + expected);
2852    } else if (pos.getIndex() != 3) {
2853        errln(UnicodeString("Incorrect parse position: ") + pos.getIndex() + " expected: " + expos);
2854    }
2855}
2856
2857
2858void NumberFormatRegressionTest::Test9780(void) {
2859    UErrorCode status = U_ZERO_ERROR;
2860    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2861    if (failure(status, "NumberFormat::createInstance", TRUE)){
2862        delete nf;
2863        return;
2864    };
2865    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
2866    if(df == NULL) {
2867        errln("DecimalFormat needed to continue");
2868        return;
2869    }
2870    df->setParseIntegerOnly(TRUE);
2871
2872    {
2873      Formattable n;
2874      ParsePosition pos(0);
2875      UnicodeString toParse("1,234","");
2876      df->parse(toParse, n, pos);
2877      if (n.getType() != Formattable::kLong
2878          || n.getLong() != 1234) {
2879        errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
2880      }
2881    }
2882    // should still work in lenient mode, just won't get fastpath
2883    df->setLenient(TRUE);
2884    {
2885      Formattable n;
2886      ParsePosition pos(0);
2887      UnicodeString toParse("1,234","");
2888      df->parse(toParse, n, pos);
2889      if (n.getType() != Formattable::kLong
2890          || n.getLong() != 1234) {
2891        errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
2892      }
2893    }
2894    delete nf;
2895}
2896
2897
2898void NumberFormatRegressionTest::Test9677(void) {
2899  static const UChar pattern[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####"
2900  static const UChar positivePrefix[] = { 0x40,0 }; // "@"
2901  static const UChar negativePrefix[] = { 0x6E,0 }; // "n"
2902  static const UChar text[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789
2903  static const UChar text2[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789
2904
2905  UErrorCode status = U_ZERO_ERROR;
2906  LocalUNumberFormatPointer f(unum_open(UNUM_DEFAULT, NULL, 0, "en_US", NULL, &status));
2907  if (U_FAILURE(status)) {
2908      dataerrln("Failure opening unum_open");
2909      return;
2910  }
2911
2912  if (U_SUCCESS(status)) {
2913    unum_applyPattern(f.getAlias(), FALSE, pattern, -1, NULL, &status);
2914    unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, positivePrefix, -1, &status);
2915    assertSuccess("setting attributes", status);
2916  }
2917
2918  if(U_SUCCESS(status)) {
2919    int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
2920    logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2921
2922    if(U_FAILURE(status)) {
2923        logln("Got expected parse error %s\n", u_errorName(status));
2924        status = U_ZERO_ERROR;
2925    } else {
2926        errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
2927    }
2928  }
2929
2930  if (U_SUCCESS(status)) {
2931    unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, NULL, 0, &status);
2932    assertSuccess("setting attributes", status);
2933    logln("removed positive prefix");
2934  }
2935
2936  if(U_SUCCESS(status)) {
2937    int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
2938    logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2939
2940    if(U_FAILURE(status)) {
2941        errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status));
2942        status = U_ZERO_ERROR;
2943    } else {
2944        if(n!=123456789) {
2945          errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status), n);
2946        } else {
2947          logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status),n);
2948        }
2949    }
2950  }
2951
2952  if(U_SUCCESS(status)) {
2953    int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
2954    logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2955
2956    if(U_FAILURE(status)) {
2957        logln("text2: Got expected parse error %s\n", u_errorName(status));
2958        status = U_ZERO_ERROR;
2959    } else {
2960        errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
2961    }
2962  }
2963
2964  if (U_SUCCESS(status)) {
2965    unum_setTextAttribute(f.getAlias(), UNUM_NEGATIVE_PREFIX, negativePrefix, -1, &status);
2966    assertSuccess("setting attributes", status);
2967    logln("Set a different neg prefix prefix");
2968  }
2969
2970  if(U_SUCCESS(status)) {
2971    int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
2972    logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2973
2974    if(U_FAILURE(status)) {
2975        errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status));
2976        status = U_ZERO_ERROR;
2977    } else {
2978;
2979        if(n!=-123456789) {
2980          errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
2981        } else {
2982          logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
2983        }
2984    }
2985  }
2986}
2987
2988
2989#endif /* #if !UCONFIG_NO_FORMATTING */
2990