1 /***********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ***********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
13 #include <float.h> // DBL_MIN, DBL_MAX
16 #include "unicode/dcfmtsym.h"
17 #include "unicode/decimfmt.h"
18 #include "unicode/locid.h"
19 #include "unicode/resbund.h"
20 #include "unicode/calendar.h"
21 #include "unicode/datefmt.h"
24 int32_t gMyNumberFormatTestClassID
;
25 UClassID
MyNumberFormatTest::getDynamicClassID() const
27 return (UClassID
)&gMyNumberFormatTestClassID
;
31 // *****************************************************************************
32 // class NumberFormatRegressionTest
33 // *****************************************************************************
35 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
38 NumberFormatRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
40 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
100 CASE(58,Test4243011
);
101 CASE(59,Test4243108
);
104 default: name
= ""; break;
109 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const Locale
& l
)
111 if(U_FAILURE(status
)) {
112 errln(UnicodeString("FAIL: ", "") + msg
113 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),""));
121 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const char *l
)
123 if(U_FAILURE(status
)) {
124 errln(UnicodeString("FAIL: ", "") + msg
125 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, ""));
133 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
)
135 if(U_FAILURE(status
)) {
136 errln(UnicodeString("FAIL: ", "") + msg
137 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
145 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
147 inline UnicodeString
str(const char *input
)
149 return CharsToUnicodeString(input
);
153 * NumberFormat.equals comparing with null should always return false.
155 // {sfb} kind of silly in C++, just checking for new success
156 void NumberFormatRegressionTest::Test4075713(void)
159 MyNumberFormatTest
*tmp
= new MyNumberFormatTest();
161 logln("NumberFormat.equals passed");
162 /*} catch (NullPointerException e) {
163 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
170 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
173 void NumberFormatRegressionTest::Test4074620(void)
176 MyNumberFormatTest
*nf1
= new MyNumberFormatTest();
177 MyNumberFormatTest
*nf2
= new MyNumberFormatTest();
179 nf1
->setGroupingUsed(FALSE
);
180 nf2
->setGroupingUsed(TRUE
);
183 errln("Test for bug 4074620 failed");
185 logln("Test for bug 4074620 passed.");
193 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
196 void NumberFormatRegressionTest::Test4088161 (void)
198 UErrorCode status
= U_ZERO_ERROR
;
199 DecimalFormat
*df
= new DecimalFormat(status
);
200 failure(status
, "new DecimalFormat", "");
202 df
->setMinimumFractionDigits(0);
203 df
->setMaximumFractionDigits(16);
205 FieldPosition
fp1(0);
206 logln(UnicodeString("d = ") + d
);
207 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
209 logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'");
210 df
->setMaximumFractionDigits(17);
212 FieldPosition
fp2(0);
213 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
214 sBuf2
= df
->format(d
, sBuf2
, fp2
);
216 errln(" format(d) = '" + sBuf2
+ "'");
222 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
223 * DecimalFormat(String, DecimalFormatSymbols).
225 void NumberFormatRegressionTest::Test4087245 (void)
227 UErrorCode status
= U_ZERO_ERROR
;
228 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(status
);
229 failure(status
, "new DecimalFormatSymbols", "");
230 // {sfb} One note about this test: if you pass in a pointer
231 // to the symbols, they are adopted and this test will fail,
232 // even though that is the correct behavior. To test the cloning
233 // of the symbols, it is necessary to pass in a reference to the symbols
234 DecimalFormat
*df
= new DecimalFormat("#,##0.0", *symbols
, status
);
235 failure(status
, "new DecimalFormat with symbols", "");
239 FieldPosition
pos(FieldPosition::DONT_CARE
);
240 logln(UnicodeString("format(") + n
+ ") = " +
241 df
->format(n
, buf1
, pos
));
242 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field
243 logln(UnicodeString("format(") + n
+ ") = " +
244 df
->format(n
, buf2
, pos
));
246 errln("Test for bug 4087245 failed");
253 * DecimalFormat.format() incorrectly formats 0.0
255 void NumberFormatRegressionTest::Test4087535 (void)
257 UErrorCode status
= U_ZERO_ERROR
;
258 DecimalFormat
*df
= new DecimalFormat(status
);
259 failure(status
, "new DecimalFormat", "");
260 df
->setMinimumIntegerDigits(0);
263 UnicodeString buffer
;
264 FieldPosition
pos(FieldPosition::DONT_CARE
);
265 buffer
= df
->format(n
, buffer
, pos
);
266 if (buffer
.length() == 0)
267 errln(/*n + */": '" + buffer
+ "'");
269 buffer
= df
->format(n
, buffer
, pos
);
270 if (buffer
.length() == 0)
271 errln(/*n + */": '" + buffer
+ "'");
277 * DecimalFormat.format fails when groupingSize is set to 0.
279 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
280 void NumberFormatRegressionTest::Test4088503 (void)
282 UErrorCode status
= U_ZERO_ERROR
;
283 DecimalFormat
*df
= new DecimalFormat(status
);
284 failure(status
, "new DecimalFormat", "");
285 df
->setGroupingSize(0);
287 FieldPosition
fp(FieldPosition::DONT_CARE
);
289 logln(df
->format((int32_t)123, sBuf
, fp
));
290 //if(fp == FieldPosition(0))
291 // errln("Test for bug 4088503 failed.");
292 /*} catch (Exception foo) {
293 errln("Test for bug 4088503 failed.");
299 * NumberFormat.getCurrencyInstance is wrong.
301 void NumberFormatRegressionTest::Test4066646 (void)
303 assignFloatValue(2.04f
);
304 assignFloatValue(2.03f
);
305 assignFloatValue(2.02f
);
306 assignFloatValue(0.0f
);
310 NumberFormatRegressionTest::assignFloatValue(float returnfloat
)
312 logln(UnicodeString(" VALUE ") + returnfloat
);
313 UErrorCode status
= U_ZERO_ERROR
;
314 NumberFormat
*nfcommon
= NumberFormat::createCurrencyInstance(Locale::getUS(), status
);
315 failure(status
, "NumberFormat::createCurrencyInstance", Locale::getUS());
316 nfcommon
->setGroupingUsed(FALSE
);
318 UnicodeString stringValue
;
319 stringValue
= nfcommon
->format(returnfloat
, stringValue
);
320 logln(" DISPLAYVALUE " + stringValue
);
322 nfcommon
->parse(stringValue
, result
, status
);
323 failure(status
, "nfcommon->parse", Locale::getUS());
324 float floatResult
= (float) (result
.getType() == Formattable::kDouble
325 ? result
.getDouble() : result
.getLong());
326 if( uprv_fabs(floatResult
- returnfloat
) > 0.0001)
327 //String stringValue = nfcommon.format(returnfloat).substring(1);
328 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
329 errln(UnicodeString("FAIL: expected ") + returnfloat
+ ", got " + floatResult
+ " (" + stringValue
+")");
333 } // End Of assignFloatValue()
336 * DecimalFormat throws exception when parsing "0"
338 void NumberFormatRegressionTest::Test4059870(void)
340 UErrorCode status
= U_ZERO_ERROR
;
341 DecimalFormat
*format
= new DecimalFormat("00", status
);
342 failure(status
, "new Decimalformat", Locale::getUS());
346 format
->parse(UnicodeString("0"), result
, status
);
347 failure(status
, "format->parse", Locale::getUS());
350 catch (Exception e) {
351 errln("Test for bug 4059870 failed : " + e);
357 * DecimalFormatSymbol.equals should always return false when
358 * comparing with null.
360 // {sfb} this is silly in C++
361 void NumberFormatRegressionTest::Test4083018 (void)
363 UErrorCode status
= U_ZERO_ERROR
;
364 DecimalFormatSymbols
*dfs
= new DecimalFormatSymbols(status
);
365 failure(status
, "new DecimalFormatSymbols", Locale::getUS());
368 logln("Test Passed!");
370 errln("Test for bug 4083018 failed");
371 /*} catch (Exception foo) {
372 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
379 * DecimalFormat does not round up correctly.
381 void NumberFormatRegressionTest::Test4071492 (void)
383 double x
= 0.00159999;
384 UErrorCode status
= U_ZERO_ERROR
;
385 NumberFormat
*nf
= NumberFormat::createInstance(status
);
386 failure(status
, "NumberFormat::createInstance", Locale::getUS());
387 nf
->setMaximumFractionDigits(4);
389 FieldPosition
pos(FieldPosition::DONT_CARE
);
390 out
= nf
->format(x
, out
, pos
);
391 logln("0.00159999 formats with 4 fractional digits to " + out
);
392 UnicodeString
expected("0.0016");
394 errln("FAIL: Expected " + expected
);
400 * A space as a group separator for localized pattern causes
401 * wrong format. WorkAround : use non-breaking space.
403 void NumberFormatRegressionTest::Test4086575(void)
405 UErrorCode status
= U_ZERO_ERROR
;
406 NumberFormat
*nf1
= NumberFormat::createInstance(Locale::getFrance(), status
);
408 // TODO: There is not a good way to find out that the creation of this number format has
409 // failed. Major rewiring of format construction proposed.
410 if(U_FAILURE(status
)) {
411 errln("Something is wrong with French number format - it should not fallback. Exitting");
415 failure(status
, "NumberFormat::createInstance", Locale::getFrance());
417 // C++ workaround to make sure cast works
418 // Wouldn't dynamic_cast<DecimalFormat*> be great?
419 if(nf1
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
420 errln("NumberFormat::createInstance returned incorrect type.");
424 DecimalFormat
*nf
= (DecimalFormat
*) nf1
;
426 logln("nf toPattern1: " + nf
->toPattern(temp
));
427 logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
));
429 // No group separator
430 logln("...applyLocalizedPattern ###,00;(###,00) ");
431 nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
);
432 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
433 logln("nf toPattern2: " + nf
->toPattern(temp
));
434 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
436 FieldPosition
pos(FieldPosition::DONT_CARE
);
437 logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00
438 logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00)
440 // Space as group separator
442 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
444 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
446 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
447 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
449 UnicodeString
pat(patChars
, 19, 19);
450 nf
->applyLocalizedPattern(pat
, status
);
451 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
452 logln("nf toPattern2: " + nf
->toPattern(temp
));
453 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
454 UnicodeString buffer
;
455 buffer
= nf
->format((int32_t)1234, buffer
, pos
);
456 //if (buffer != UnicodeString("1\u00a0234,00"))
458 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
460 UnicodeString
cc(c
, 8, 8);
462 errln("nf : " + buffer
); // Expect 1 234,00
465 buffer
= nf
->format((int32_t)-1234, buffer
, pos
);
467 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
469 UnicodeString
cc1(c1
, 10, 10);
471 errln("nf : " + buffer
); // Expect (1 234,00)
473 // Erroneously prints:
480 * DecimalFormat.parse returns wrong value
482 // {sfb} slightly converted into a round-trip test, since in C++
483 // there is no Double.toString()
484 void NumberFormatRegressionTest::Test4068693(void)
486 logln("----- Test Application -----");
487 ParsePosition
pos(0);
488 UErrorCode status
= U_ZERO_ERROR
;
489 DecimalFormat
*df
= new DecimalFormat(status
);
490 if(U_FAILURE(status
)) {
491 errln("Error creating DecimalFormat: %s", u_errorName(status
));
495 failure(status
, "new DecimalFormat");
497 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
498 df
->parse(UnicodeString("123.55456"), d
, pos
);
499 //if (!d.toString().equals("123.55456")) {
501 df
->setMaximumFractionDigits(999);
502 df
->setMaximumIntegerDigits(999);
503 FieldPosition
fp(FieldPosition::DONT_CARE
);
504 dstr
= df
->format(d
.getDouble(), dstr
, fp
);
505 if (dstr
!= UnicodeString("123.55456")) {
506 errln(UnicodeString("Result -> ") + d
.getDouble());
512 /* @bug 4069754, 4067878
513 * null pointer thrown when accessing a deserialized DecimalFormat
516 // {sfb} doesn't apply in C++
517 void NumberFormatRegressionTest::Test4069754(void)
520 myformat it = new myformat();
522 FileOutputStream ostream = new FileOutputStream("t.tmp");
523 ObjectOutputStream p = new ObjectOutputStream(ostream);
528 FileInputStream istream = new FileInputStream("t.tmp");
529 ObjectInputStream p2 = new ObjectInputStream(istream);
530 myformat it2 = (myformat)p2.readObject();
534 } catch (Exception foo) {
535 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
540 * DecimalFormat.applyPattern(String) allows illegal patterns
542 void NumberFormatRegressionTest::Test4087251 (void)
544 UErrorCode status
= U_ZERO_ERROR
;
545 DecimalFormat
*df
= new DecimalFormat(status
);
546 if(U_FAILURE(status
)) {
547 errln("Error creating DecimalFormat: %s", u_errorName(status
));
551 failure(status
, "new DecimalFormat");
553 df
->applyPattern(UnicodeString("#.#.#"), status
);
554 if( ! U_FAILURE(status
))
555 errln("df->applyPattern with illegal pattern didn't fail");
557 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
558 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
559 /*} catch (IllegalArgumentException e) {
560 logln("Caught Illegal Argument Error !");
562 // Second test; added 5/11/98 when reported to fail on 1.2b3
564 df
->applyPattern("#0.0#0#0", status
);
565 if( ! U_FAILURE(status
))
566 errln("df->applyPattern with illegal pattern didn't fail");
567 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
568 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
569 /*} catch (IllegalArgumentException e) {
570 logln("Ok - IllegalArgumentException for #0.0#0#0");
577 * DecimalFormat.format() loses precision
579 void NumberFormatRegressionTest::Test4090489 (void)
581 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
582 // that NumberFormat can do. For some reason, it does not format the last 1.
584 /* UErrorCode status = U_ZERO_ERROR;
585 DecimalFormat *df = new DecimalFormat(status);
586 failure(status, "new DecimalFormat");
587 df->setMinimumFractionDigits(10);
588 df->setMaximumFractionDigits(999);
589 df->setGroupingUsed(FALSE);
590 double d = 1.000000000000001E7;
591 //BigDecimal bd = new BigDecimal(d);
594 logln(UnicodeString("d = ") + d);
595 //logln("BigDecimal.toString(): " + bd.toString());
596 df->format(d, sb, fp);
597 if (sb != "10000000.0000000100") {
598 errln("DecimalFormat.format(): " + sb);
604 * DecimalFormat.format() loses precision
606 void NumberFormatRegressionTest::Test4090504 (void)
609 logln(UnicodeString("d = ") + d
);
610 UErrorCode status
= U_ZERO_ERROR
;
611 DecimalFormat
*df
= new DecimalFormat(status
);
612 if(U_FAILURE(status
)) {
613 errln("Error creating DecimalFormat: %s", u_errorName(status
));
617 failure(status
, "new DecimalFormat");
619 FieldPosition
fp(FieldPosition::DONT_CARE
);
621 for (int i
= 17; i
<= 20; i
++) {
622 df
->setMaximumFractionDigits(i
);
623 //sb = new StringBuffer("");
625 logln(" getMaximumFractionDigits() = " + i
);
626 logln(" formated: " + df
->format(d
, sb
, fp
));
628 /*} catch (Exception foo) {
629 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
635 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
637 void NumberFormatRegressionTest::Test4095713 (void)
639 UErrorCode status
= U_ZERO_ERROR
;
640 DecimalFormat
*df
= new DecimalFormat(status
);
641 if(U_FAILURE(status
)) {
642 errln("Error creating DecimalFormat: %s", u_errorName(status
));
646 failure(status
, "new DecimalFormat");
647 UnicodeString
str("0.1234");
649 //Double d1 = new Double(str);
650 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
653 df
->parse(str
, d2
, pp
);
654 logln(UnicodeString("") + d1
);
655 if (d2
.getDouble() != d1
)
656 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble());
661 * DecimalFormat.parse() fails when multiplier is not set to 1
663 // {sfb} not sure what to do with this one
664 void NumberFormatRegressionTest::Test4092561 (void)
666 UErrorCode status
= U_ZERO_ERROR
;
667 DecimalFormat
*df
= new DecimalFormat(status
);
668 if(U_FAILURE(status
)) {
669 errln("Error creating DecimalFormat: %s", u_errorName(status
));
673 failure(status
, "new DecimalFormat");
675 // {sfb} going to cheat here and use sprintf ??
677 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
678 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
679 df.setMultiplier(100);
680 Number num = df.parse(str, new ParsePosition(0));
681 if (num.doubleValue() != -9.223372036854776E16)
682 errln("Bug 4092561 test failed when multiplier is set to not 1.");
688 * DecimalFormat: Negative format ignored.
690 void NumberFormatRegressionTest::Test4092480 (void)
692 UErrorCode status
= U_ZERO_ERROR
;
693 DecimalFormat
*dfFoo
= new DecimalFormat(UnicodeString("000"), status
);
694 if(U_FAILURE(status
)) {
695 errln("Error creating DecimalFormat: %s", u_errorName(status
));
699 failure(status
, "new DecimalFormat");
702 dfFoo
->applyPattern("0000;-000", status
);
703 failure(status
, "dfFoo->applyPattern");
705 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
706 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
707 FieldPosition
pos(FieldPosition::DONT_CARE
);
708 logln(dfFoo
->format((int32_t)42, temp
, pos
));
709 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
710 dfFoo
->applyPattern("000;-000", status
);
711 failure(status
, "dfFoo->applyPattern");
712 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
713 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
714 logln(dfFoo
->format((int32_t)42,temp
, pos
));
715 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
717 dfFoo
->applyPattern("000;-0000", status
);
718 failure(status
, "dfFoo->applyPattern");
719 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
720 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
721 logln(dfFoo
->format((int32_t)42, temp
, pos
));
722 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
724 dfFoo
->applyPattern("0000;-000", status
);
725 failure(status
, "dfFoo->applyPattern");
726 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
727 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
728 logln(dfFoo
->format((int32_t)42, temp
, pos
));
729 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
730 /*} catch (Exception foo) {
731 errln("Message " + foo.getMessage());
737 * NumberFormat.getCurrencyInstance() produces format that uses
738 * decimal separator instead of monetary decimal separator.
740 * Rewrote this test not to depend on the actual pattern. Pattern should
741 * never contain the monetary separator! Decimal separator in pattern is
742 * interpreted as monetary separator if currency symbol is seen!
744 void NumberFormatRegressionTest::Test4087244 (void) {
745 UErrorCode status
= U_ZERO_ERROR
;
747 uloc_canonicalize("pt_PT_PREEURO", loc
, 256, &status
);
748 Locale
*de
= new Locale(loc
);
749 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(*de
, status
);
750 if(U_FAILURE(status
)) {
751 errln("Error creating DecimalFormat: %s", u_errorName(status
));
755 if (nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
756 errln("expected DecimalFormat!");
759 DecimalFormat
*df
= (DecimalFormat
*) nf
;
760 const DecimalFormatSymbols
*sym
= df
->getDecimalFormatSymbols();
761 UnicodeString decSep
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
762 UnicodeString monSep
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
763 if (decSep
== monSep
) {
764 errln("ERROR in test: want decimal sep != monetary sep");
767 df
->setMinimumIntegerDigits(1);
768 df
->setMinimumFractionDigits(2);
771 df
->format(1.23, str
, pos
);
772 UnicodeString
monStr("1x23");
773 monStr
.replace((int32_t)1, 1, monSep
);
774 UnicodeString
decStr("1x23");
775 decStr
.replace((int32_t)1, 1, decSep
);
776 if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) {
777 logln(UnicodeString("OK: 1.23 -> \"") + str
+ "\" contains \"" +
778 monStr
+ "\" and not \"" + decStr
+ '"');
780 errln(UnicodeString("FAIL: 1.23 -> \"") + str
+ "\", should contain \"" +
782 "\" and not \"" + decStr
+ '"');
788 * Number format data rounding errors for locale FR
790 void NumberFormatRegressionTest::Test4070798 (void)
792 NumberFormat
*formatter
;
793 UnicodeString tempString
;
796 String expectedDefault = "-5\u00a0789,987";
797 String expectedCurrency = "5\u00a0789,98 F";
798 String expectedPercent = "-578\u00a0998%";
801 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
804 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x46
807 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x25
809 UnicodeString
expectedDefault(chars1
, 10, 10);
810 UnicodeString
expectedCurrency(chars2
, 10, 10);
811 UnicodeString
expectedPercent(chars3
, 9, 9);
813 UErrorCode status
= U_ZERO_ERROR
;
815 int len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
816 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
817 if(U_FAILURE(status
)) {
818 errln("Error creating DecimalFormat: %s", u_errorName(status
));
822 failure(status
, "NumberFormat::createNumberInstance", loc
);
823 tempString
= formatter
->format (-5789.9876, tempString
);
825 if (tempString
== expectedDefault
) {
826 logln ("Bug 4070798 default test passed.");
828 errln(UnicodeString("Failed:") +
829 " Expected " + expectedDefault
+
830 " Received " + tempString
);
833 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
834 formatter
= NumberFormat::createCurrencyInstance(loc
, status
);
835 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
837 tempString
= formatter
->format( 5789.9876, tempString
);
839 if (tempString
== expectedCurrency
) {
840 logln ("Bug 4070798 currency test passed.");
842 errln(UnicodeString("Failed:") +
843 " Expected " + expectedCurrency
+
844 " Received " + tempString
);
848 uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
849 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
850 failure(status
, "NumberFormat::createPercentInstance", loc
);
852 tempString
= formatter
->format (-5789.9876, tempString
);
854 if (tempString
== expectedPercent
) {
855 logln ("Bug 4070798 percentage test passed.");
857 errln(UnicodeString("Failed:") +
858 " Expected " + expectedPercent
+
859 " Received " + tempString
);
865 * Data rounding errors for French (Canada) locale
867 void NumberFormatRegressionTest::Test4071005 (void)
869 NumberFormat
*formatter
;
870 UnicodeString tempString
;
872 String expectedDefault = "-5\u00a0789,987";
873 String expectedCurrency = "5\u00a0789,98 $";
874 String expectedPercent = "-578\u00a0998%";
877 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
880 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x24
883 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x25
885 UnicodeString
expectedDefault(chars1
, 10, 10);
886 UnicodeString
expectedCurrency(chars2
, 10, 10);
887 UnicodeString
expectedPercent(chars3
, 9, 9);
889 UErrorCode status
= U_ZERO_ERROR
;
890 formatter
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
);
891 failure(status
, "NumberFormat::createNumberInstance", Locale::getCanadaFrench());
892 tempString
= formatter
->format (-5789.9876, tempString
);
894 if (tempString
== expectedDefault
) {
895 logln ("Bug 4071005 default test passed.");
897 errln(UnicodeString("Failed:") +
898 " Expected " + expectedDefault
+
899 " Received " + tempString
);
903 formatter
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
904 failure(status
, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
906 tempString
= formatter
->format( 5789.9876, tempString
);
908 if (tempString
== expectedCurrency
) {
909 logln ("Bug 4071005 currency test assed.");
911 errln(UnicodeString("Failed:") +
912 " Expected " + expectedCurrency
+
913 " Received " + tempString
);
917 formatter
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
);
918 failure(status
, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
920 tempString
= formatter
->format (-5789.9876, tempString
);
922 if (tempString
== expectedPercent
) {
923 logln ("Bug 4071005 percentage test passed.");
925 errln(UnicodeString("Failed:") +
926 " Expected " + expectedPercent
+
927 " Received " + tempString
);
934 * Data rounding errors for German (Germany) locale
936 void NumberFormatRegressionTest::Test4071014 (void)
938 NumberFormat
*formatter
;
939 UnicodeString tempString
;
941 String expectedDefault = "-5.789,987";
942 String expectedCurrency = "5.789,98 DM";
943 String expectedPercent = "-578.998%";
945 UnicodeString
expectedDefault("-5.789,988");
946 UnicodeString
expectedCurrency("5.789,99 DM");
947 UnicodeString
expectedPercent("-578.999%");
949 UErrorCode status
= U_ZERO_ERROR
;
951 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
952 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
953 failure(status
, "NumberFormat::createNumberInstance", loc
);
955 tempString
= formatter
->format (-5789.9876, tempString
);
957 if (tempString
== expectedDefault
) {
958 logln ("Bug 4071014 default test passed.");
960 errln(UnicodeString("Failed:") +
961 " Expected " + expectedDefault
+
962 " Received " + tempString
);
965 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
966 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
967 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
969 tempString
= formatter
->format( 5789.9876, tempString
);
971 if (tempString
== expectedCurrency
) {
972 logln ("Bug 4071014 currency test assed.");
974 errln(UnicodeString("Failed:") +
975 " Expected " + expectedCurrency
+
976 " Received " + tempString
);
980 formatter
= NumberFormat::createPercentInstance(Locale::getGermany(), status
);
981 failure(status
, "NumberFormat::createPercentInstance", Locale::getGermany());
983 tempString
= formatter
->format (-5789.9876, tempString
);
985 if (tempString
== expectedPercent
) {
986 logln ("Bug 4071014 percentage test passed.");
988 errln(UnicodeString("Failed:") +
989 " Expected " + expectedPercent
+
990 " Received " + tempString
);
996 * Data rounding errors for Italian locale number formats
998 void NumberFormatRegressionTest::Test4071859 (void)
1000 NumberFormat
*formatter
;
1001 UnicodeString tempString
;
1003 String expectedDefault = "-5.789,987";
1004 String expectedCurrency = "-L. 5.789,98";
1005 String expectedPercent = "-578.998%";
1007 UnicodeString
expectedDefault("-5.789,988");
1008 UnicodeString
expectedCurrency("-\\u20A4 5.790");
1009 UnicodeString
expectedPercent("-578.999%");
1010 expectedCurrency
= expectedCurrency
.unescape();
1012 UErrorCode status
= U_ZERO_ERROR
;
1014 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1015 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1016 failure(status
, "NumberFormat::createNumberInstance");
1017 tempString
= formatter
->format (-5789.9876, tempString
);
1019 if (tempString
== expectedDefault
) {
1020 logln ("Bug 4071859 default test passed.");
1022 errln(UnicodeString("Failed:") +
1023 " Expected " + expectedDefault
+
1024 " Received " + tempString
);
1027 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1028 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1029 failure(status
, "NumberFormat::createCurrencyInstance");
1030 tempString
.remove();
1031 tempString
= formatter
->format( -5789.9876, tempString
);
1033 if (tempString
== expectedCurrency
) {
1034 logln ("Bug 4071859 currency test assed.");
1036 errln(UnicodeString("Failed:") +
1037 " Expected " + expectedCurrency
+
1038 " Received " + tempString
);
1041 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1042 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
1043 failure(status
, "NumberFormat::createPercentInstance");
1044 tempString
.remove();
1045 tempString
= formatter
->format (-5789.9876, tempString
);
1047 if (tempString
== expectedPercent
) {
1048 logln ("Bug 4071859 percentage test passed.");
1050 errln(UnicodeString("Failed:") +
1051 " Expected " + expectedPercent
+
1052 " Received " + tempString
);
1058 * Test rounding for nearest even.
1060 void NumberFormatRegressionTest::Test4093610(void)
1062 UErrorCode status
= U_ZERO_ERROR
;
1063 DecimalFormat
*df
= new DecimalFormat("#0.#", status
);
1064 failure(status
, "new DecimalFormat");
1065 UnicodeString
s("12.4");
1066 roundingTest(df
, 12.35, s
);
1067 roundingTest(df
, 12.45, s
);
1069 roundingTest(df
, 12.452,s
);
1071 roundingTest(df
, 12.55, s
);
1072 roundingTest(df
, 12.65, s
);
1074 roundingTest(df
, 12.652,s
);
1076 roundingTest(df
, 12.75, s
);
1077 roundingTest(df
, 12.752,s
);
1078 roundingTest(df
, 12.85, s
);
1080 roundingTest(df
, 12.852,s
);
1082 roundingTest(df
, 12.95, s
);
1083 roundingTest(df
, 12.952,s
);
1088 void NumberFormatRegressionTest::roundingTest(DecimalFormat
*df
, double x
, UnicodeString
& expected
)
1091 FieldPosition
pos(FieldPosition::DONT_CARE
);
1092 out
= df
->format(x
, out
, pos
);
1093 logln(UnicodeString("") + x
+ " formats with 1 fractional digits to " + out
);
1094 if (out
!= expected
)
1095 errln("FAIL: Expected " + expected
);
1098 * Tests the setMaximumFractionDigits limit.
1100 void NumberFormatRegressionTest::Test4098741(void)
1103 UErrorCode status
= U_ZERO_ERROR
;
1104 NumberFormat
*fmt
= NumberFormat::createPercentInstance(status
);
1105 fmt
->setMaximumFractionDigits(20);
1107 logln(fmt
->format(.001, temp
));
1108 /*} catch (Exception foo) {
1109 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1114 * Tests illegal pattern exception.
1115 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1116 * Part2 has been fixed.
1118 void NumberFormatRegressionTest::Test4074454(void)
1121 UErrorCode status
= U_ZERO_ERROR
;
1122 DecimalFormat
*fmt
= new DecimalFormat("#,#00.00;-#.#", status
);
1123 if(U_FAILURE(status
)) {
1124 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1128 failure(status
, "new DecimalFormat");
1129 logln("Inconsistent negative pattern is fine.");
1130 DecimalFormat
*newFmt
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
);
1131 failure(status
, "new DecimalFormat");
1132 UnicodeString tempString
;
1133 FieldPosition
pos(FieldPosition::DONT_CARE
);
1134 tempString
= newFmt
->format(3456.78, tempString
, pos
);
1135 if (tempString
!= UnicodeString("3,456.78 p'ieces"))
1136 errln("Failed! 3456.78 p'ieces expected, but got : " + tempString
);
1137 /*} catch (Exception foo) {
1138 errln("An exception was thrown for any inconsistent negative pattern.");
1145 * Tests all different comments.
1146 * Response to some comments :
1147 * [1] DecimalFormat.parse API documentation is more than just one line.
1148 * This is not a reproducable doc error in 116 source code.
1149 * [2] See updated javadoc.
1151 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1152 * a null object will be returned. The unchanged parse position also
1153 * reflects an error.
1154 * NumberFormat.parse(String) : If parsing fails, an ParseException
1156 * See updated javadoc for more details.
1157 * [5] See updated javadoc.
1158 * [6] See updated javadoc.
1159 * [7] This is a correct behavior if the DateFormat object is linient.
1160 * Otherwise, an IllegalArgumentException will be thrown when formatting
1161 * "January 35". See GregorianCalendar class javadoc for more details.
1163 void NumberFormatRegressionTest::Test4099404(void)
1166 UErrorCode status
= U_ZERO_ERROR
;
1167 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("000.0#0"), status
);
1168 if(! U_FAILURE(status
))
1169 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1170 /*} catch (Exception foo) {
1171 logln("Bug 4099404 pattern \"000.0#0\" passed");
1176 fmt
= new DecimalFormat(UnicodeString("0#0.000"), status
);
1177 if( !U_FAILURE(status
))
1178 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1179 /*} catch (Exception foo) {
1180 logln("Bug 4099404 pattern \"0#0.000\" passed");
1186 * DecimalFormat.applyPattern doesn't set minimum integer digits
1188 void NumberFormatRegressionTest::Test4101481(void)
1190 UErrorCode status
= U_ZERO_ERROR
;
1191 DecimalFormat
*sdf
= new DecimalFormat(UnicodeString("#,##0"), status
);
1192 if(U_FAILURE(status
)) {
1193 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1197 failure(status
, "new DecimalFormat");
1198 if (sdf
->getMinimumIntegerDigits() != 1)
1199 errln("Minimum integer digits : " + sdf
->getMinimumIntegerDigits());
1202 /* @bug 4052223 (API addition request A27)
1203 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1205 void NumberFormatRegressionTest::Test4052223(void)
1208 UErrorCode status
= U_ZERO_ERROR
;
1209 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,#00.00"), status
);
1210 if(U_FAILURE(status
)) {
1211 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1215 failure(status
, "new DecimalFormat");
1217 fmt
->parse(UnicodeString("abc3"), num
, status
);
1218 if(! U_FAILURE(status
))
1219 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1220 /*} catch (ParseException foo) {
1221 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1226 * API tests for API addition request A9.
1228 void NumberFormatRegressionTest::Test4061302(void)
1230 UErrorCode status
= U_ZERO_ERROR
;
1231 DecimalFormatSymbols
*fmt
= new DecimalFormatSymbols(status
);
1232 failure(status
, "new DecimalFormatSymbols");
1233 UnicodeString
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1234 UnicodeString
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1235 UnicodeString
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1236 if (currency
== UnicodeString("") ||
1237 intlCurrency
== UnicodeString("") ||
1238 monDecSeparator
== UnicodeString(""))
1240 errln("getCurrencySymbols failed, got empty string.");
1242 UnicodeString monDecSeparatorStr
;
1243 monDecSeparatorStr
.append(monDecSeparator
);
1244 logln((UnicodeString
)"Before set ==> Currency : " + currency
+(UnicodeString
)" Intl Currency : " + intlCurrency
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
);
1245 fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ"));
1246 fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC"));
1247 fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/));
1248 currency
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
);
1249 intlCurrency
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
1250 monDecSeparator
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1251 if (currency
!= UnicodeString("XYZ") ||
1252 intlCurrency
!= UnicodeString("ABC") ||
1253 monDecSeparator
!= UnicodeString((UChar
)0x002A/*'*'*/)) {
1254 errln("setCurrencySymbols failed.");
1256 monDecSeparatorStr
.remove();
1257 monDecSeparatorStr
.append(monDecSeparator
);
1258 logln("After set ==> Currency : " + currency
+ " Intl Currency : " + intlCurrency
+ " Monetary Decimal Separator : " + monDecSeparatorStr
);
1263 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1264 * FieldPosition.getEndIndex.
1266 void NumberFormatRegressionTest::Test4062486(void)
1268 UErrorCode status
= U_ZERO_ERROR
;
1269 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,##0.00"), status
);
1270 failure(status
, "new DecimalFormat");
1271 UnicodeString formatted
;
1272 FieldPosition
field(0);
1273 double num
= 1234.5;
1274 fmt
->format(num
, formatted
, field
);
1275 if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5)
1276 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1277 field
.setBeginIndex(7);
1278 field
.setEndIndex(4);
1279 if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4)
1280 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1286 * DecimalFormat.parse incorrectly works with a group separator.
1288 void NumberFormatRegressionTest::Test4108738(void)
1290 UErrorCode status
= U_ZERO_ERROR
;
1291 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getUS(), status
);
1292 failure(status
, "new DecimalFormatSymbols");
1293 DecimalFormat
*df
= new DecimalFormat("#,##0.###", syms
, status
);
1294 if(U_FAILURE(status
)) {
1295 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1299 failure(status
, "new DecimalFormat");
1300 UnicodeString
text("1.222,111");
1302 ParsePosition
pp(0);
1303 df
->parse(text
, num
, pp
);
1305 // {sfb} how to do this (again) ?
1306 // shouldn't just be another round-trip test, should it?
1308 FieldPosition
pos(FieldPosition::DONT_CARE
);
1309 temp
= df
->format(num
.getDouble(), temp
, pos
);
1310 //if (!num.toString().equals("1.222"))
1311 if (temp
!= UnicodeString("1.222"))
1312 //errln("\"" + text + "\" is parsed as " + num);
1313 errln("\"" + text
+ "\" is parsed as " + temp
);
1314 text
= UnicodeString("1.222x111");
1315 pp
= ParsePosition(0);
1316 df
->parse(text
, num
, pp
);
1318 temp
= df
->format(num
.getDouble(), temp
, pos
);
1319 //if (!num.toString().equals("1.222"))
1320 if (temp
!= UnicodeString("1.222"))
1321 errln("\"" + text
+ "\" is parsed as " + temp
);
1327 * DecimalFormat.format() incorrectly formats negative doubles.
1329 void NumberFormatRegressionTest::Test4106658(void)
1331 UErrorCode status
= U_ZERO_ERROR
;
1332 DecimalFormat
*df
= new DecimalFormat(status
); // Corrected; see 4147706
1333 if(U_FAILURE(status
)) {
1334 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1338 failure(status
, "new DecimalFormat");
1339 volatile double d1
= 0.0; // volatile to prevent code optimization
1340 double d2
= -0.0001;
1341 UnicodeString buffer
;
1343 FieldPosition
pos(FieldPosition::DONT_CARE
);
1346 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1348 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1350 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1351 df
->format(d1
, buffer
, pos
);
1352 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1353 errln(UnicodeString("") + d1
+ " is formatted as " + buffer
);
1355 df
->format(d2
, buffer
, pos
);
1356 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1357 errln(UnicodeString("") + d2
+ " is formatted as " + buffer
);
1363 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1365 void NumberFormatRegressionTest::Test4106662(void)
1367 UErrorCode status
= U_ZERO_ERROR
;
1368 DecimalFormat
*df
= new DecimalFormat(status
);
1369 if(U_FAILURE(status
)) {
1370 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1374 failure(status
, "new DecimalFormat");
1375 UnicodeString
text("x");
1376 ParsePosition
pos1(0), pos2(0);
1379 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1381 df
->parse(text
, num
, pos1
);
1382 if (pos1
== ParsePosition(0)/*num != null*/) {
1383 errln(UnicodeString("Test Failed: \"") + text
+ "\" is parsed as " /*+ num*/);
1386 df
= new DecimalFormat(UnicodeString("$###.00"), status
);
1387 failure(status
, "new DecimalFormat");
1388 df
->parse(UnicodeString("$"), num
, pos2
);
1389 if (pos2
== ParsePosition(0) /*num != null*/){
1390 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1396 /* @bug 4114639 (duplicate of 4106662)
1397 * NumberFormat.parse doesn't return null
1399 void NumberFormatRegressionTest::Test4114639(void)
1401 UErrorCode status
= U_ZERO_ERROR
;
1402 NumberFormat
*format
= NumberFormat::createInstance(status
);
1403 if(U_FAILURE(status
)) {
1404 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1408 failure(status
, "NumberFormat::createInstance");
1409 UnicodeString
text("time 10:x");
1410 ParsePosition
pos(8);
1412 format
->parse(text
, result
, pos
);
1413 if (/*result != null*/pos
.getErrorIndex() != 8)
1414 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1420 * TODO: this test does not work because we need to use a 64 bit number and a
1421 * a double only MAY only have 52 bits of precision.
1422 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1424 void NumberFormatRegressionTest::Test4106664(void)
1426 UErrorCode status
= U_ZERO_ERROR
;
1427 DecimalFormat
*df
= new DecimalFormat(status
);
1428 if(U_FAILURE(status
)) {
1429 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1433 failure(status
, "new DecimalFormat");
1434 // {sfb} long in java is 64 bits
1435 /*long*/double n
= 1234567890123456.0;
1436 /*int*/int32_t m
= 12345678;
1437 // {sfb} will this work?
1438 //BigInteger bigN = BigInteger.valueOf(n);
1439 //bigN = bigN.multiply(BigInteger.valueOf(m));
1440 double bigN
= n
* m
;
1441 df
->setMultiplier(m
);
1442 df
->setGroupingUsed(FALSE
);
1444 FieldPosition
pos(FieldPosition::DONT_CARE
);
1445 logln("formated: " +
1446 df
->format(n
, temp
, pos
));
1449 sprintf(buf
, "%g", bigN
);
1450 //logln("expected: " + bigN.toString());
1451 logln(UnicodeString("expected: ") + buf
);
1455 /* @bug 4106667 (duplicate of 4106658)
1456 * DecimalFormat.format incorrectly formats -0.0.
1458 void NumberFormatRegressionTest::Test4106667(void)
1460 UErrorCode status
= U_ZERO_ERROR
;
1461 DecimalFormat
*df
= new DecimalFormat(status
);
1462 if(U_FAILURE(status
)) {
1463 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1467 failure(status
, "new DecimalFormat");
1468 UChar foo
[] = { 0x002B };
1469 UnicodeString
bar(foo
, 1, 1);
1470 volatile double d
= 0.0; // volatile to prevent code optimization
1472 UnicodeString buffer
;
1473 FieldPosition
pos(FieldPosition::DONT_CARE
);
1475 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1477 d
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1479 d
*= -1.0; // Some compilers have a problem with defining -0.0
1481 df
->setPositivePrefix(/*"+"*/bar
);
1482 df
->format(d
, buffer
, pos
);
1483 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1484 errln(/*d + */UnicodeString(" is formatted as ") + buffer
);
1490 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1493 # define MAX_INT_DIGITS 70
1495 # define MAX_INT_DIGITS 128
1498 void NumberFormatRegressionTest::Test4110936(void)
1500 UErrorCode status
= U_ZERO_ERROR
;
1501 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1502 if(U_FAILURE(status
)) {
1503 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1507 failure(status
, "NumberFormat::createInstance");
1508 nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
);
1509 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1510 if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
)
1511 errln("getMaximumIntegerDigits() returns " +
1512 nf
->getMaximumIntegerDigits());
1518 * Locale data should use generic currency symbol
1520 * 1) Make sure that all currency formats use the generic currency symbol.
1521 * 2) Make sure we get the same results using the generic symbol or a
1524 void NumberFormatRegressionTest::Test4122840(void)
1527 const Locale
*locales
= Locale::getAvailableLocales(count
);
1529 for (int i
= 0; i
< count
; i
++) {
1530 UErrorCode status
= U_ZERO_ERROR
;
1531 ResourceBundle
*rb
= new ResourceBundle(
1532 NULL
/*"java.text.resources.LocaleElements"*/,
1533 locales
[i
], status
);
1534 failure(status
, "new ResourceBundle");
1535 ResourceBundle numPat
= rb
->get("NumberPatterns", status
);
1536 failure(status
, "new ResourceBundle(NumberPatterns)");
1538 // Get the currency pattern for this locale. We have to fish it
1539 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1540 // will return the localized symbol, not \00a4
1542 UnicodeString pattern
= numPat
.getStringEx(1, status
);
1543 failure(status
, "rb->getStringArray");
1545 UChar fo
[] = { 0x00A4 };
1546 UnicodeString
foo(fo
, 1, 1);
1548 //if (pattern.indexOf("\u00A4") == -1 ) {
1549 if (pattern
.indexOf(foo
) == -1 ) {
1550 errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) +
1551 " does not contain generic currency symbol:" +
1555 // Create a DecimalFormat using the pattern we got and format a number
1556 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(locales
[i
], status
);
1557 failure(status
, "new DecimalFormatSymbols");
1558 DecimalFormat
*fmt1
= new DecimalFormat(pattern
, *symbols
, status
);
1559 failure(status
, "new DecimalFormat");
1561 UnicodeString result1
;
1562 FieldPosition
pos(FieldPosition::DONT_CARE
);
1563 result1
= fmt1
->format(1.111, result1
, pos
);
1566 // Now substitute in the locale's currency symbol and create another
1567 // pattern. We have to skip locales where the currency symbol
1568 // contains decimal separators, because that confuses things
1570 UChar ba
[] = { 0x002E/*'.'*/ };
1571 UnicodeString
bar(ba
, 1, 1);
1573 if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) {
1574 // {sfb} Also, switch the decimal separator to the monetary decimal
1575 // separator to mimic the behavior of a currency format
1576 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
,
1577 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1579 UnicodeString
buf(pattern
);
1580 for (int j
= 0; j
< buf
.length(); j
++) {
1581 if (buf
[j
] == 0x00a4 ) {
1582 if(buf
[j
+ 1] == 0x00a4) {
1583 // {sfb} added to support double currency marker (intl currency sign)
1584 buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1585 j
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length();
1588 buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1589 j
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1;
1594 DecimalFormat
*fmt2
= new DecimalFormat(buf
, *symbols
, status
);
1595 failure(status
, "new DecimalFormat");
1597 UnicodeString result2
;
1598 fmt2
->format(1.111, result2
, pos
);
1600 if (result1
!= result2
) {
1601 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " +
1602 result1
+ " vs " + result2
);
1615 * DecimalFormat.format() delivers wrong string.
1617 void NumberFormatRegressionTest::Test4125885(void)
1619 UErrorCode status
= U_ZERO_ERROR
;
1620 double rate
= 12.34;
1621 DecimalFormat
*formatDec
= new DecimalFormat ("000.00", status
);
1622 if(U_FAILURE(status
)) {
1623 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1627 failure(status
, "new DecimalFormat");
1629 logln("toPattern: " + formatDec
->toPattern(temp
));
1630 UnicodeString rateString
;
1631 FieldPosition
pos(FieldPosition::DONT_CARE
);
1632 rateString
= formatDec
->format(rate
, rateString
, pos
);
1633 if (rateString
!= UnicodeString("012.34"))
1634 errln("result : " + rateString
+ " expected : 012.34");
1636 delete formatDec
;// = null;
1637 formatDec
= new DecimalFormat ("+000.00%;-000.00%", status
);
1638 failure(status
, "new DecimalFormat");
1639 logln("toPattern: " + formatDec
->toPattern(temp
));
1640 rateString
.remove();
1641 rateString
= formatDec
->format(rate
, rateString
, pos
);
1642 if (rateString
!= UnicodeString("+012.34%"))
1643 errln("result : " + rateString
+ " expected : +012.34%");
1650 * DecimalFormat produces extra zeros when formatting numbers.
1652 void NumberFormatRegressionTest::Test4134034(void)
1654 UErrorCode status
= U_ZERO_ERROR
;
1655 DecimalFormat
*nf
= new DecimalFormat("##,###,###.00", status
);
1656 failure(status
, "new DecimalFormat");
1659 FieldPosition
pos(FieldPosition::DONT_CARE
);
1660 f
= nf
->format(9.02, f
, pos
);
1661 if (f
== UnicodeString("9.02"))
1664 errln("9.02 -> " + f
+ "; want 9.02");
1667 f
= nf
->format((int32_t)0, f
, pos
);
1668 if (f
== UnicodeString(".00"))
1671 errln("0 -> " + f
+ "; want .00");
1678 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1679 * a duplicate of 4134034.
1681 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1682 * Possibly related to bug 4125885.
1684 * This class demonstrates a regression in version 1.1.6
1685 * of DecimalFormat class.
1688 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1689 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1690 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1691 * Value 1.2 Format #0.0# Result '1.2'
1692 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1695 * Value 1.2 Format #.00 Result '1.20'
1696 * Value 1.2 Format 0.00 Result '1.20'
1697 * Value 1.2 Format 00.00 Result '01.20'
1698 * Value 1.2 Format #0.0# Result '1.2'
1699 * Value 1.2 Format #0.00 Result '1.20'
1701 void NumberFormatRegressionTest::Test4134300(void) {
1702 UnicodeString DATA
[] = {
1703 // Pattern Expected string
1704 UnicodeString("#.00"), UnicodeString("1.20"),
1705 UnicodeString("0.00"), UnicodeString("1.20"),
1706 UnicodeString("00.00"), UnicodeString("01.20"),
1707 UnicodeString("#0.0#"), UnicodeString("1.2"),
1708 UnicodeString("#0.00"), UnicodeString("1.20")
1711 for (int i
=0; i
< 10; i
+=2) {
1712 UnicodeString result
;
1713 UErrorCode status
= U_ZERO_ERROR
;
1714 DecimalFormat
*df
= new DecimalFormat(DATA
[i
], status
);
1715 failure(status
, "new DecimalFormat");
1716 FieldPosition
pos(FieldPosition::DONT_CARE
);
1717 result
= df
->format(1.2, result
, pos
);
1718 if (result
!= DATA
[i
+1]) {
1719 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result
+
1720 "; want " + DATA
[i
+1]);
1723 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
);
1732 * Empty pattern produces double negative prefix.
1734 void NumberFormatRegressionTest::Test4140009(void)
1736 UErrorCode status
= U_ZERO_ERROR
;
1737 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1738 failure(status
, "new DecimalFormatSymbols");
1739 DecimalFormat
*f
= new DecimalFormat(UnicodeString(""), syms
, status
);
1740 failure(status
, "new DecimalFormat");
1742 FieldPosition
pos(FieldPosition::DONT_CARE
);
1743 s
= f
->format(123.456, s
, pos
);
1744 if (s
!= UnicodeString("123.456"))
1745 errln("Fail: Format empty pattern x 123.456 => " + s
);
1747 s
= f
->format(-123.456, s
, pos
);
1748 if (s
!= UnicodeString("-123.456"))
1749 errln("Fail: Format empty pattern x -123.456 => " + s
);
1755 * BigDecimal numbers get their fractions truncated by NumberFormat.
1757 // {sfb} not pertinent in C++ ??
1758 void NumberFormatRegressionTest::Test4141750(void) {
1760 UnicodeString str("12345.67");
1761 BigDecimal bd = new BigDecimal(str);
1762 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1763 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1765 catch (Exception e) {
1766 errln(e.toString());
1767 e.printStackTrace();
1773 * DecimalFormat toPattern() doesn't quote special characters or handle
1776 void NumberFormatRegressionTest::Test4145457() {
1778 UErrorCode status
= U_ZERO_ERROR
;
1779 NumberFormat
*nff
= NumberFormat::createInstance(status
);
1780 failure(status
, "NumberFormat::createInstance");
1781 if(nff
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
1782 errln("DecimalFormat needed to continue");
1786 DecimalFormat
*nf
= (DecimalFormat
*)nff
;
1787 DecimalFormatSymbols
*sym
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols();
1788 sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027);
1789 nf
->setDecimalFormatSymbols(*sym
);
1790 double pi
= 3.14159;
1792 UnicodeString PATS
[] = {
1793 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1796 for (int32_t i
=0; i
<2; ++i
) {
1797 nf
->applyPattern(PATS
[i
], status
);
1798 failure(status
, "nf->applyPattern");
1800 FieldPosition
pos(FieldPosition::DONT_CARE
);
1801 out
= nf
->format(pi
, out
, pos
);
1803 pat
= nf
->toPattern(pat
);
1805 ParsePosition
pp(0);
1806 nf
->parse(out
, num
, pp
);
1807 double val
= num
.getDouble();
1809 nf
->applyPattern(pat
, status
);
1810 failure(status
, "nf->applyPattern");
1812 out2
= nf
->format(pi
, out2
, pos
);
1814 pat2
= nf
->toPattern(pat2
);
1815 nf
->parse(out2
, num
, pp
);
1816 double val2
= num
.getDouble();
1819 errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" +
1820 pat
+ "\" vs. \"" + pat2
+ "\"");
1822 logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat
+ '"');
1824 if (val
== val2
&& out
== out2
) {
1825 logln(UnicodeString("Ok ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1826 out
+ "\" -> " + val
+ " -> \"" +
1827 out2
+ "\" -> " + val2
);
1830 errln(UnicodeString("Fail ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1831 out
+ "\" -> " + val
+ " -> \"" +
1832 out2
+ "\" -> " + val2
);
1836 catch (ParseException e) {
1837 errln("Fail: " + e);
1838 e.printStackTrace();
1846 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1848 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1850 void NumberFormatRegressionTest::Test4147295(void)
1852 UErrorCode status
= U_ZERO_ERROR
;
1853 DecimalFormat
*sdf
= new DecimalFormat(status
);
1854 UnicodeString
pattern("#,###");
1855 logln("Applying pattern \"" + pattern
+ "\"");
1856 sdf
->applyPattern(pattern
, status
);
1857 failure(status
, "sdf->applyPattern");
1858 int minIntDig
= sdf
->getMinimumIntegerDigits();
1859 if (minIntDig
!= 0) {
1860 errln("Test failed");
1861 errln(" Minimum integer digits : " + minIntDig
);
1863 errln(" new pattern: " + sdf
->toPattern(temp
));
1865 logln("Test passed");
1866 logln(" Minimum integer digits : " + minIntDig
);
1873 * DecimalFormat formats -0.0 as +0.0
1874 * See also older related bug 4106658, 4106667
1876 void NumberFormatRegressionTest::Test4147706(void)
1878 UErrorCode status
= U_ZERO_ERROR
;
1879 DecimalFormat
*df
= new DecimalFormat("#,##0.0##", status
);
1880 failure(status
, "new DecimalFormat");
1881 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1882 failure(status
, "new DecimalFormatSymbols");
1884 UnicodeString f2
, temp
;
1885 FieldPosition
pos(FieldPosition::DONT_CARE
);
1886 volatile double d1
= 0.0; // volatile to prevent code optimization
1887 double d2
= -0.0001;
1890 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1892 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1894 df
->adoptDecimalFormatSymbols(syms
);
1895 f1
= df
->format(d1
, f1
, pos
);
1896 f2
= df
->format(d2
, f2
, pos
);
1897 if (f1
!= UnicodeString("-0.0")) {
1898 errln(UnicodeString("") + d1
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1
+ '"');
1900 if (f2
!= UnicodeString("-0.0")) {
1901 errln(UnicodeString("") + d2
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2
+ '"');
1908 // Not applicable, since no serialization in C++
1909 /*class myformat implements Serializable
1911 DateFormat _dateFormat = DateFormat.getDateInstance();
1915 GregorianCalendar calendar = new GregorianCalendar();
1916 Date t = calendar.getTime();
1917 String nowStr = _dateFormat.format(t);
1924 * NumberFormat cannot format Double.MAX_VALUE
1926 // TODO: make this test actually test something
1928 NumberFormatRegressionTest::Test4162198(void)
1930 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
1931 double dbl
= INT32_MAX
* 1000.0;
1932 UErrorCode status
= U_ZERO_ERROR
;
1933 NumberFormat
*f
= NumberFormat::createInstance(status
);
1934 if(U_FAILURE(status
)) {
1935 errln("Couldn't create number format");
1938 f
->setMaximumFractionDigits(INT32_MAX
);
1939 f
->setMaximumIntegerDigits(INT32_MAX
);
1942 logln(UnicodeString("The number ") + dbl
+ " formatted to " + s
);
1945 f
->parse(s
, n
, status
);
1946 if(U_FAILURE(status
))
1947 errln("Couldn't parse!");
1948 //} catch (java.text.ParseException e) {
1949 // errln("Caught a ParseException:");
1950 // e.printStackTrace();
1953 //logln("The string " + s + " parsed as " + n);
1955 // {dlf} The old code assumes n is a double, but it isn't any more...
1956 // Formattable apparently does not and never did interconvert... too bad.
1957 //if(n.getDouble() != dbl) {
1958 // errln("Round trip failure");
1960 if (n
.getInt64() != dbl
) {
1961 errln("Round trip failure");
1969 * NumberFormat does not parse negative zero.
1972 NumberFormatRegressionTest::Test4162852(void)
1974 UErrorCode status
= U_ZERO_ERROR
;
1975 for(int32_t i
=0; i
< 2; ++i
) {
1976 NumberFormat
*f
= (i
== 0) ? NumberFormat::createInstance(status
)
1977 : NumberFormat::createPercentInstance(status
);
1978 if(U_FAILURE(status
)) {
1979 errln("Couldn't create number format");
1987 f
->parse(s
, n
, status
);
1988 if(U_FAILURE(status
))
1989 errln("Couldn't parse!");
1990 double e
= n
.getDouble();
1991 logln(UnicodeString("") +
1993 '"' + s
+ '"' + " -> " + e
);
1994 #if (defined(OS390) && !defined(IEEE_754)) || defined(OS400)
1997 if (e
!= 0.0 || 1.0/e
> 0.0) {
1999 logln("Failed to parse negative zero");
2005 static double _u_abs(double a
) { return a
<0?-a
:a
; }
2008 * May 17 1999 sync up - liu
2010 * NumberFormat truncates data
2012 void NumberFormatRegressionTest::Test4167494(void) {
2013 UErrorCode status
= U_ZERO_ERROR
;
2014 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2015 failure(status
, "NumberFormat::createInstance");
2017 double a
= DBL_MAX
* 0.99; // DBL_MAX itself overflows to +Inf
2021 fmt
->parse(s
, num
, status
);
2022 failure(status
, "Parse");
2023 if (num
.getType() == Formattable::kDouble
&&
2024 _u_abs(num
.getDouble() - a
) / a
< 0.01) { // RT within 1%
2025 logln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2026 toString(num
) + " ok");
2028 errln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2029 toString(num
) + " FAIL");
2032 // We don't test Double.MIN_VALUE because the locale data for the US
2033 // currently doesn't specify enough digits to display Double.MIN_VALUE.
2034 // This is correct for now; however, we leave this here as a reminder
2035 // in case we want to address this later.
2041 * May 17 1999 sync up - liu
2043 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2045 void NumberFormatRegressionTest::Test4170798(void) {
2046 UErrorCode status
= U_ZERO_ERROR
;
2047 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2048 failure(status
, "NumberFormat::createInstance");
2049 if(nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
2050 errln("DecimalFormat needed to continue");
2053 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2054 df
->setParseIntegerOnly(TRUE
);
2056 ParsePosition
pos(0);
2057 df
->parse("-0.0", n
, pos
);
2058 if (n
.getType() != Formattable::kLong
2059 || n
.getLong() != 0) {
2060 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
));
2066 * May 17 1999 sync up - liu
2067 * toPattern only puts the first grouping separator in.
2069 void NumberFormatRegressionTest::Test4176114(void) {
2070 const char* DATA
[] = {
2072 "000", "#000", // No grouping
2073 "#000", "#000", // No grouping
2077 "00,000", "#00,000",
2078 "000,000", "#,000,000",
2079 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2081 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2082 UErrorCode status
= U_ZERO_ERROR
;
2084 for (int i
=0; i
<DATA_length
; i
+=2) {
2085 DecimalFormat
df(DATA
[i
], status
);
2086 failure(status
, "DecimalFormat constructor");
2088 UnicodeString
exp(DATA
[i
+1]);
2090 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " +
2091 s
+ ", want " + exp
);
2097 * May 17 1999 sync up - liu
2099 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2101 void NumberFormatRegressionTest::Test4179818(void) {
2102 const char* DATA
[] = {
2103 // Input Pattern Expected output
2104 "1.2511", "#.#", "1.3",
2105 "1.2501", "#.#", "1.3",
2108 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2114 UErrorCode status
= U_ZERO_ERROR
;
2115 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2116 failure(status
, "Construct DecimalFormatSymbols");
2117 DecimalFormat
fmt("#", sym
, status
);
2118 failure(status
, "Construct DecimalFormat");
2119 for (int i
=0; i
<DATA_length
; i
+=3) {
2120 double in
= DOUBLE
[i
/3];
2121 UnicodeString
pat(DATA
[i
+1]);
2122 UnicodeString
exp(DATA
[i
+2]);
2123 fmt
.applyPattern(pat
, status
);
2124 failure(status
, "applyPattern");
2127 fmt
.format(in
, out
, pos
);
2129 logln(UnicodeString("Ok: ") + in
+ " x " + pat
+ " = " + out
);
2131 errln(UnicodeString("FAIL: ") + in
+ " x " + pat
+ " = " + out
+
2132 ", expected " + exp
);
2138 * May 17 1999 sync up - liu
2139 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2140 * This includes the minus sign, currency symbol, international currency
2141 * symbol, percent, and permille. This is filed as bugs 4212072 and
2144 void NumberFormatRegressionTest::Test4212072(void) {
2145 UErrorCode status
= U_ZERO_ERROR
;
2146 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2148 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2149 DecimalFormat
fmt(UnicodeString("#"), sym
, status
);
2150 failure(status
, "DecimalFormat ct", Locale::getUS());
2155 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e);
2156 fmt
.setDecimalFormatSymbols(sym
);
2158 if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) {
2159 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s
+
2163 if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) {
2164 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2167 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d);
2169 fmt
.applyPattern(UnicodeString("#%"), status
);
2170 failure(status
, "applyPattern percent");
2171 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e);
2172 fmt
.setDecimalFormatSymbols(sym
);
2174 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) {
2175 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s
+
2179 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2180 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2183 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25);
2185 fmt
.applyPattern(str("#\\u2030"), status
);
2186 failure(status
, "applyPattern permill");
2187 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e);
2188 fmt
.setDecimalFormatSymbols(sym
);
2190 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) {
2191 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s
+
2195 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2196 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2199 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030);
2201 fmt
.applyPattern(str("\\u00A4#.00"), status
);
2202 failure(status
, "applyPattern currency");
2203 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd");
2204 fmt
.setDecimalFormatSymbols(sym
);
2206 if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) {
2207 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s
+
2211 if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) {
2212 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2215 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$");
2217 fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
);
2218 failure(status
, "applyPattern intl currency");
2219 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL");
2220 fmt
.setDecimalFormatSymbols(sym
);
2222 if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) {
2223 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s
+
2227 if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) {
2228 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2231 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD");
2233 // Since the pattern logic has changed, make sure that patterns round
2234 // trip properly. Test stream in/out integrity too.
2236 const Locale
* avail
= NumberFormat::getAvailableLocales(n
);
2237 static const char* type
[] = {
2242 for (int i
=0; i
<n
; ++i
) {
2243 for (int j
=0; j
<3; ++j
) {
2244 status
= U_ZERO_ERROR
;
2248 nf
= NumberFormat::createInstance(avail
[i
], status
);
2249 failure(status
, "createInstance", avail
[i
]);
2252 nf
= NumberFormat::createCurrencyInstance(avail
[i
], status
);
2253 failure(status
, "createCurrencyInstance", avail
[i
]);
2256 nf
= NumberFormat::createPercentInstance(avail
[i
], status
);
2257 failure(status
, "createPercentInstance", avail
[i
]);
2260 if (U_FAILURE(status
)) {
2263 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2265 // Test toPattern/applyPattern round trip
2268 DecimalFormatSymbols
symb(avail
[i
], status
);
2269 failure(status
, "Construct DecimalFormatSymbols", avail
[i
]);
2270 DecimalFormat
f2(pat
, symb
, status
);
2272 UnicodeString("Construct DecimalFormat(") + pat
+ ")")) {
2277 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2279 "\" -> \"" + f2
.toPattern(p
) + "\"");
2282 // Test toLocalizedPattern/applyLocalizedPattern round trip
2283 df
->toLocalizedPattern(pat
);
2284 f2
.applyLocalizedPattern(pat
, status
);
2286 UnicodeString("applyLocalizedPattern(") + pat
+ ")", avail
[i
]);
2287 if (U_FAILURE(status
)) {
2292 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2293 " -> localized \"" + pat
+
2294 "\" -> \"" + f2
.toPattern(p
) + "\"");
2299 // Test writeObject/readObject round trip
2300 // NOT ON ICU -- Java only
2306 * May 17 1999 sync up - liu
2307 * DecimalFormat.parse() fails for mulipliers 2^n.
2309 void NumberFormatRegressionTest::Test4216742(void) {
2310 UErrorCode status
= U_ZERO_ERROR
;
2311 DecimalFormat
*fmt
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
);
2312 failure(status
, "createInstance", Locale::getUS());
2313 int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 };
2314 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2315 for (int i
=0; i
<DATA_length
; ++i
) {
2316 UnicodeString
str((UnicodeString
)"" + DATA
[i
]);
2317 for (int m
= 1; m
<= 100; m
++) {
2318 fmt
->setMultiplier(m
);
2320 fmt
->parse(str
, num
, status
);
2321 failure(status
, "parse", Locale::getUS());
2322 if (num
.getType() != Formattable::kLong
&&
2323 num
.getType() != Formattable::kDouble
) {
2324 errln(UnicodeString("FAIL: Wanted number, got ") +
2327 double d
= num
.getType() == Formattable::kDouble
?
2328 num
.getDouble() : (double) num
.getLong();
2329 if (d
> 0 != DATA
[i
] > 0) {
2330 errln(UnicodeString("\"") + str
+ "\" parse(x " +
2331 fmt
->getMultiplier() +
2332 ") => " + toString(num
));
2341 * May 17 1999 sync up - liu
2342 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2345 void NumberFormatRegressionTest::Test4217661(void) {
2346 const double D
[] = { 0.001, 1.001, 0.006, 1.006 };
2347 const char* S
[] = { "0", "1", "0.01", "1.01" };
2348 int D_length
= (int)(sizeof(D
) / sizeof(D
[0]));
2349 UErrorCode status
= U_ZERO_ERROR
;
2350 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2351 failure(status
, "createInstance", Locale::getUS());
2352 fmt
->setMaximumFractionDigits(2);
2353 for (int i
=0; i
<D_length
; i
++) {
2355 fmt
->format(D
[i
], s
);
2356 if (s
!= UnicodeString(S
[i
])) {
2357 errln(UnicodeString("FAIL: Got ") + s
+ ", exp " + S
[i
]);
2364 * alphaWorks upgrade
2366 void NumberFormatRegressionTest::Test4161100(void) {
2367 UErrorCode status
= U_ZERO_ERROR
;
2368 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2369 failure(status
, "createInstance", Locale::getUS());
2370 nf
->setMinimumFractionDigits(1);
2371 nf
->setMaximumFractionDigits(1);
2376 logln(UnicodeString() + a
+ " x " +
2377 ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
);
2378 if (s
!= UnicodeString("-0.1")) {
2385 * June 16 1999 sync up - liu
2386 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2388 void NumberFormatRegressionTest::Test4243011(void) {
2389 UErrorCode status
= U_ZERO_ERROR
;
2390 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2391 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2392 DecimalFormat
fmt(UnicodeString("0."), sym
, status
);
2393 failure(status
, "DecimalFormat ct", Locale::getUS());
2395 const double NUM
[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2396 const char* STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2397 int32_t N
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0]));
2399 for (int32_t i
=0; i
<N
; ++i
) {
2401 UnicodeString
exp(STR
[i
]);
2403 fmt
.format(NUM
[i
], str
, pos
);
2405 logln(UnicodeString("Ok ") + NUM
[i
] + " x 0. = " + str
);
2407 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str
+
2414 * June 16 1999 sync up - liu
2415 * format(0.0) gives "0.1" if preceded by parse("99.99").
2416 * (Regression in 1.2.2 RC1)
2418 void NumberFormatRegressionTest::Test4243108(void) {
2419 UErrorCode status
= U_ZERO_ERROR
;
2420 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2421 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2422 DecimalFormat
fmt(UnicodeString("#.#"), sym
, status
);
2423 failure(status
, "DecimalFormat ct", Locale::getUS());
2428 fmt
.format(0.0, str
, pos
);
2429 UnicodeString
exp("0");
2431 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2433 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2439 fmt
.parse(str
, val
, status
);
2440 failure(status
, "DecimalFormat.parse(99.99)", Locale::getUS());
2441 if (val
.getType() == Formattable::kDouble
&&
2442 val
.getDouble() == 99.99) {
2443 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val
));
2445 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) +
2450 fmt
.format(0.0, str
, pos
);
2452 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2454 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2461 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2462 * NumberFormat objects.
2464 void NumberFormatRegressionTest::TestJ691(void) {
2465 UErrorCode status
= U_ZERO_ERROR
;
2466 Locale
loc("fr", "CH");
2468 // set up the input date string & expected output
2469 UnicodeString
udt("11.10.2000", "");
2470 UnicodeString
exp("11.10.00", "");
2472 // create a Calendar for this locale
2473 Calendar
*cal
= Calendar::createInstance(loc
, status
);
2474 if (U_FAILURE(status
)) {
2475 errln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2479 // create a NumberFormat for this locale
2480 NumberFormat
*nf
= NumberFormat::createInstance(loc
, status
);
2481 if (U_FAILURE(status
)) {
2482 errln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2486 // *** Here's the key: We don't want to have to do THIS:
2487 // nf->setParseIntegerOnly(TRUE);
2489 // create the DateFormat
2490 DateFormat
*df
= DateFormat::createDateInstance(DateFormat::kShort
, loc
);
2491 if (U_FAILURE(status
)) {
2492 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2496 df
->adoptCalendar(cal
);
2497 df
->adoptNumberFormat(nf
);
2499 // set parsing to lenient & parse
2500 df
->setLenient(TRUE
);
2501 UDate ulocdat
= df
->parse(udt
, status
);
2503 // format back to a string
2504 UnicodeString outString
;
2505 df
->format(ulocdat
, outString
);
2507 if (outString
!= exp
) {
2508 errln("FAIL: " + udt
+ " => " + outString
);
2514 #endif /* #if !UCONFIG_NO_FORMATTING */