1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 1996-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
10 #include "unicode/utypes.h"
12 #if !UCONFIG_NO_FORMATTING
16 #include "unicode/umachine.h"
18 #include "unicode/tblcoll.h"
19 #include "unicode/coleitr.h"
20 #include "unicode/ures.h"
21 #include "unicode/ustring.h"
22 #include "unicode/decimfmt.h"
23 #include "unicode/udata.h"
30 // import com.ibm.text.RuleBasedNumberFormat;
31 // import com.ibm.test.TestFmwk;
33 // import java.util.Locale;
34 // import java.text.NumberFormat;
36 // current macro not in icu1.8.1
37 #define TESTCASE(id,test) \
47 void IntlTestRBNF::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* /*par*/)
49 if (exec
) logln("TestSuite RuleBasedNumberFormat");
52 TESTCASE(0, TestEnglishSpellout
);
53 TESTCASE(1, TestOrdinalAbbreviations
);
54 TESTCASE(2, TestDurations
);
55 TESTCASE(3, TestSpanishSpellout
);
56 TESTCASE(4, TestFrenchSpellout
);
57 TESTCASE(5, TestSwissFrenchSpellout
);
58 TESTCASE(6, TestItalianSpellout
);
59 TESTCASE(7, TestGermanSpellout
);
60 TESTCASE(8, TestThaiSpellout
);
62 TESTCASE(10, TestFractionalRuleSet
);
63 TESTCASE(11, TestSwedishSpellout
);
64 TESTCASE(12, TestBelgianFrenchSpellout
);
65 TESTCASE(13, TestSmallValues
);
66 TESTCASE(14, TestLocalizations
);
67 TESTCASE(15, TestAllLocales
);
68 TESTCASE(16, TestHebrewFraction
);
69 TESTCASE(17, TestPortugueseSpellout
);
70 TESTCASE(18, TestMultiplierSubstitution
);
71 TESTCASE(19, TestSetDecimalFormatSymbols
);
72 TESTCASE(20, TestPluralRules
);
73 TESTCASE(21, TestMultiplePluralRules
);
74 TESTCASE(22, TestInfinityNaN
);
75 TESTCASE(23, TestVariableDecimalPoint
);
76 TESTCASE(24, TestLargeNumbers
);
77 TESTCASE(25, TestCompactDecimalFormatStyle
);
78 TESTCASE(26, TestParseFailure
);
79 TESTCASE(27, TestMinMaxIntegerDigitsIgnored
);
81 TESTCASE(0, TestRBNFDisabled
);
91 void IntlTestRBNF::TestHebrewFraction() {
93 // this is the expected output for 123.45, with no '<' in it.
95 0x05de, 0x05d0, 0x05d4, 0x0020,
96 0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
97 0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
98 0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
99 0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020,
100 0x05d7, 0x05de, 0x05e9, 0x0000,
103 0x05DE, 0x05D0, 0x05D4, 0x0020,
104 0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020,
105 0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020,
106 0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020,
107 0x05D0, 0x05E4, 0x05E1, 0x0020,
108 0x05D0, 0x05E4, 0x05E1, 0x0020,
109 0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020,
110 0x05D7, 0x05DE, 0x05E9, 0x0000,
112 UErrorCode status
= U_ZERO_ERROR
;
113 RuleBasedNumberFormat
* formatter
= new RuleBasedNumberFormat(URBNF_SPELLOUT
, "he_IL", status
);
114 if (status
== U_MISSING_RESOURCE_ERROR
|| status
== U_FILE_ACCESS_ERROR
) {
115 errcheckln(status
, "Failed in constructing RuleBasedNumberFormat - %s", u_errorName(status
));
119 UnicodeString result
;
120 Formattable parseResult
;
123 UnicodeString
expected(text1
);
124 formatter
->format(123.45, result
);
125 if (result
!= expected
) {
126 errln((UnicodeString
)"expected '" + TestUtility::hex(expected
) + "'\nbut got: '" + TestUtility::hex(result
) + "'");
128 // formatter->parse(result, parseResult, pp);
129 // if (parseResult.getDouble() != 123.45) {
130 // errln("expected 123.45 but got: %g", parseResult.getDouble());
135 UnicodeString
expected(text2
);
137 formatter
->format(123.0045, result
);
138 if (result
!= expected
) {
139 errln((UnicodeString
)"expected '" + TestUtility::hex(expected
) + "'\nbut got: '" + TestUtility::hex(result
) + "'");
142 // formatter->parse(result, parseResult, pp);
143 // if (parseResult.getDouble() != 123.0045) {
144 // errln("expected 123.0045 but got: %g", parseResult.getDouble());
152 IntlTestRBNF::TestAPI() {
153 // This test goes through the APIs that were not tested before.
154 // These tests are too small to have separate test classes/functions
156 UErrorCode status
= U_ZERO_ERROR
;
157 RuleBasedNumberFormat
* formatter
158 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getUS(), status
);
159 if (status
== U_MISSING_RESOURCE_ERROR
|| status
== U_FILE_ACCESS_ERROR
) {
160 dataerrln("Unable to create formatter. - %s", u_errorName(status
));
165 logln("RBNF API test starting");
168 logln("Testing Clone");
169 RuleBasedNumberFormat
* rbnfClone
= (RuleBasedNumberFormat
*)formatter
->clone();
170 if(rbnfClone
!= NULL
) {
171 if(!(*rbnfClone
== *formatter
)) {
172 errln("Clone should be semantically equivalent to the original!");
176 errln("Cloning failed!");
182 logln("Testing assignment operator");
183 RuleBasedNumberFormat
assignResult(URBNF_SPELLOUT
, Locale("es", "ES", ""), status
);
184 assignResult
= *formatter
;
185 if(!(assignResult
== *formatter
)) {
186 errln("Assignment result should be semantically equivalent to the original!");
190 // test rule constructor
192 logln("Testing rule constructor");
193 LocalUResourceBundlePointer
en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING
"rbnf", "en", &status
));
194 if(U_FAILURE(status
)) {
195 errln("Unable to access resource bundle with data!");
199 LocalUResourceBundlePointer
rbnfRules(ures_getByKey(en
.getAlias(), "RBNFRules", NULL
, &status
));
200 LocalUResourceBundlePointer
ruleSets(ures_getByKey(rbnfRules
.getAlias(), "SpelloutRules", NULL
, &status
));
202 while (ures_hasNext(ruleSets
.getAlias())) {
203 const UChar
* currentString
= ures_getNextString(ruleSets
.getAlias(), &len
, NULL
, &status
);
205 desc
.append(currentString
);
208 const UChar
*spelloutRules
= desc
.getTerminatedBuffer();
210 if(U_FAILURE(status
) || ruleLen
== 0 || spelloutRules
== NULL
) {
211 errln("Unable to access the rules string!");
214 RuleBasedNumberFormat
ruleCtorResult(spelloutRules
, Locale::getUS(), perror
, status
);
215 if(!(ruleCtorResult
== *formatter
)) {
216 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
219 // Jitterbug 4452, for coverage
220 RuleBasedNumberFormat
nf(spelloutRules
, (UnicodeString
)"", Locale::getUS(), perror
, status
);
221 if(!(nf
== *formatter
)) {
222 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
230 logln("Testing getRules function");
231 UnicodeString rules
= formatter
->getRules();
233 RuleBasedNumberFormat
fromRulesResult(rules
, Locale::getUS(), perror
, status
);
235 if(!(fromRulesResult
== *formatter
)) {
236 errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
242 logln("Testing copy constructor");
243 RuleBasedNumberFormat
copyCtorResult(*formatter
);
244 if(!(copyCtorResult
== *formatter
)) {
245 errln("Copy constructor result result should be semantically equivalent to the original!");
249 #if !UCONFIG_NO_COLLATION
251 #define NUMERIC_STRINGS_NOT_PARSEABLE 1 // ticket/8224
253 // test ruleset names
255 logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule set names");
256 int32_t noOfRuleSetNames
= formatter
->getNumberOfRuleSetNames();
257 if(noOfRuleSetNames
== 0) {
258 errln("Number of rule set names should be more than zero");
260 UnicodeString ruleSetName
;
262 int32_t intFormatNum
= 34567;
263 double doubleFormatNum
= 893411.234;
264 logln("number of rule set names is %i", noOfRuleSetNames
);
265 for(i
= 0; i
< noOfRuleSetNames
; i
++) {
266 FieldPosition pos1
, pos2
;
267 UnicodeString intFormatResult
, doubleFormatResult
;
268 Formattable intParseResult
, doubleParseResult
;
269 #if NUMERIC_STRINGS_NOT_PARSEABLE
270 UBool parseDoubleNonLenientOK
= TRUE
;
271 UBool parseDoubleLenientOK
= TRUE
;
274 ruleSetName
= formatter
->getRuleSetName(i
);
275 log("Rule set name %i is ", i
);
277 logln(". Format results are: ");
278 intFormatResult
= formatter
->format(intFormatNum
, ruleSetName
, intFormatResult
, pos1
, status
);
279 doubleFormatResult
= formatter
->format(doubleFormatNum
, ruleSetName
, doubleFormatResult
, pos2
, status
);
280 if(U_FAILURE(status
)) {
281 errln("Format using a rule set failed");
284 logln(intFormatResult
);
285 logln(doubleFormatResult
);
287 #if NUMERIC_STRINGS_NOT_PARSEABLE
288 // "spellout-numbering-year" ruleSet produces (above) a numeric string using:
289 // "x.x: =#,###0.#=;"
290 // which will not parse (below) - we believe this is CORRECT behavior, as found in ICU 4.0 (see ticket/8224).
291 // Note this numeric string "89,3411.2" will not even parse with Lenient = TRUE because
292 // the NumberFormat (used as last-resort) in NFSubstitution::doParse fails.
293 UnicodeString numberingYear
= UNICODE_STRING_SIMPLE("spellout-numbering-year");
295 // "spellout-ordinal" and "spellout-ordinal-verbose" ruleSets produce (above) a numeric string using:
296 // "x.x: =#,##0.#=;" -> "893,411.2"
297 // which will not parse (below) with Lenient = FALSE, but does parse with Lenient = TRUE because
298 // NFSubstitution::doParse will succeed when using NumberFormat as last-resort.
299 UnicodeString ordinal
= UNICODE_STRING_SIMPLE("spellout-ordinal");
301 // RuleSets other than spellout-numbering-year and spellout-ordinalXXX produce fully spelled out text above
302 // which is fully parseable.
303 parseDoubleLenientOK
= ( ruleSetName
.indexOf(numberingYear
) == -1 );
304 parseDoubleNonLenientOK
= ( ruleSetName
.indexOf(numberingYear
) == -1 && ruleSetName
.indexOf(ordinal
) == -1 );
307 formatter
->setLenient(TRUE
);
308 formatter
->parse(intFormatResult
, intParseResult
, status
);
309 formatter
->parse(doubleFormatResult
, doubleParseResult
, status
);
311 logln("Parse results for lenient = TRUE, %i, %f", intParseResult
.getLong(), doubleParseResult
.getDouble());
313 #if NUMERIC_STRINGS_NOT_PARSEABLE
314 if((!parseDoubleLenientOK
) && (status
== U_INVALID_FORMAT_ERROR
)) {
315 status
= U_USING_FALLBACK_WARNING
;
316 logln("Clearing expected U_INVALID_FORMAT_ERROR during parsing");
320 formatter
->setLenient(FALSE
);
321 formatter
->parse(intFormatResult
, intParseResult
, status
);
322 formatter
->parse(doubleFormatResult
, doubleParseResult
, status
);
324 logln("Parse results for lenient = FALSE, %i, %f", intParseResult
.getLong(), doubleParseResult
.getDouble());
326 #if NUMERIC_STRINGS_NOT_PARSEABLE
327 if((!parseDoubleNonLenientOK
) && (status
== U_INVALID_FORMAT_ERROR
)) {
328 status
= U_USING_FALLBACK_WARNING
;
329 logln("Clearing expected U_INVALID_FORMAT_ERROR during parsing");
333 if(U_FAILURE(status
)) {
334 errln("Error during parsing");
337 intFormatResult
= formatter
->format(intFormatNum
, "BLABLA", intFormatResult
, pos1
, status
);
338 if(U_SUCCESS(status
)) {
339 errln("Using invalid rule set name should have failed");
342 status
= U_ZERO_ERROR
;
343 doubleFormatResult
= formatter
->format(doubleFormatNum
, "TRUC", doubleFormatResult
, pos2
, status
);
344 if(U_SUCCESS(status
)) {
345 errln("Using invalid rule set name should have failed");
348 status
= U_ZERO_ERROR
;
350 status
= U_ZERO_ERROR
;
355 UnicodeString
expected("four point five","");
356 logln("Testing format(double)");
357 UnicodeString result
;
358 formatter
->format(4.5,result
);
359 if(result
!= expected
) {
360 errln("Formatted 4.5, expected " + expected
+ " got " + result
);
362 logln("Formatted 4.5, expected " + expected
+ " got " + result
);
366 formatter
->format((int32_t)4,result
);
367 if(result
!= expected
) {
368 errln("Formatted 4, expected " + expected
+ " got " + result
);
370 logln("Formatted 4, expected " + expected
+ " got " + result
);
375 formatter
->format((int64_t)4, result
, pos
, status
= U_ZERO_ERROR
);
376 if(result
!= expected
) {
377 errln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
379 logln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
382 //Jitterbug 4452, for coverage
385 formatter
->format((int64_t)4, formatter
->getRuleSetName(0), result
, pos2
, status
= U_ZERO_ERROR
);
386 if(result
!= expected
) {
387 errln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
389 logln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
393 logln("Cleaning up");
398 * Perform a simple spot check on the parsing going into an infinite loop for alternate rules.
400 void IntlTestRBNF::TestMultiplePluralRules() {
401 // This is trying to model the feminine form, but don't worry about the details too much.
402 // We're trying to test the plural rules where there are different prefixes.
403 UnicodeString
rules("%spellout-cardinal-feminine-genitive:"
407 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
408 "%spellout-cardinal-feminine:"
409 "x.x: [<< $(cardinal,one{singleton}other{plurality})$ ]>%%fractions>;"
413 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
415 "10: <%spellout-cardinal-feminine< $(cardinal,one{oneth}other{tenth})$;"
416 "100: <%spellout-cardinal-feminine< $(cardinal,one{1hundredth}other{hundredth})$;");
417 UErrorCode status
= U_ZERO_ERROR
;
419 RuleBasedNumberFormat
formatter(rules
, Locale("ru"), pError
, status
);
421 UnicodeString resultStr
;
424 if (U_FAILURE(status
)) {
425 dataerrln("Unable to create formatter - %s", u_errorName(status
));
429 formatter
.parse(formatter
.format(1000.0, resultStr
, pos
, status
), result
, status
);
430 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("one thousand")) {
431 errln("RuleBasedNumberFormat did not return the correct value. Got: %d", result
.getLong());
435 formatter
.parse(formatter
.format(1000.0, UnicodeString("%spellout-cardinal-feminine-genitive"), resultStr
, pos
, status
), result
, status
);
436 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("ono thousand")) {
437 errln("RuleBasedNumberFormat(cardinal-feminine-genitive) did not return the correct value. Got: %d", result
.getLong());
441 formatter
.parse(formatter
.format(1000.0, UnicodeString("%spellout-cardinal-feminine"), resultStr
, pos
, status
), result
, status
);
442 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("one thousand")) {
443 errln("RuleBasedNumberFormat(spellout-cardinal-feminine) did not return the correct value. Got: %d", result
.getLong());
446 static const char* const testData
[][2] = {
450 { "0.1", "one oneth" },
451 { "0.2", "two tenth" },
452 { "1.1", "one singleton one oneth" },
453 { "1.2", "one singleton two tenth" },
454 { "2.1", "two plurality one oneth" },
455 { "2.2", "two plurality two tenth" },
456 { "0.01", "one 1hundredth" },
457 { "0.02", "two hundredth" },
460 doTest(&formatter
, testData
, TRUE
);
463 void IntlTestRBNF::TestFractionalRuleSet()
465 UnicodeString
fracRules(
467 // this rule formats the number if it's 1 or more. It formats
468 // the integral part using a DecimalFormat ("#,##0" puts
469 // thousands separators in the right places) and the fractional
470 // part using %%frac. If there is no fractional part, it
471 // just shows the integral part.
472 " x.0: <#,##0<[ >%%frac>];\n"
473 // this rule formats the number if it's between 0 and 1. It
474 // shows only the fractional part (0.5 shows up as "1/2," not
477 // the fraction rule set. This works the same way as the one in the
478 // preceding example: We multiply the fractional part of the number
479 // being formatted by each rule's base value and use the rule that
480 // produces the result closest to 0 (or the first rule that produces 0).
481 // Since we only provide rules for the numbers from 2 to 10, we know
482 // we'll get a fraction with a denominator between 2 and 10.
483 // "<0<" causes the numerator of the fraction to be formatted
497 int len
= fracRules
.length();
499 for (int i
= 0; i
< len
; ++i
) {
500 UChar ch
= fracRules
.charAt(i
);
502 change
= 2; // change ok
503 } else if (ch
== ':') {
504 change
= 1; // change, but once we hit a non-space char, don't change
505 } else if (ch
== ' ') {
507 fracRules
.setCharAt(i
, (UChar
)0x200e);
516 UErrorCode status
= U_ZERO_ERROR
;
518 RuleBasedNumberFormat
formatter(fracRules
, Locale::getEnglish(), perror
, status
);
519 if (U_FAILURE(status
)) {
520 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
522 static const char* const testData
[][2] = {
535 { "3.125", "3 1/8" },
536 { "4.1428", "4 1/7" },
537 { "5.1667", "5 1/6" },
540 { "8.333", "8 1/3" },
545 { "1.2856", "1 2/7" },
548 doTest(&formatter
, testData
, FALSE
); // exact values aren't parsable from fractions
553 #define LLAssert(a) \
554 if (!(a)) errln("FAIL: " #a)
556 void IntlTestRBNF::TestLLongConstructors()
558 logln("Testing constructors");
560 // constant (shouldn't really be public)
561 LLAssert(llong(llong::kD32
).asDouble() == llong::kD32
);
563 // internal constructor (shouldn't really be public)
564 LLAssert(llong(0, 1).asDouble() == 1);
565 LLAssert(llong(1, 0).asDouble() == llong::kD32
);
566 LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
568 // public empty constructor
569 LLAssert(llong().asDouble() == 0);
571 // public int32_t constructor
572 LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
573 LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
574 LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
575 LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
576 LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
577 LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
579 // public int16_t constructor
580 LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
581 LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
582 LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
583 LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
584 LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
585 LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
587 // public int8_t constructor
588 LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
589 LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
590 LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
591 LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
592 LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
593 LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
595 // public uint16_t constructor
596 LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
597 LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
598 LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
599 LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
600 LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
601 LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
603 // public uint32_t constructor
604 LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
605 LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
606 LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
607 LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
608 LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
609 LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
611 // public double constructor
612 LLAssert(llong((double)0).asDouble() == (double)0);
613 LLAssert(llong((double)1).asDouble() == (double)1);
614 LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
615 LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
616 LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
618 // can't access uprv_maxmantissa, so fake it
619 double maxmantissa
= (llong((int32_t)1) << 40).asDouble();
620 LLAssert(llong(maxmantissa
).asDouble() == maxmantissa
);
621 LLAssert(llong(-maxmantissa
).asDouble() == -maxmantissa
);
624 LLAssert(llong(llong(0, 1)).asDouble() == 1);
625 LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32
);
626 LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
628 // asInt - test unsigned to signed narrowing conversion
629 LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
630 LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
632 // asUInt - test signed to unsigned narrowing conversion
633 LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
634 LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
636 // asDouble already tested
640 void IntlTestRBNF::TestLLongSimpleOperators()
642 logln("Testing simple operators");
645 LLAssert(llong() == llong(0, 0));
646 LLAssert(llong(1,0) == llong(1, 0));
647 LLAssert(llong(0,1) == llong(0, 1));
650 LLAssert(llong(1,0) != llong(1,1));
651 LLAssert(llong(0,1) != llong(1,1));
652 LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
655 LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
658 LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
661 LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
662 LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
665 LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
666 LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
669 LLAssert(llong(1, 1) > llong(1, 0));
670 LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
671 LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
672 LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
673 LLAssert(llong(1, 0) > llong(0, 0xffffffff));
674 LLAssert(llong(0, 0) > llong(0x80000000, 1));
677 LLAssert(llong(1, 0) < llong(1, 1));
678 LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
679 LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
680 LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
681 LLAssert(llong(0, 0xffffffff) < llong(1, 0));
682 LLAssert(llong(0x80000000, 1) < llong(0, 0));
685 LLAssert(llong(1, 1) >= llong(1, 0));
686 LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
687 LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
688 LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
689 LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
690 LLAssert(llong(0, 0) >= llong(0x80000000, 1));
691 LLAssert(llong() >= llong(0, 0));
692 LLAssert(llong(1,0) >= llong(1, 0));
693 LLAssert(llong(0,1) >= llong(0, 1));
696 LLAssert(llong(1, 0) <= llong(1, 1));
697 LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
698 LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
699 LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
700 LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
701 LLAssert(llong(0x80000000, 1) <= llong(0, 0));
702 LLAssert(llong() <= llong(0, 0));
703 LLAssert(llong(1,0) <= llong(1, 0));
704 LLAssert(llong(0,1) <= llong(0, 1));
707 LLAssert(llong() == (int32_t)0);
708 LLAssert(llong(0,1) == (int32_t)1);
711 LLAssert(llong(1,0) != (int32_t)0);
712 LLAssert(llong(0,1) != (int32_t)2);
713 LLAssert(llong(0,0xffffffff) != (int32_t)-1);
715 llong
negOne(0xffffffff, 0xffffffff);
718 LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
719 LLAssert(negOne
> (int32_t)-2);
720 LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
721 LLAssert(llong(0, 0) > (int32_t)-1);
724 LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
725 LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
728 LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
729 LLAssert(negOne
>= (int32_t)-2);
730 LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
731 LLAssert(llong(0, 0) >= (int32_t)-1);
732 LLAssert(llong() >= (int32_t)0);
733 LLAssert(llong(0,1) >= (int32_t)1);
736 LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
737 LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
738 LLAssert(llong() <= (int32_t)0);
739 LLAssert(llong(0,1) <= (int32_t)1);
742 LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
745 LLAssert((llong(1, 1) <<= 0) == llong(1, 1));
746 LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
747 LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
748 LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
749 LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
750 LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
753 LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
755 // operator >>= (sign extended)
756 LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
757 LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
758 LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
759 LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
760 LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
761 LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
763 // operator >> sign extended)
764 LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
766 // ushr (right shift without sign extension)
767 LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
768 LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
769 LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
770 LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
771 LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
772 LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
775 LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
778 LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
781 LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
784 LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
787 LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
790 LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
793 LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
796 LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
799 LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
802 LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
804 // operator&=(uint32)
805 LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
807 // operator|=(uint32)
808 LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
810 // operator^=(uint32)
811 LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
814 LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
817 LLAssert(llong(0,0xffffffff) == --llong(1, 0));
821 llong
n(0, 0xffffffff);
822 LLAssert(llong(0, 0xffffffff) == n
++);
823 LLAssert(llong(1, 0) == n
);
829 LLAssert(llong(1, 0) == n
--);
830 LLAssert(llong(0, 0xffffffff) == n
);
834 LLAssert(llong(0, 0) == -llong(0, 0));
835 LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
836 LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
837 LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
838 LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
843 LLAssert((n
-= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
844 LLAssert(n
== llong(0xffffffff, 0xffffffff));
847 LLAssert((n
-= llong(0, 1)) == llong(0, 0xffffffff));
848 LLAssert(n
== llong(0, 0xffffffff));
854 LLAssert((n
- llong(0, 1)) == llong(0xffffffff, 0xffffffff));
855 LLAssert(n
== llong(0, 0));
858 LLAssert((n
- llong(0, 1)) == llong(0, 0xffffffff));
859 LLAssert(n
== llong(1, 0));
864 llong
n(0xffffffff, 0xffffffff);
865 LLAssert((n
+= llong(0, 1)) == llong(0, 0));
866 LLAssert(n
== llong(0, 0));
868 n
= llong(0, 0xffffffff);
869 LLAssert((n
+= llong(0, 1)) == llong(1, 0));
870 LLAssert(n
== llong(1, 0));
875 llong
n(0xffffffff, 0xffffffff);
876 LLAssert((n
+ llong(0, 1)) == llong(0, 0));
877 LLAssert(n
== llong(0xffffffff, 0xffffffff));
879 n
= llong(0, 0xffffffff);
880 LLAssert((n
+ llong(0, 1)) == llong(1, 0));
881 LLAssert(n
== llong(0, 0xffffffff));
886 void IntlTestRBNF::TestLLong()
888 logln("Starting TestLLong");
890 TestLLongConstructors();
892 TestLLongSimpleOperators();
894 logln("Testing operator*=, operator*");
896 // operator*=, operator*
897 // small and large values, positive, &NEGative, zero
898 // also test commutivity
901 const llong
ONE(0, 1);
902 const llong
NEG_ONE((int32_t)-1);
903 const llong
THREE(0, 3);
904 const llong
NEG_THREE((int32_t)-3);
905 const llong
TWO_TO_16(0, 0x10000);
906 const llong NEG_TWO_TO_16
= -TWO_TO_16
;
907 const llong
TWO_TO_32(1, 0);
908 const llong NEG_TWO_TO_32
= -TWO_TO_32
;
910 const llong
NINE(0, 9);
911 const llong NEG_NINE
= -NINE
;
913 const llong
TWO_TO_16X3(0, 0x00030000);
914 const llong NEG_TWO_TO_16X3
= -TWO_TO_16X3
;
916 const llong
TWO_TO_32X3(3, 0);
917 const llong NEG_TWO_TO_32X3
= -TWO_TO_32X3
;
919 const llong
TWO_TO_48(0x10000, 0);
920 const llong NEG_TWO_TO_48
= -TWO_TO_48
;
922 const int32_t VALUE_WIDTH
= 9;
923 const llong
* values
[VALUE_WIDTH
] = {
924 &ZERO
, &ONE
, &NEG_ONE
, &THREE
, &NEG_THREE
, &TWO_TO_16
, &NEG_TWO_TO_16
, &TWO_TO_32
, &NEG_TWO_TO_32
927 const llong
* answers
[VALUE_WIDTH
*VALUE_WIDTH
] = {
928 &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
,
929 &ZERO
, &ONE
, &NEG_ONE
, &THREE
, &NEG_THREE
, &TWO_TO_16
, &NEG_TWO_TO_16
, &TWO_TO_32
, &NEG_TWO_TO_32
,
930 &ZERO
, &NEG_ONE
, &ONE
, &NEG_THREE
, &THREE
, &NEG_TWO_TO_16
, &TWO_TO_16
, &NEG_TWO_TO_32
, &TWO_TO_32
,
931 &ZERO
, &THREE
, &NEG_THREE
, &NINE
, &NEG_NINE
, &TWO_TO_16X3
, &NEG_TWO_TO_16X3
, &TWO_TO_32X3
, &NEG_TWO_TO_32X3
,
932 &ZERO
, &NEG_THREE
, &THREE
, &NEG_NINE
, &NINE
, &NEG_TWO_TO_16X3
, &TWO_TO_16X3
, &NEG_TWO_TO_32X3
, &TWO_TO_32X3
,
933 &ZERO
, &TWO_TO_16
, &NEG_TWO_TO_16
, &TWO_TO_16X3
, &NEG_TWO_TO_16X3
, &TWO_TO_32
, &NEG_TWO_TO_32
, &TWO_TO_48
, &NEG_TWO_TO_48
,
934 &ZERO
, &NEG_TWO_TO_16
, &TWO_TO_16
, &NEG_TWO_TO_16X3
, &TWO_TO_16X3
, &NEG_TWO_TO_32
, &TWO_TO_32
, &NEG_TWO_TO_48
, &TWO_TO_48
,
935 &ZERO
, &TWO_TO_32
, &NEG_TWO_TO_32
, &TWO_TO_32X3
, &NEG_TWO_TO_32X3
, &TWO_TO_48
, &NEG_TWO_TO_48
, &ZERO
, &ZERO
,
936 &ZERO
, &NEG_TWO_TO_32
, &TWO_TO_32
, &NEG_TWO_TO_32X3
, &TWO_TO_32X3
, &NEG_TWO_TO_48
, &TWO_TO_48
, &ZERO
, &ZERO
939 for (int i
= 0; i
< VALUE_WIDTH
; ++i
) {
940 for (int j
= 0; j
< VALUE_WIDTH
; ++j
) {
941 llong lhs
= *values
[i
];
942 llong rhs
= *values
[j
];
943 llong ans
= *answers
[i
*VALUE_WIDTH
+ j
];
947 LLAssert((n
*= rhs
) == ans
);
951 LLAssert((n
* rhs
) == ans
);
957 logln("Testing operator/=, operator/");
958 // operator/=, operator/
959 // test num = 0, div = 0, pos/neg, > 2^32, div > num
962 const llong
ONE(0, 1);
963 const llong NEG_ONE
= -ONE
;
964 const llong
MAX(0x7fffffff, 0xffffffff);
965 const llong
MIN(0x80000000, 0);
966 const llong
TWO(0, 2);
967 const llong NEG_TWO
= -TWO
;
968 const llong
FIVE(0, 5);
969 const llong NEG_FIVE
= -FIVE
;
970 const llong
TWO_TO_32(1, 0);
971 const llong NEG_TWO_TO_32
= -TWO_TO_32
;
972 const llong TWO_TO_32d5
= llong(TWO_TO_32
.asDouble()/5.0);
973 const llong NEG_TWO_TO_32d5
= -TWO_TO_32d5
;
974 const llong TWO_TO_32X5
= TWO_TO_32
* FIVE
;
975 const llong NEG_TWO_TO_32X5
= -TWO_TO_32X5
;
977 const llong
* tuples
[] = { // lhs, rhs, ans
980 &NEG_ONE
, &ZERO
, &MIN
,
982 &ONE
, &NEG_ONE
, &NEG_ONE
,
983 &NEG_ONE
, &ONE
, &NEG_ONE
,
984 &NEG_ONE
, &NEG_ONE
, &ONE
,
986 &FIVE
, &NEG_TWO
, &NEG_TWO
,
987 &NEG_FIVE
, &TWO
, &NEG_TWO
,
988 &NEG_FIVE
, &NEG_TWO
, &TWO
,
990 &TWO
, &NEG_FIVE
, &ZERO
,
991 &NEG_TWO
, &FIVE
, &ZERO
,
992 &NEG_TWO
, &NEG_FIVE
, &ZERO
,
993 &TWO_TO_32
, &TWO_TO_32
, &ONE
,
994 &TWO_TO_32
, &NEG_TWO_TO_32
, &NEG_ONE
,
995 &NEG_TWO_TO_32
, &TWO_TO_32
, &NEG_ONE
,
996 &NEG_TWO_TO_32
, &NEG_TWO_TO_32
, &ONE
,
997 &TWO_TO_32
, &FIVE
, &TWO_TO_32d5
,
998 &TWO_TO_32
, &NEG_FIVE
, &NEG_TWO_TO_32d5
,
999 &NEG_TWO_TO_32
, &FIVE
, &NEG_TWO_TO_32d5
,
1000 &NEG_TWO_TO_32
, &NEG_FIVE
, &TWO_TO_32d5
,
1001 &TWO_TO_32X5
, &FIVE
, &TWO_TO_32
,
1002 &TWO_TO_32X5
, &NEG_FIVE
, &NEG_TWO_TO_32
,
1003 &NEG_TWO_TO_32X5
, &FIVE
, &NEG_TWO_TO_32
,
1004 &NEG_TWO_TO_32X5
, &NEG_FIVE
, &TWO_TO_32
,
1005 &TWO_TO_32X5
, &TWO_TO_32
, &FIVE
,
1006 &TWO_TO_32X5
, &NEG_TWO_TO_32
, &NEG_FIVE
,
1007 &NEG_TWO_TO_32X5
, &NEG_TWO_TO_32
, &FIVE
,
1008 &NEG_TWO_TO_32X5
, &TWO_TO_32
, &NEG_FIVE
1010 const int TUPLE_WIDTH
= 3;
1011 const int TUPLE_COUNT
= UPRV_LENGTHOF(tuples
)/TUPLE_WIDTH
;
1012 for (int i
= 0; i
< TUPLE_COUNT
; ++i
) {
1013 const llong lhs
= *tuples
[i
*TUPLE_WIDTH
+0];
1014 const llong rhs
= *tuples
[i
*TUPLE_WIDTH
+1];
1015 const llong ans
= *tuples
[i
*TUPLE_WIDTH
+2];
1018 if (!((n
/= rhs
) == ans
)) {
1019 errln("fail: (n /= rhs) == ans");
1024 LLAssert((n
/ rhs
) == ans
);
1029 logln("Testing operator%%=, operator%%");
1030 //operator%=, operator%
1033 const llong
ONE(0, 1);
1034 const llong
TWO(0, 2);
1035 const llong
THREE(0,3);
1036 const llong
FOUR(0, 4);
1037 const llong
FIVE(0, 5);
1038 const llong
SIX(0, 6);
1040 const llong NEG_ONE
= -ONE
;
1041 const llong NEG_TWO
= -TWO
;
1042 const llong NEG_THREE
= -THREE
;
1043 const llong NEG_FOUR
= -FOUR
;
1044 const llong NEG_FIVE
= -FIVE
;
1045 const llong NEG_SIX
= -SIX
;
1047 const llong
NINETY_NINE(0, 99);
1048 const llong
HUNDRED(0, 100);
1049 const llong
HUNDRED_ONE(0, 101);
1051 const llong
BIG(0x12345678, 0x9abcdef0);
1052 const llong
BIG_FIVE(BIG
* FIVE
);
1053 const llong BIG_FIVEm1
= BIG_FIVE
- ONE
;
1054 const llong BIG_FIVEp1
= BIG_FIVE
+ ONE
;
1056 const llong
* tuples
[] = {
1057 &ZERO
, &FIVE
, &ZERO
,
1060 &THREE
, &FIVE
, &THREE
,
1061 &FOUR
, &FIVE
, &FOUR
,
1062 &FIVE
, &FIVE
, &ZERO
,
1064 &ZERO
, &NEG_FIVE
, &ZERO
,
1065 &ONE
, &NEG_FIVE
, &ONE
,
1066 &TWO
, &NEG_FIVE
, &TWO
,
1067 &THREE
, &NEG_FIVE
, &THREE
,
1068 &FOUR
, &NEG_FIVE
, &FOUR
,
1069 &FIVE
, &NEG_FIVE
, &ZERO
,
1070 &SIX
, &NEG_FIVE
, &ONE
,
1071 &NEG_ONE
, &FIVE
, &NEG_ONE
,
1072 &NEG_TWO
, &FIVE
, &NEG_TWO
,
1073 &NEG_THREE
, &FIVE
, &NEG_THREE
,
1074 &NEG_FOUR
, &FIVE
, &NEG_FOUR
,
1075 &NEG_FIVE
, &FIVE
, &ZERO
,
1076 &NEG_SIX
, &FIVE
, &NEG_ONE
,
1077 &NEG_ONE
, &NEG_FIVE
, &NEG_ONE
,
1078 &NEG_TWO
, &NEG_FIVE
, &NEG_TWO
,
1079 &NEG_THREE
, &NEG_FIVE
, &NEG_THREE
,
1080 &NEG_FOUR
, &NEG_FIVE
, &NEG_FOUR
,
1081 &NEG_FIVE
, &NEG_FIVE
, &ZERO
,
1082 &NEG_SIX
, &NEG_FIVE
, &NEG_ONE
,
1083 &NINETY_NINE
, &FIVE
, &FOUR
,
1084 &HUNDRED
, &FIVE
, &ZERO
,
1085 &HUNDRED_ONE
, &FIVE
, &ONE
,
1086 &BIG_FIVEm1
, &FIVE
, &FOUR
,
1087 &BIG_FIVE
, &FIVE
, &ZERO
,
1088 &BIG_FIVEp1
, &FIVE
, &ONE
1090 const int TUPLE_WIDTH
= 3;
1091 const int TUPLE_COUNT
= UPRV_LENGTHOF(tuples
)/TUPLE_WIDTH
;
1092 for (int i
= 0; i
< TUPLE_COUNT
; ++i
) {
1093 const llong lhs
= *tuples
[i
*TUPLE_WIDTH
+0];
1094 const llong rhs
= *tuples
[i
*TUPLE_WIDTH
+1];
1095 const llong ans
= *tuples
[i
*TUPLE_WIDTH
+2];
1098 if (!((n
%= rhs
) == ans
)) {
1099 errln("fail: (n %= rhs) == ans");
1104 LLAssert((n
% rhs
) == ans
);
1109 logln("Testing pow");
1111 LLAssert(llong(0, 0).pow(0) == llong(0, 0));
1112 LLAssert(llong(0, 0).pow(2) == llong(0, 0));
1113 LLAssert(llong(0, 2).pow(0) == llong(0, 1));
1114 LLAssert(llong(0, 2).pow(2) == llong(0, 4));
1115 LLAssert(llong(0, 2).pow(32) == llong(1, 0));
1116 LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
1120 const llong
n(0xffffffff,0xffffffff);
1121 LLAssert(n
.abs() == llong(0, 1));
1125 logln("Testing atoll");
1127 const char empty
[] = "";
1128 const char zero
[] = "0";
1129 const char neg_one
[] = "-1";
1130 const char neg_12345
[] = "-12345";
1131 const char big1
[] = "123456789abcdef0";
1132 const char big2
[] = "fFfFfFfFfFfFfFfF";
1133 LLAssert(llong::atoll(empty
) == llong(0, 0));
1134 LLAssert(llong::atoll(zero
) == llong(0, 0));
1135 LLAssert(llong::atoll(neg_one
) == llong(0xffffffff, 0xffffffff));
1136 LLAssert(llong::atoll(neg_12345
) == -llong(0, 12345));
1137 LLAssert(llong::atoll(big1
, 16) == llong(0x12345678, 0x9abcdef0));
1138 LLAssert(llong::atoll(big2
, 16) == llong(0xffffffff, 0xffffffff));
1142 const UChar uempty
[] = { 0 };
1143 const UChar uzero
[] = { 0x30, 0 };
1144 const UChar uneg_one
[] = { 0x2d, 0x31, 0 };
1145 const UChar uneg_12345
[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1146 const UChar ubig1
[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1147 const UChar ubig2
[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1148 LLAssert(llong::utoll(uempty
) == llong(0, 0));
1149 LLAssert(llong::utoll(uzero
) == llong(0, 0));
1150 LLAssert(llong::utoll(uneg_one
) == llong(0xffffffff, 0xffffffff));
1151 LLAssert(llong::utoll(uneg_12345
) == -llong(0, 12345));
1152 LLAssert(llong::utoll(ubig1
, 16) == llong(0x12345678, 0x9abcdef0));
1153 LLAssert(llong::utoll(ubig2
, 16) == llong(0xffffffff, 0xffffffff));
1156 logln("Testing lltoa");
1159 char buf
[64]; // ascii
1160 LLAssert((llong(0, 0).lltoa(buf
, (uint32_t)sizeof(buf
)) == 1) && (strcmp(buf
, zero
) == 0));
1161 LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf
, (uint32_t)sizeof(buf
)) == 2) && (strcmp(buf
, neg_one
) == 0));
1162 LLAssert(((-llong(0, 12345)).lltoa(buf
, (uint32_t)sizeof(buf
)) == 6) && (strcmp(buf
, neg_12345
) == 0));
1163 LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf
, (uint32_t)sizeof(buf
), 16) == 16) && (strcmp(buf
, big1
) == 0));
1167 logln("Testing u_lltoa");
1171 LLAssert((llong(0, 0).lltou(buf
, (uint32_t)sizeof(buf
)) == 1) && (u_strcmp(buf
, uzero
) == 0));
1172 LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf
, (uint32_t)sizeof(buf
)) == 2) && (u_strcmp(buf
, uneg_one
) == 0));
1173 LLAssert(((-llong(0, 12345)).lltou(buf
, (uint32_t)sizeof(buf
)) == 6) && (u_strcmp(buf
, uneg_12345
) == 0));
1174 LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf
, (uint32_t)sizeof(buf
), 16) == 16) && (u_strcmp(buf
, ubig1
) == 0));
1182 IntlTestRBNF::TestEnglishSpellout()
1184 UErrorCode status
= U_ZERO_ERROR
;
1185 RuleBasedNumberFormat
* formatter
1186 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getUS(), status
);
1187 if (U_FAILURE(status
)) {
1188 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1190 static const char* const testData
[][2] = {
1193 { "15", "fifteen" },
1195 { "23", "twenty-three" },
1196 { "73", "seventy-three" },
1197 { "88", "eighty-eight" },
1198 { "100", "one hundred" },
1199 { "106", "one hundred six" },
1200 { "127", "one hundred twenty-seven" },
1201 { "200", "two hundred" },
1202 { "579", "five hundred seventy-nine" },
1203 { "1,000", "one thousand" },
1204 { "2,000", "two thousand" },
1205 { "3,004", "three thousand four" },
1206 { "4,567", "four thousand five hundred sixty-seven" },
1207 { "15,943", "fifteen thousand nine hundred forty-three" },
1208 { "2,345,678", "two million three hundred forty-five thousand six hundred seventy-eight" },
1209 { "-36", "minus thirty-six" },
1210 { "234.567", "two hundred thirty-four point five six seven" },
1214 doTest(formatter
, testData
, TRUE
);
1216 #if !UCONFIG_NO_COLLATION
1217 formatter
->setLenient(TRUE
);
1218 static const char* lpTestData
[][2] = {
1219 { "fifty-7", "57" },
1220 { " fifty-7", "57" },
1221 { " fifty-7", "57" },
1222 { "2 thousand six HUNDRED fifty-7", "2,657" },
1223 { "fifteen hundred and zero", "1,500" },
1224 { "FOurhundred thiRTY six", "436" },
1227 doLenientParseTest(formatter
, lpTestData
);
1234 IntlTestRBNF::TestOrdinalAbbreviations()
1236 UErrorCode status
= U_ZERO_ERROR
;
1237 RuleBasedNumberFormat
* formatter
1238 = new RuleBasedNumberFormat(URBNF_ORDINAL
, Locale::getUS(), status
);
1240 if (U_FAILURE(status
)) {
1241 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1243 static const char* const testData
[][2] = {
1260 { "12,345", "12,345th" },
1264 doTest(formatter
, testData
, FALSE
);
1270 IntlTestRBNF::TestDurations()
1272 UErrorCode status
= U_ZERO_ERROR
;
1273 RuleBasedNumberFormat
* formatter
1274 = new RuleBasedNumberFormat(URBNF_DURATION
, Locale::getUS(), status
);
1276 if (U_FAILURE(status
)) {
1277 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1279 static const char* const testData
[][2] = {
1280 { "3,600", "1:00:00" }, //move me and I fail
1283 { "24", "24 sec." },
1288 // { "3,600", "1:00:00" },
1289 { "3,740", "1:02:20" },
1290 { "10,293", "2:51:33" },
1294 doTest(formatter
, testData
, TRUE
);
1296 #if !UCONFIG_NO_COLLATION
1297 formatter
->setLenient(TRUE
);
1298 static const char* lpTestData
[][2] = {
1299 { "2-51-33", "10,293" },
1302 doLenientParseTest(formatter
, lpTestData
);
1309 IntlTestRBNF::TestSpanishSpellout()
1311 UErrorCode status
= U_ZERO_ERROR
;
1312 RuleBasedNumberFormat
* formatter
1313 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("es", "ES", ""), status
);
1315 if (U_FAILURE(status
)) {
1316 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1318 static const char* const testData
[][2] = {
1321 { "16", "diecis\\u00e9is" },
1323 { "24", "veinticuatro" },
1324 { "26", "veintis\\u00e9is" },
1325 { "73", "setenta y tres" },
1326 { "88", "ochenta y ocho" },
1328 { "106", "ciento seis" },
1329 { "127", "ciento veintisiete" },
1330 { "200", "doscientos" },
1331 { "579", "quinientos setenta y nueve" },
1333 { "2,000", "dos mil" },
1334 { "3,004", "tres mil cuatro" },
1335 { "4,567", "cuatro mil quinientos sesenta y siete" },
1336 { "15,943", "quince mil novecientos cuarenta y tres" },
1337 { "2,345,678", "dos millones trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1338 { "-36", "menos treinta y seis" },
1339 { "234.567", "doscientos treinta y cuatro coma cinco seis siete" },
1343 doTest(formatter
, testData
, TRUE
);
1349 IntlTestRBNF::TestFrenchSpellout()
1351 UErrorCode status
= U_ZERO_ERROR
;
1352 RuleBasedNumberFormat
* formatter
1353 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getFrance(), status
);
1355 if (U_FAILURE(status
)) {
1356 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1358 static const char* const testData
[][2] = {
1362 { "21", "vingt-et-un" },
1363 { "23", "vingt-trois" },
1364 { "62", "soixante-deux" },
1365 { "70", "soixante-dix" },
1366 { "71", "soixante-et-onze" },
1367 { "73", "soixante-treize" },
1368 { "80", "quatre-vingts" },
1369 { "88", "quatre-vingt-huit" },
1371 { "106", "cent six" },
1372 { "127", "cent vingt-sept" },
1373 { "200", "deux cents" },
1374 { "579", "cinq cent soixante-dix-neuf" },
1375 { "1,000", "mille" },
1376 { "1,123", "mille cent vingt-trois" },
1377 { "1,594", "mille cinq cent quatre-vingt-quatorze" },
1378 { "2,000", "deux mille" },
1379 { "3,004", "trois mille quatre" },
1380 { "4,567", "quatre mille cinq cent soixante-sept" },
1381 { "15,943", "quinze mille neuf cent quarante-trois" },
1382 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent soixante-dix-huit" },
1383 { "-36", "moins trente-six" },
1384 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1388 doTest(formatter
, testData
, TRUE
);
1390 #if !UCONFIG_NO_COLLATION
1391 formatter
->setLenient(TRUE
);
1392 static const char* lpTestData
[][2] = {
1393 { "trente-et-un", "31" },
1394 { "un cent quatre vingt dix huit", "198" },
1397 doLenientParseTest(formatter
, lpTestData
);
1403 static const char* const swissFrenchTestData
[][2] = {
1407 { "21", "vingt-et-un" },
1408 { "23", "vingt-trois" },
1409 { "62", "soixante-deux" },
1410 { "70", "septante" },
1411 { "71", "septante-et-un" },
1412 { "73", "septante-trois" },
1413 { "80", "huitante" },
1414 { "88", "huitante-huit" },
1416 { "106", "cent six" },
1417 { "127", "cent vingt-sept" },
1418 { "200", "deux cents" },
1419 { "579", "cinq cent septante-neuf" },
1420 { "1,000", "mille" },
1421 { "1,123", "mille cent vingt-trois" },
1422 { "1,594", "mille cinq cent nonante-quatre" },
1423 { "2,000", "deux mille" },
1424 { "3,004", "trois mille quatre" },
1425 { "4,567", "quatre mille cinq cent soixante-sept" },
1426 { "15,943", "quinze mille neuf cent quarante-trois" },
1427 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1428 { "-36", "moins trente-six" },
1429 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1434 IntlTestRBNF::TestSwissFrenchSpellout()
1436 UErrorCode status
= U_ZERO_ERROR
;
1437 RuleBasedNumberFormat
* formatter
1438 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("fr", "CH", ""), status
);
1440 if (U_FAILURE(status
)) {
1441 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1443 doTest(formatter
, swissFrenchTestData
, TRUE
);
1448 static const char* const belgianFrenchTestData
[][2] = {
1452 { "21", "vingt-et-un" },
1453 { "23", "vingt-trois" },
1454 { "62", "soixante-deux" },
1455 { "70", "septante" },
1456 { "71", "septante-et-un" },
1457 { "73", "septante-trois" },
1458 { "80", "quatre-vingts" },
1459 { "88", "quatre-vingt huit" },
1460 { "90", "nonante" },
1461 { "91", "nonante-et-un" },
1462 { "95", "nonante-cinq" },
1464 { "106", "cent six" },
1465 { "127", "cent vingt-sept" },
1466 { "200", "deux cents" },
1467 { "579", "cinq cent septante-neuf" },
1468 { "1,000", "mille" },
1469 { "1,123", "mille cent vingt-trois" },
1470 { "1,594", "mille cinq cent nonante-quatre" },
1471 { "2,000", "deux mille" },
1472 { "3,004", "trois mille quatre" },
1473 { "4,567", "quatre mille cinq cent soixante-sept" },
1474 { "15,943", "quinze mille neuf cent quarante-trois" },
1475 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1476 { "-36", "moins trente-six" },
1477 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1483 IntlTestRBNF::TestBelgianFrenchSpellout()
1485 UErrorCode status
= U_ZERO_ERROR
;
1486 RuleBasedNumberFormat
* formatter
1487 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("fr", "BE", ""), status
);
1489 if (U_FAILURE(status
)) {
1490 errcheckln(status
, "rbnf status: 0x%x (%s)\n", status
, u_errorName(status
));
1491 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1493 // Belgian french should match Swiss french.
1494 doTest(formatter
, belgianFrenchTestData
, TRUE
);
1500 IntlTestRBNF::TestItalianSpellout()
1502 UErrorCode status
= U_ZERO_ERROR
;
1503 RuleBasedNumberFormat
* formatter
1504 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getItalian(), status
);
1506 if (U_FAILURE(status
)) {
1507 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1509 static const char* const testData
[][2] = {
1511 { "15", "quindici" },
1513 { "23", "venti\\u00ADtr\\u00E9" },
1514 { "73", "settanta\\u00ADtr\\u00E9" },
1515 { "88", "ottant\\u00ADotto" },
1517 { "101", "cento\\u00ADuno" },
1518 { "103", "cento\\u00ADtr\\u00E9" },
1519 { "106", "cento\\u00ADsei" },
1520 { "108", "cent\\u00ADotto" },
1521 { "127", "cento\\u00ADventi\\u00ADsette" },
1522 { "181", "cent\\u00ADottant\\u00ADuno" },
1523 { "200", "due\\u00ADcento" },
1524 { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" },
1525 { "1,000", "mille" },
1526 { "2,000", "due\\u00ADmila" },
1527 { "3,004", "tre\\u00ADmila\\u00ADquattro" },
1528 { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessanta\\u00ADsette" },
1529 { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaranta\\u00ADtr\\u00E9" },
1530 { "-36", "meno trenta\\u00ADsei" },
1531 { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cinque sei sette" },
1535 doTest(formatter
, testData
, TRUE
);
1541 IntlTestRBNF::TestPortugueseSpellout()
1543 UErrorCode status
= U_ZERO_ERROR
;
1544 RuleBasedNumberFormat
* formatter
1545 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("pt","BR",""), status
);
1547 if (U_FAILURE(status
)) {
1548 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1550 static const char* const testData
[][2] = {
1554 { "23", "vinte e tr\\u00EAs" },
1555 { "73", "setenta e tr\\u00EAs" },
1556 { "88", "oitenta e oito" },
1558 { "106", "cento e seis" },
1559 { "108", "cento e oito" },
1560 { "127", "cento e vinte e sete" },
1561 { "181", "cento e oitenta e um" },
1562 { "200", "duzentos" },
1563 { "579", "quinhentos e setenta e nove" },
1565 { "2,000", "dois mil" },
1566 { "3,004", "tr\\u00EAs mil e quatro" },
1567 { "4,567", "quatro mil e quinhentos e sessenta e sete" },
1568 { "15,943", "quinze mil e novecentos e quarenta e tr\\u00EAs" },
1569 { "-36", "menos trinta e seis" },
1570 { "234.567", "duzentos e trinta e quatro v\\u00EDrgula cinco seis sete" },
1574 doTest(formatter
, testData
, TRUE
);
1579 IntlTestRBNF::TestGermanSpellout()
1581 UErrorCode status
= U_ZERO_ERROR
;
1582 RuleBasedNumberFormat
* formatter
1583 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getGermany(), status
);
1585 if (U_FAILURE(status
)) {
1586 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1588 static const char* const testData
[][2] = {
1590 { "15", "f\\u00fcnfzehn" },
1591 { "20", "zwanzig" },
1592 { "23", "drei\\u00ADund\\u00ADzwanzig" },
1593 { "73", "drei\\u00ADund\\u00ADsiebzig" },
1594 { "88", "acht\\u00ADund\\u00ADachtzig" },
1595 { "100", "ein\\u00ADhundert" },
1596 { "106", "ein\\u00ADhundert\\u00ADsechs" },
1597 { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" },
1598 { "200", "zwei\\u00ADhundert" },
1599 { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzig" },
1600 { "1,000", "ein\\u00ADtausend" },
1601 { "2,000", "zwei\\u00ADtausend" },
1602 { "3,004", "drei\\u00ADtausend\\u00ADvier" },
1603 { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADsechzig" },
1604 { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\u00ADdrei\\u00ADund\\u00ADvierzig" },
1605 { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00ADund\\u00ADsiebzig" },
1609 doTest(formatter
, testData
, TRUE
);
1611 #if !UCONFIG_NO_COLLATION
1612 formatter
->setLenient(TRUE
);
1613 static const char* lpTestData
[][2] = {
1614 { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1617 doLenientParseTest(formatter
, lpTestData
);
1624 IntlTestRBNF::TestThaiSpellout()
1626 UErrorCode status
= U_ZERO_ERROR
;
1627 RuleBasedNumberFormat
* formatter
1628 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("th"), status
);
1630 if (U_FAILURE(status
)) {
1631 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1633 static const char* const testData
[][2] = {
1634 { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1635 { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1636 { "10", "\\u0e2a\\u0e34\\u0e1a" },
1637 { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1638 { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1639 { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1640 { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1644 doTest(formatter
, testData
, TRUE
);
1650 IntlTestRBNF::TestSwedishSpellout()
1652 UErrorCode status
= U_ZERO_ERROR
;
1653 RuleBasedNumberFormat
* formatter
1654 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("sv"), status
);
1656 if (U_FAILURE(status
)) {
1657 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1659 static const char* testDataDefault
[][2] = {
1660 { "101", "ett\\u00adhundra\\u00adett" },
1661 { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" },
1662 { "1,001", "et\\u00adtusen ett" },
1663 { "1,100", "et\\u00adtusen ett\\u00adhundra" },
1664 { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1665 { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00adfyra" },
1666 { "10,001", "tio\\u00adtusen ett" },
1667 { "11,000", "elva\\u00adtusen" },
1668 { "12,000", "tolv\\u00adtusen" },
1669 { "20,000", "tjugo\\u00adtusen" },
1670 { "21,000", "tjugo\\u00adet\\u00adtusen" },
1671 { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1672 { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" },
1673 { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" },
1674 { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhundra" },
1675 { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1676 { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adfem\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" },
1677 { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" },
1678 { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrtio\\u00adfem komma sex sju \\u00e5tta" },
1681 doTest(formatter
, testDataDefault
, TRUE
);
1683 static const char* testDataNeutrum
[][2] = {
1684 { "101", "ett\\u00adhundra\\u00adett" },
1685 { "1,001", "et\\u00adtusen ett" },
1686 { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1687 { "10,001", "tio\\u00adtusen ett" },
1688 { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1692 formatter
->setDefaultRuleSet("%spellout-cardinal-neuter", status
);
1693 if (U_SUCCESS(status
)) {
1694 logln(" testing spellout-cardinal-neuter rules");
1695 doTest(formatter
, testDataNeutrum
, TRUE
);
1698 errln("Can't test spellout-cardinal-neuter rules");
1701 static const char* testDataYear
[][2] = {
1702 { "101", "ett\\u00adhundra\\u00adett" },
1703 { "900", "nio\\u00adhundra" },
1704 { "1,001", "et\\u00adtusen ett" },
1705 { "1,100", "elva\\u00adhundra" },
1706 { "1,101", "elva\\u00adhundra\\u00adett" },
1707 { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" },
1708 { "2,001", "tjugo\\u00adhundra\\u00adett" },
1709 { "10,001", "tio\\u00adtusen ett" },
1713 status
= U_ZERO_ERROR
;
1714 formatter
->setDefaultRuleSet("%spellout-numbering-year", status
);
1715 if (U_SUCCESS(status
)) {
1716 logln("testing year rules");
1717 doTest(formatter
, testDataYear
, TRUE
);
1720 errln("Can't test year rules");
1728 IntlTestRBNF::TestSmallValues()
1730 UErrorCode status
= U_ZERO_ERROR
;
1731 RuleBasedNumberFormat
* formatter
1732 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("en_US"), status
);
1734 if (U_FAILURE(status
)) {
1735 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1737 static const char* const testDataDefault
[][2] = {
1738 { "0.001", "zero point zero zero one" },
1739 { "0.0001", "zero point zero zero zero one" },
1740 { "0.00001", "zero point zero zero zero zero one" },
1741 { "0.000001", "zero point zero zero zero zero zero one" },
1742 { "0.0000001", "zero point zero zero zero zero zero zero one" },
1743 { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1744 { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1745 { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1746 { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1747 { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1748 { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1749 { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1750 { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1751 { "10,000,000.001", "ten million point zero zero one" },
1752 { "10,000,000.0001", "ten million point zero zero zero one" },
1753 { "10,000,000.00001", "ten million point zero zero zero zero one" },
1754 { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1755 { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1756 // { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1757 // { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1758 { "10,000,000", "ten million" },
1759 // { "1,234,567,890.0987654", "one billion, two hundred and thirty-four million, five hundred and sixty-seven thousand, eight hundred and ninety point zero nine eight seven six five four" },
1760 // { "123,456,789.9876543", "one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine point nine eight seven six five four three" },
1761 // { "12,345,678.87654321", "twelve million, three hundred and forty-five thousand, six hundred and seventy-eight point eight seven six five four three two one" },
1762 { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
1763 { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
1764 { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
1765 { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
1766 { "123.321", "one hundred twenty-three point three two one" },
1767 { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1768 { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1772 doTest(formatter
, testDataDefault
, TRUE
);
1779 IntlTestRBNF::TestLocalizations(void)
1782 UnicodeString
rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1783 "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1785 UErrorCode status
= U_ZERO_ERROR
;
1787 RuleBasedNumberFormat
formatter(rules
, perror
, status
);
1788 if (U_FAILURE(status
)) {
1789 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1792 static const char* const testData
[][2] = {
1794 { "5", "yah, some" },
1795 { "423", "plenty" },
1796 { "12345", "more'n you'll ever need" },
1799 doTest(&formatter
, testData
, FALSE
);
1803 UnicodeString
loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1804 static const char* const testData
[][2] = {
1808 { "12345", "tons" },
1811 RuleBasedNumberFormat
formatter0(rules
, loc
, perror
, status
);
1812 if (U_FAILURE(status
)) {
1813 errln("failed to build second formatter");
1815 doTest(&formatter0
, testData
, FALSE
);
1818 // exercise localization info
1819 Locale
locale0("en__VALLEY@turkey=gobblegobble");
1820 Locale
locale1("de_DE_FOO");
1821 Locale
locale2("ja_JP");
1822 UnicodeString name
= formatter0
.getRuleSetName(0);
1823 if ( formatter0
.getRuleSetDisplayName(0, locale0
) == "Main"
1824 && formatter0
.getRuleSetDisplayName(0, locale1
) == "das Main"
1825 && formatter0
.getRuleSetDisplayName(0, locale2
) == "%main"
1826 && formatter0
.getRuleSetDisplayName(name
, locale0
) == "Main"
1827 && formatter0
.getRuleSetDisplayName(name
, locale1
) == "das Main"
1828 && formatter0
.getRuleSetDisplayName(name
, locale2
) == "%main"){
1829 logln("getRuleSetDisplayName tested");
1831 errln("failed to getRuleSetDisplayName");
1835 for (i
= 0; i
< formatter0
.getNumberOfRuleSetDisplayNameLocales(); ++i
) {
1836 Locale locale
= formatter0
.getRuleSetDisplayNameLocale(i
, status
);
1837 if (U_SUCCESS(status
)) {
1838 for (int j
= 0; j
< formatter0
.getNumberOfRuleSetNames(); ++j
) {
1839 UnicodeString name
= formatter0
.getRuleSetName(j
);
1840 UnicodeString lname
= formatter0
.getRuleSetDisplayName(j
, locale
);
1841 UnicodeString msg
= locale
.getName();
1854 static const char* goodLocs
[] = {
1855 "", // zero-length ok, same as providing no localization data
1856 "<<>>", // no public rule sets ok
1857 "<<%main>>", // no localizations ok
1858 "<<%main,>,<en, Main,>>", // comma before close angle ok
1859 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1860 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1861 " \n <\n <\n %main\n >\n , \t <\t en\t , \tfoo \t\t > \n\n > \n ", // Pattern_White_Space ok
1863 int32_t goodLocsLen
= UPRV_LENGTHOF(goodLocs
);
1865 static const char* badLocs
[] = {
1866 " ", // non-zero length
1867 "<>", // empty array
1868 "<", // unclosed outer array
1869 "<<", // unclosed inner array
1870 "<<,>>", // unexpected comma
1871 "<<''>>", // empty string
1872 " x<<%main>>", // first non space char not open angle bracket
1873 "<%main>", // missing inner array
1874 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1875 "<<%main><en, Main>>", // arrays missing separating comma
1876 "<<%main>,<en, main, foo>>", // too many elements in locale data
1877 "<<%main>,<en>>", // too few elements in locale data
1878 "<<<%main>>>", // unexpected open angle
1879 "<<%main<>>>", // unexpected open angle
1880 "<<%main, %other>,<en,,>>", // implicit empty strings
1881 "<<%main>,<en,''>>", // empty string
1882 "<<%main>, < en, '>>", // unterminated quote
1883 "<<%main>, < en, \"<>>", // unterminated quote
1884 "<<%main\">>", // quote in string
1885 "<<%main'>>", // quote in string
1886 "<<%main<>>", // open angle in string
1887 "<<%main>> x", // extra non-space text at end
1890 int32_t badLocsLen
= UPRV_LENGTHOF(badLocs
);
1892 for (i
= 0; i
< goodLocsLen
; ++i
) {
1893 logln("[%d] '%s'", i
, goodLocs
[i
]);
1894 UErrorCode status
= U_ZERO_ERROR
;
1895 UnicodeString
loc(goodLocs
[i
]);
1896 RuleBasedNumberFormat
fmt(rules
, loc
, perror
, status
);
1897 if (U_FAILURE(status
)) {
1898 errln("Failed parse of good localization string: '%s'", goodLocs
[i
]);
1902 for (i
= 0; i
< badLocsLen
; ++i
) {
1903 logln("[%d] '%s'", i
, badLocs
[i
]);
1904 UErrorCode status
= U_ZERO_ERROR
;
1905 UnicodeString
loc(badLocs
[i
]);
1906 RuleBasedNumberFormat
fmt(rules
, loc
, perror
, status
);
1907 if (U_SUCCESS(status
)) {
1908 errln("Successful parse of bad localization string: '%s'", badLocs
[i
]);
1916 IntlTestRBNF::TestAllLocales()
1918 const char* names
[] = {
1921 // " (duration) " // This is English only, and it's not really supported in CLDR anymore.
1923 double numbers
[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
1926 const Locale
* locales
= Locale::getAvailableLocales(count
);
1927 for (int i
= 0; i
< count
; ++i
) {
1928 const Locale
* loc
= &locales
[i
];
1930 for (int j
= 0; j
< 2; ++j
) {
1931 UErrorCode status
= U_ZERO_ERROR
;
1932 RuleBasedNumberFormat
* f
= new RuleBasedNumberFormat((URBNFRuleSetTag
)j
, *loc
, status
);
1934 if (status
== U_USING_DEFAULT_WARNING
|| status
== U_USING_FALLBACK_WARNING
) {
1939 if (U_FAILURE(status
)) {
1940 errln(UnicodeString(loc
->getName()) + names
[j
]
1941 + "ERROR could not instantiate -> " + u_errorName(status
));
1944 #if !UCONFIG_NO_COLLATION
1945 for (unsigned int numidx
= 0; numidx
< UPRV_LENGTHOF(numbers
); numidx
++) {
1946 double n
= numbers
[numidx
];
1951 logln(UnicodeString(loc
->getName()) + names
[j
]
1952 + "success: " + n
+ " -> " + str
);
1955 // We do not validate the result in this test case,
1956 // because there are cases which do not round trip by design.
1960 status
= U_ZERO_ERROR
;
1961 f
->setLenient(FALSE
);
1962 f
->parse(str
, num
, status
);
1963 if (U_FAILURE(status
)) {
1964 errln(UnicodeString(loc
->getName()) + names
[j
]
1965 + "ERROR could not parse '" + str
+ "' -> " + u_errorName(status
));
1967 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1969 if (num
.getType() == Formattable::kLong
&& num
.getLong() != n
) {
1970 errln(UnicodeString(loc
->getName()) + names
[j
]
1971 + UnicodeString("ERROR could not roundtrip ") + n
1972 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getLong());
1974 else if (num
.getType() == Formattable::kDouble
&& (int64_t)(num
.getDouble() * 1000) != (int64_t)(n
*1000)) {
1975 // The epsilon difference is too high.
1976 errln(UnicodeString(loc
->getName()) + names
[j
]
1977 + UnicodeString("ERROR could not roundtrip ") + n
1978 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getDouble());
1981 if (!quick
&& !logKnownIssue("9503") ) {
1983 status
= U_ZERO_ERROR
;
1984 f
->setLenient(TRUE
);
1985 f
->parse(str
, num
, status
);
1986 if (U_FAILURE(status
)) {
1987 errln(UnicodeString(loc
->getName()) + names
[j
]
1988 + "ERROR could not parse(lenient) '" + str
+ "' -> " + u_errorName(status
));
1990 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1992 if (num
.getType() == Formattable::kLong
&& num
.getLong() != n
) {
1993 errln(UnicodeString(loc
->getName()) + names
[j
]
1994 + UnicodeString("ERROR could not roundtrip ") + n
1995 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getLong());
1997 else if (num
.getType() == Formattable::kDouble
&& (int64_t)(num
.getDouble() * 1000) != (int64_t)(n
*1000)) {
1998 // The epsilon difference is too high.
1999 errln(UnicodeString(loc
->getName()) + names
[j
]
2000 + UnicodeString("ERROR could not roundtrip ") + n
2001 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getDouble());
2013 IntlTestRBNF::TestMultiplierSubstitution(void) {
2014 UnicodeString
rules("=#,##0=;1,000,000: <##0.###< million;");
2015 UErrorCode status
= U_ZERO_ERROR
;
2016 UParseError parse_error
;
2017 RuleBasedNumberFormat
*rbnf
=
2018 new RuleBasedNumberFormat(rules
, Locale::getUS(), parse_error
, status
);
2019 if (U_SUCCESS(status
)) {
2022 double n
= 1234000.0;
2023 rbnf
->format(n
, res
, pos
);
2026 UnicodeString
expected(UNICODE_STRING_SIMPLE("1.234 million"));
2027 if (expected
!= res
) {
2028 UnicodeString msg
= "Expected: ";
2029 msg
.append(expected
);
2030 msg
.append(" but got ");
2038 IntlTestRBNF::TestSetDecimalFormatSymbols() {
2039 UErrorCode status
= U_ZERO_ERROR
;
2041 RuleBasedNumberFormat
rbnf(URBNF_ORDINAL
, Locale::getEnglish(), status
);
2042 if (U_FAILURE(status
)) {
2043 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2047 DecimalFormatSymbols
dfs(Locale::getEnglish(), status
);
2048 if (U_FAILURE(status
)) {
2049 errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status
)));
2053 UnicodeString expected
[] = {
2054 UnicodeString("1,001st"),
2055 UnicodeString("1&001st")
2058 double number
= 1001;
2060 UnicodeString result
;
2062 rbnf
.format(number
, result
);
2063 if (result
!= expected
[0]) {
2064 errln("Format Error - Got: " + result
+ " Expected: " + expected
[0]);
2069 /* Set new symbol for testing */
2070 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, UnicodeString("&"), TRUE
);
2071 rbnf
.setDecimalFormatSymbols(dfs
);
2073 rbnf
.format(number
, result
);
2074 if (result
!= expected
[1]) {
2075 errln("Format Error - Got: " + result
+ " Expected: " + expected
[1]);
2079 void IntlTestRBNF::TestPluralRules() {
2080 UErrorCode status
= U_ZERO_ERROR
;
2081 UnicodeString
enRules("%digits-ordinal:-x: ->>;0: =#,##0=$(ordinal,one{st}two{nd}few{rd}other{th})$;");
2082 UParseError parseError
;
2083 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2084 if (U_FAILURE(status
)) {
2085 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2088 const char* const enTestData
[][2] = {
2104 doTest(&enFormatter
, enTestData
, TRUE
);
2106 // This is trying to model the feminine form, but don't worry about the details too much.
2107 // We're trying to test the plural rules.
2108 UnicodeString
ruRules("%spellout-numbering:"
2139 "100: hundred[ >>];"
2140 "200: << hundred[ >>];"
2141 "300: << hundreds[ >>];"
2142 "500: << hundredss[ >>];"
2143 "1000: << $(cardinal,one{thousand}few{thousands}other{thousandss})$[ >>];"
2144 "1000000: << $(cardinal,one{million}few{millions}other{millionss})$[ >>];");
2145 RuleBasedNumberFormat
ruFormatter(ruRules
, Locale("ru"), parseError
, status
);
2146 const char* const ruTestData
[][2] = {
2148 { "100", "hundred" },
2149 { "125", "hundred twenty-five" },
2150 { "399", "three hundreds ninety-nine" },
2151 { "1,000", "one thousand" },
2152 { "1,001", "one thousand one" },
2153 { "2,000", "two thousands" },
2154 { "2,001", "two thousands one" },
2155 { "2,002", "two thousands two" },
2156 { "3,333", "three thousands three hundreds thirty-three" },
2157 { "5,000", "five thousandss" },
2158 { "11,000", "eleven thousandss" },
2159 { "21,000", "twenty-one thousand" },
2160 { "22,000", "twenty-two thousands" },
2161 { "25,001", "twenty-five thousandss one" },
2165 if (U_FAILURE(status
)) {
2166 errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2169 doTest(&ruFormatter
, ruTestData
, TRUE
);
2171 // Make sure there are no divide by 0 errors.
2172 UnicodeString result
;
2173 RuleBasedNumberFormat(ruRules
, Locale("ru"), parseError
, status
).format((int32_t)21000, result
);
2174 if (result
.compare(UNICODE_STRING_SIMPLE("twenty-one thousand")) != 0) {
2175 errln("Got " + result
+ " for 21000");
2180 void IntlTestRBNF::TestInfinityNaN() {
2181 UErrorCode status
= U_ZERO_ERROR
;
2182 UParseError parseError
;
2183 UnicodeString
enRules("%default:"
2186 "NaN: not a number;"
2188 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2189 const char * const enTestData
[][2] = {
2191 {"\\u221E", "infinite"},
2192 {"-\\u221E", "minus infinite"},
2193 {"NaN", "not a number"},
2196 if (U_FAILURE(status
)) {
2197 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2201 doTest(&enFormatter
, enTestData
, true);
2203 // Test the default behavior when the rules are undefined.
2204 UnicodeString
enRules2("%default:"
2207 RuleBasedNumberFormat
enFormatter2(enRules2
, Locale::getEnglish(), parseError
, status
);
2208 if (U_FAILURE(status
)) {
2209 errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2212 const char * const enDefaultTestData
[][2] = {
2214 {"\\u221E", "\\u221E"},
2215 {"-\\u221E", "-\\u221E"},
2220 doTest(&enFormatter2
, enDefaultTestData
, true);
2223 void IntlTestRBNF::TestVariableDecimalPoint() {
2224 UErrorCode status
= U_ZERO_ERROR
;
2225 UParseError parseError
;
2226 UnicodeString
enRules("%spellout-numbering:"
2242 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2243 const char * const enTestPointData
[][2] = {
2244 {"1.1", "one point one"},
2245 {"1.23", "one point two three"},
2246 {"0.4", "xpoint four"},
2249 if (U_FAILURE(status
)) {
2250 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2253 doTest(&enFormatter
, enTestPointData
, true);
2255 DecimalFormatSymbols
decimalFormatSymbols(Locale::getEnglish(), status
);
2256 decimalFormatSymbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UNICODE_STRING_SIMPLE(","));
2257 enFormatter
.setDecimalFormatSymbols(decimalFormatSymbols
);
2258 const char * const enTestCommaData
[][2] = {
2259 {"1.1", "one comma one"},
2260 {"1.23", "one comma two three"},
2261 {"0.4", "xcomma four"},
2264 doTest(&enFormatter
, enTestCommaData
, true);
2267 void IntlTestRBNF::TestLargeNumbers() {
2268 UErrorCode status
= U_ZERO_ERROR
;
2269 RuleBasedNumberFormat
rbnf(URBNF_SPELLOUT
, Locale::getEnglish(), status
);
2271 const char * const enTestFullData
[][2] = {
2272 {"-9007199254740991", "minus nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one"}, // Maximum precision in both a double and a long
2273 {"9007199254740991", "nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one"}, // Maximum precision in both a double and a long
2274 {"-9007199254740992", "minus nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-two"}, // Only precisely contained in a long
2275 {"9007199254740992", "nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-two"}, // Only precisely contained in a long
2276 {"9999999999999998", "nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-eight"},
2277 {"9999999999999999", "nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine"},
2278 {"999999999999999999", "nine hundred ninety-nine quadrillion nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine"},
2279 {"1000000000000000000", "1,000,000,000,000,000,000"}, // The rules don't go to 1 quintillion yet
2280 {"-9223372036854775809", "-9,223,372,036,854,775,809"}, // We've gone beyond 64-bit precision
2281 {"-9223372036854775808", "-9,223,372,036,854,775,808"}, // We've gone beyond +64-bit precision
2282 {"-9223372036854775807", "minus 9,223,372,036,854,775,807"}, // Minimum 64-bit precision
2283 {"-9223372036854775806", "minus 9,223,372,036,854,775,806"}, // Minimum 64-bit precision + 1
2284 {"9223372036854774111", "9,223,372,036,854,774,111"}, // Below 64-bit precision
2285 {"9223372036854774999", "9,223,372,036,854,774,999"}, // Below 64-bit precision
2286 {"9223372036854775000", "9,223,372,036,854,775,000"}, // Below 64-bit precision
2287 {"9223372036854775806", "9,223,372,036,854,775,806"}, // Maximum 64-bit precision - 1
2288 {"9223372036854775807", "9,223,372,036,854,775,807"}, // Maximum 64-bit precision
2289 {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2292 doTest(&rbnf
, enTestFullData
, false);
2295 void IntlTestRBNF::TestCompactDecimalFormatStyle() {
2296 UErrorCode status
= U_ZERO_ERROR
;
2297 UParseError parseError
;
2298 // This is not a common use case, but we're testing it anyway.
2299 UnicodeString
numberPattern("=###0.#####=;"
2300 "1000: <###0.00< K;"
2301 "1000000: <###0.00< M;"
2302 "1000000000: <###0.00< B;"
2303 "1000000000000: <###0.00< T;"
2304 "1000000000000000: <###0.00< Q;");
2305 RuleBasedNumberFormat
rbnf(numberPattern
, UnicodeString(), Locale::getEnglish(), parseError
, status
);
2307 const char * const enTestFullData
[][2] = {
2310 {"999994", "999.99 K"},
2311 {"999995", "1000.00 K"},
2312 {"1000000", "1.00 M"},
2313 {"1200000", "1.20 M"},
2314 {"1200000000", "1.20 B"},
2315 {"1200000000000", "1.20 T"},
2316 {"1200000000000000", "1.20 Q"},
2317 {"4503599627370495", "4.50 Q"},
2318 {"4503599627370496", "4.50 Q"},
2319 {"8990000000000000", "8.99 Q"},
2320 {"9008000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2321 {"9456000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2322 {"10000000000000000", "10.00 Q"}, // Number doesn't precisely fit into a double
2323 {"9223372036854775807", "9223.00 Q"}, // Maximum 64-bit precision
2324 {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2327 doTest(&rbnf
, enTestFullData
, false);
2330 void IntlTestRBNF::TestParseFailure() {
2331 UErrorCode status
= U_ZERO_ERROR
;
2332 RuleBasedNumberFormat
rbnf(URBNF_SPELLOUT
, Locale::getJapanese(), status
);
2333 static const UChar
* testData
[] = {
2334 u
"・・・・・・・・・・・・・・・・・・・・・・・・"
2336 if (assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
2337 for (int i
= 0; i
< UPRV_LENGTHOF(testData
); ++i
) {
2338 UnicodeString
spelledNumberString(testData
[i
]);
2339 Formattable actualNumber
;
2340 rbnf
.parse(spelledNumberString
, actualNumber
, status
);
2341 if (status
!= U_INVALID_FORMAT_ERROR
) { // I would have expected U_PARSE_ERROR, but NumberFormat::parse gives U_INVALID_FORMAT_ERROR
2342 errln("FAIL: string should be unparseable index=%d %s", i
, u_errorName(status
));
2348 void IntlTestRBNF::TestMinMaxIntegerDigitsIgnored() {
2349 IcuTestErrorCode
status(*this, "TestMinMaxIntegerDigitsIgnored");
2351 // NOTE: SimpleDateFormat has an optimization that depends on the fact that min/max integer digits
2352 // do not affect RBNF (see SimpleDateFormat#zeroPaddingNumber).
2353 RuleBasedNumberFormat
rbnf(URBNF_SPELLOUT
, "en", status
);
2354 if (status
.isSuccess()) {
2355 rbnf
.setMinimumIntegerDigits(2);
2356 rbnf
.setMaximumIntegerDigits(3);
2357 UnicodeString result
;
2358 rbnf
.format(3, result
.remove(), status
);
2359 assertEquals("Min integer digits are ignored", u
"three", result
);
2360 rbnf
.format(1012, result
.remove(), status
);
2361 assertEquals("Max integer digits are ignored", u
"one thousand twelve", result
);
2366 IntlTestRBNF::doTest(RuleBasedNumberFormat
* formatter
, const char* const testData
[][2], UBool testParsing
)
2368 // man, error reporting would be easier with printf-style syntax for unicode string and formattable
2370 UErrorCode status
= U_ZERO_ERROR
;
2371 DecimalFormatSymbols
dfs("en", status
);
2372 // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2373 DecimalFormat
decFmt("#,###.################", dfs
, status
);
2374 if (U_FAILURE(status
)) {
2375 errcheckln(status
, "FAIL: could not create NumberFormat - %s", u_errorName(status
));
2377 for (int i
= 0; testData
[i
][0]; ++i
) {
2378 const char* numString
= testData
[i
][0];
2379 const char* expectedWords
= testData
[i
][1];
2381 log("[%i] %s = ", i
, numString
);
2382 Formattable expectedNumber
;
2383 UnicodeString escapedNumString
= UnicodeString(numString
, -1, US_INV
).unescape();
2384 decFmt
.parse(escapedNumString
, expectedNumber
, status
);
2385 if (U_FAILURE(status
)) {
2386 errln("FAIL: decFmt could not parse %s", numString
);
2389 UnicodeString actualString
;
2391 formatter
->format(expectedNumber
, actualString
/* , pos*/, status
);
2392 if (U_FAILURE(status
)) {
2393 UnicodeString msg
= "Fail: formatter could not format ";
2394 decFmt
.format(expectedNumber
, msg
, status
);
2398 UnicodeString expectedString
= UnicodeString(expectedWords
, -1, US_INV
).unescape();
2399 if (actualString
!= expectedString
) {
2400 UnicodeString msg
= "FAIL: check failed for ";
2401 decFmt
.format(expectedNumber
, msg
, status
);
2402 msg
.append(", expected ");
2403 msg
.append(expectedString
);
2404 msg
.append(" but got ");
2405 msg
.append(actualString
);
2409 logln(actualString
);
2411 Formattable parsedNumber
;
2412 formatter
->parse(actualString
, parsedNumber
, status
);
2413 if (U_FAILURE(status
)) {
2414 UnicodeString msg
= "FAIL: formatter could not parse ";
2415 msg
.append(actualString
);
2416 msg
.append(" status code: " );
2417 msg
.append(u_errorName(status
));
2421 if (parsedNumber
!= expectedNumber
2422 && (!uprv_isNaN(parsedNumber
.getDouble()) || !uprv_isNaN(expectedNumber
.getDouble())))
2424 UnicodeString msg
= "FAIL: parse failed for ";
2425 msg
.append(actualString
);
2426 msg
.append(", expected ");
2427 decFmt
.format(expectedNumber
, msg
, status
);
2428 msg
.append(", but got ");
2429 decFmt
.format(parsedNumber
, msg
, status
);
2443 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat
* formatter
, const char* testData
[][2])
2445 UErrorCode status
= U_ZERO_ERROR
;
2446 NumberFormat
* decFmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2447 if (U_FAILURE(status
)) {
2448 errcheckln(status
, "FAIL: could not create NumberFormat - %s", u_errorName(status
));
2450 for (int i
= 0; testData
[i
][0]; ++i
) {
2451 const char* spelledNumber
= testData
[i
][0]; // spelled-out number
2452 const char* asciiUSNumber
= testData
[i
][1]; // number as ascii digits formatted for US locale
2454 UnicodeString spelledNumberString
= UnicodeString(spelledNumber
).unescape();
2455 Formattable actualNumber
;
2456 formatter
->parse(spelledNumberString
, actualNumber
, status
);
2457 if (U_FAILURE(status
)) {
2458 UnicodeString msg
= "FAIL: formatter could not parse ";
2459 msg
.append(spelledNumberString
);
2463 // I changed the logic of this test somewhat from Java-- instead of comparing the
2464 // strings, I compare the Formattables. Hmmm, but the Formattables don't compare,
2465 // so change it back.
2467 UnicodeString asciiUSNumberString
= asciiUSNumber
;
2468 Formattable expectedNumber
;
2469 decFmt
->parse(asciiUSNumberString
, expectedNumber
, status
);
2470 if (U_FAILURE(status
)) {
2471 UnicodeString msg
= "FAIL: decFmt could not parse ";
2472 msg
.append(asciiUSNumberString
);
2476 UnicodeString actualNumberString
;
2477 UnicodeString expectedNumberString
;
2478 decFmt
->format(actualNumber
, actualNumberString
, status
);
2479 decFmt
->format(expectedNumber
, expectedNumberString
, status
);
2480 if (actualNumberString
!= expectedNumberString
) {
2481 UnicodeString msg
= "FAIL: parsing";
2482 msg
.append(asciiUSNumberString
);
2484 msg
.append(" lenient parse failed for ");
2485 msg
.append(spelledNumberString
);
2486 msg
.append(", expected ");
2487 msg
.append(expectedNumberString
);
2488 msg
.append(", but got ");
2489 msg
.append(actualNumberString
);
2504 IntlTestRBNF::TestRBNFDisabled() {
2505 errln("*** RBNF currently disabled on this platform ***\n");
2511 #endif /* #if !UCONFIG_NO_FORMATTING */