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
);
79 TESTCASE(0, TestRBNFDisabled
);
89 void IntlTestRBNF::TestHebrewFraction() {
91 // this is the expected output for 123.45, with no '<' in it.
93 0x05de, 0x05d0, 0x05d4, 0x0020,
94 0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
95 0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
96 0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
97 0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020,
98 0x05d7, 0x05de, 0x05e9, 0x0000,
101 0x05DE, 0x05D0, 0x05D4, 0x0020,
102 0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020,
103 0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020,
104 0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020,
105 0x05D0, 0x05E4, 0x05E1, 0x0020,
106 0x05D0, 0x05E4, 0x05E1, 0x0020,
107 0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020,
108 0x05D7, 0x05DE, 0x05E9, 0x0000,
110 UErrorCode status
= U_ZERO_ERROR
;
111 RuleBasedNumberFormat
* formatter
= new RuleBasedNumberFormat(URBNF_SPELLOUT
, "he_IL", status
);
112 if (status
== U_MISSING_RESOURCE_ERROR
|| status
== U_FILE_ACCESS_ERROR
) {
113 errcheckln(status
, "Failed in constructing RuleBasedNumberFormat - %s", u_errorName(status
));
117 UnicodeString result
;
118 Formattable parseResult
;
121 UnicodeString
expected(text1
);
122 formatter
->format(123.45, result
);
123 if (result
!= expected
) {
124 errln((UnicodeString
)"expected '" + TestUtility::hex(expected
) + "'\nbut got: '" + TestUtility::hex(result
) + "'");
126 // formatter->parse(result, parseResult, pp);
127 // if (parseResult.getDouble() != 123.45) {
128 // errln("expected 123.45 but got: %g", parseResult.getDouble());
133 UnicodeString
expected(text2
);
135 formatter
->format(123.0045, result
);
136 if (result
!= expected
) {
137 errln((UnicodeString
)"expected '" + TestUtility::hex(expected
) + "'\nbut got: '" + TestUtility::hex(result
) + "'");
140 // formatter->parse(result, parseResult, pp);
141 // if (parseResult.getDouble() != 123.0045) {
142 // errln("expected 123.0045 but got: %g", parseResult.getDouble());
150 IntlTestRBNF::TestAPI() {
151 // This test goes through the APIs that were not tested before.
152 // These tests are too small to have separate test classes/functions
154 UErrorCode status
= U_ZERO_ERROR
;
155 RuleBasedNumberFormat
* formatter
156 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getUS(), status
);
157 if (status
== U_MISSING_RESOURCE_ERROR
|| status
== U_FILE_ACCESS_ERROR
) {
158 dataerrln("Unable to create formatter. - %s", u_errorName(status
));
163 logln("RBNF API test starting");
166 logln("Testing Clone");
167 RuleBasedNumberFormat
* rbnfClone
= (RuleBasedNumberFormat
*)formatter
->clone();
168 if(rbnfClone
!= NULL
) {
169 if(!(*rbnfClone
== *formatter
)) {
170 errln("Clone should be semantically equivalent to the original!");
174 errln("Cloning failed!");
180 logln("Testing assignment operator");
181 RuleBasedNumberFormat
assignResult(URBNF_SPELLOUT
, Locale("es", "ES", ""), status
);
182 assignResult
= *formatter
;
183 if(!(assignResult
== *formatter
)) {
184 errln("Assignment result should be semantically equivalent to the original!");
188 // test rule constructor
190 logln("Testing rule constructor");
191 LocalUResourceBundlePointer
en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING
"rbnf", "en", &status
));
192 if(U_FAILURE(status
)) {
193 errln("Unable to access resource bundle with data!");
197 LocalUResourceBundlePointer
rbnfRules(ures_getByKey(en
.getAlias(), "RBNFRules", NULL
, &status
));
198 LocalUResourceBundlePointer
ruleSets(ures_getByKey(rbnfRules
.getAlias(), "SpelloutRules", NULL
, &status
));
200 while (ures_hasNext(ruleSets
.getAlias())) {
201 const UChar
* currentString
= ures_getNextString(ruleSets
.getAlias(), &len
, NULL
, &status
);
203 desc
.append(currentString
);
206 const UChar
*spelloutRules
= desc
.getTerminatedBuffer();
208 if(U_FAILURE(status
) || ruleLen
== 0 || spelloutRules
== NULL
) {
209 errln("Unable to access the rules string!");
212 RuleBasedNumberFormat
ruleCtorResult(spelloutRules
, Locale::getUS(), perror
, status
);
213 if(!(ruleCtorResult
== *formatter
)) {
214 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
217 // Jitterbug 4452, for coverage
218 RuleBasedNumberFormat
nf(spelloutRules
, (UnicodeString
)"", Locale::getUS(), perror
, status
);
219 if(!(nf
== *formatter
)) {
220 errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
228 logln("Testing getRules function");
229 UnicodeString rules
= formatter
->getRules();
231 RuleBasedNumberFormat
fromRulesResult(rules
, Locale::getUS(), perror
, status
);
233 if(!(fromRulesResult
== *formatter
)) {
234 errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
240 logln("Testing copy constructor");
241 RuleBasedNumberFormat
copyCtorResult(*formatter
);
242 if(!(copyCtorResult
== *formatter
)) {
243 errln("Copy constructor result result should be semantically equivalent to the original!");
247 #if !UCONFIG_NO_COLLATION
249 #define NUMERIC_STRINGS_NOT_PARSEABLE 1 // ticket/8224
251 // test ruleset names
253 logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule set names");
254 int32_t noOfRuleSetNames
= formatter
->getNumberOfRuleSetNames();
255 if(noOfRuleSetNames
== 0) {
256 errln("Number of rule set names should be more than zero");
258 UnicodeString ruleSetName
;
260 int32_t intFormatNum
= 34567;
261 double doubleFormatNum
= 893411.234;
262 logln("number of rule set names is %i", noOfRuleSetNames
);
263 for(i
= 0; i
< noOfRuleSetNames
; i
++) {
264 FieldPosition pos1
, pos2
;
265 UnicodeString intFormatResult
, doubleFormatResult
;
266 Formattable intParseResult
, doubleParseResult
;
267 #if NUMERIC_STRINGS_NOT_PARSEABLE
268 UBool parseDoubleNonLenientOK
= TRUE
;
269 UBool parseDoubleLenientOK
= TRUE
;
272 ruleSetName
= formatter
->getRuleSetName(i
);
273 log("Rule set name %i is ", i
);
275 logln(". Format results are: ");
276 intFormatResult
= formatter
->format(intFormatNum
, ruleSetName
, intFormatResult
, pos1
, status
);
277 doubleFormatResult
= formatter
->format(doubleFormatNum
, ruleSetName
, doubleFormatResult
, pos2
, status
);
278 if(U_FAILURE(status
)) {
279 errln("Format using a rule set failed");
282 logln(intFormatResult
);
283 logln(doubleFormatResult
);
285 #if NUMERIC_STRINGS_NOT_PARSEABLE
286 // "spellout-numbering-year" ruleSet produces (above) a numeric string using:
287 // "x.x: =#,###0.#=;"
288 // which will not parse (below) - we believe this is CORRECT behavior, as found in ICU 4.0 (see ticket/8224).
289 // Note this numeric string "89,3411.2" will not even parse with Lenient = TRUE because
290 // the NumberFormat (used as last-resort) in NFSubstitution::doParse fails.
291 UnicodeString numberingYear
= UNICODE_STRING_SIMPLE("spellout-numbering-year");
293 // "spellout-ordinal" and "spellout-ordinal-verbose" ruleSets produce (above) a numeric string using:
294 // "x.x: =#,##0.#=;" -> "893,411.2"
295 // which will not parse (below) with Lenient = FALSE, but does parse with Lenient = TRUE because
296 // NFSubstitution::doParse will succeed when using NumberFormat as last-resort.
297 UnicodeString ordinal
= UNICODE_STRING_SIMPLE("spellout-ordinal");
299 // RuleSets other than spellout-numbering-year and spellout-ordinalXXX produce fully spelled out text above
300 // which is fully parseable.
301 parseDoubleLenientOK
= ( ruleSetName
.indexOf(numberingYear
) == -1 );
302 parseDoubleNonLenientOK
= ( ruleSetName
.indexOf(numberingYear
) == -1 && ruleSetName
.indexOf(ordinal
) == -1 );
305 formatter
->setLenient(TRUE
);
306 formatter
->parse(intFormatResult
, intParseResult
, status
);
307 formatter
->parse(doubleFormatResult
, doubleParseResult
, status
);
309 logln("Parse results for lenient = TRUE, %i, %f", intParseResult
.getLong(), doubleParseResult
.getDouble());
311 #if NUMERIC_STRINGS_NOT_PARSEABLE
312 if((!parseDoubleLenientOK
) && (status
== U_INVALID_FORMAT_ERROR
)) {
313 status
= U_USING_FALLBACK_WARNING
;
314 logln("Clearing expected U_INVALID_FORMAT_ERROR during parsing");
318 formatter
->setLenient(FALSE
);
319 formatter
->parse(intFormatResult
, intParseResult
, status
);
320 formatter
->parse(doubleFormatResult
, doubleParseResult
, status
);
322 logln("Parse results for lenient = FALSE, %i, %f", intParseResult
.getLong(), doubleParseResult
.getDouble());
324 #if NUMERIC_STRINGS_NOT_PARSEABLE
325 if((!parseDoubleNonLenientOK
) && (status
== U_INVALID_FORMAT_ERROR
)) {
326 status
= U_USING_FALLBACK_WARNING
;
327 logln("Clearing expected U_INVALID_FORMAT_ERROR during parsing");
331 if(U_FAILURE(status
)) {
332 errln("Error during parsing");
335 intFormatResult
= formatter
->format(intFormatNum
, "BLABLA", intFormatResult
, pos1
, status
);
336 if(U_SUCCESS(status
)) {
337 errln("Using invalid rule set name should have failed");
340 status
= U_ZERO_ERROR
;
341 doubleFormatResult
= formatter
->format(doubleFormatNum
, "TRUC", doubleFormatResult
, pos2
, status
);
342 if(U_SUCCESS(status
)) {
343 errln("Using invalid rule set name should have failed");
346 status
= U_ZERO_ERROR
;
348 status
= U_ZERO_ERROR
;
353 UnicodeString
expected("four point five","");
354 logln("Testing format(double)");
355 UnicodeString result
;
356 formatter
->format(4.5,result
);
357 if(result
!= expected
) {
358 errln("Formatted 4.5, expected " + expected
+ " got " + result
);
360 logln("Formatted 4.5, expected " + expected
+ " got " + result
);
364 formatter
->format((int32_t)4,result
);
365 if(result
!= expected
) {
366 errln("Formatted 4, expected " + expected
+ " got " + result
);
368 logln("Formatted 4, expected " + expected
+ " got " + result
);
373 formatter
->format((int64_t)4, result
, pos
, status
= U_ZERO_ERROR
);
374 if(result
!= expected
) {
375 errln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
377 logln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
380 //Jitterbug 4452, for coverage
383 formatter
->format((int64_t)4, formatter
->getRuleSetName(0), result
, pos2
, status
= U_ZERO_ERROR
);
384 if(result
!= expected
) {
385 errln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
387 logln("Formatted 4 int64_t, expected " + expected
+ " got " + result
);
391 logln("Cleaning up");
396 * Perform a simple spot check on the parsing going into an infinite loop for alternate rules.
398 void IntlTestRBNF::TestMultiplePluralRules() {
399 // This is trying to model the feminine form, but don't worry about the details too much.
400 // We're trying to test the plural rules where there are different prefixes.
401 UnicodeString
rules("%spellout-cardinal-feminine-genitive:"
405 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
406 "%spellout-cardinal-feminine:"
407 "x.x: [<< $(cardinal,one{singleton}other{plurality})$ ]>%%fractions>;"
411 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
413 "10: <%spellout-cardinal-feminine< $(cardinal,one{oneth}other{tenth})$;"
414 "100: <%spellout-cardinal-feminine< $(cardinal,one{1hundredth}other{hundredth})$;");
415 UErrorCode status
= U_ZERO_ERROR
;
417 RuleBasedNumberFormat
formatter(rules
, Locale("ru"), pError
, status
);
419 UnicodeString resultStr
;
422 if (U_FAILURE(status
)) {
423 dataerrln("Unable to create formatter - %s", u_errorName(status
));
427 formatter
.parse(formatter
.format(1000.0, resultStr
, pos
, status
), result
, status
);
428 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("one thousand")) {
429 errln("RuleBasedNumberFormat did not return the correct value. Got: %d", result
.getLong());
433 formatter
.parse(formatter
.format(1000.0, UnicodeString("%spellout-cardinal-feminine-genitive"), resultStr
, pos
, status
), result
, status
);
434 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("ono thousand")) {
435 errln("RuleBasedNumberFormat(cardinal-feminine-genitive) did not return the correct value. Got: %d", result
.getLong());
439 formatter
.parse(formatter
.format(1000.0, UnicodeString("%spellout-cardinal-feminine"), resultStr
, pos
, status
), result
, status
);
440 if (1000 != result
.getLong() || resultStr
!= UNICODE_STRING_SIMPLE("one thousand")) {
441 errln("RuleBasedNumberFormat(spellout-cardinal-feminine) did not return the correct value. Got: %d", result
.getLong());
444 static const char* const testData
[][2] = {
448 { "0.1", "one oneth" },
449 { "0.2", "two tenth" },
450 { "1.1", "one singleton one oneth" },
451 { "1.2", "one singleton two tenth" },
452 { "2.1", "two plurality one oneth" },
453 { "2.2", "two plurality two tenth" },
454 { "0.01", "one 1hundredth" },
455 { "0.02", "two hundredth" },
458 doTest(&formatter
, testData
, TRUE
);
461 void IntlTestRBNF::TestFractionalRuleSet()
463 UnicodeString
fracRules(
465 // this rule formats the number if it's 1 or more. It formats
466 // the integral part using a DecimalFormat ("#,##0" puts
467 // thousands separators in the right places) and the fractional
468 // part using %%frac. If there is no fractional part, it
469 // just shows the integral part.
470 " x.0: <#,##0<[ >%%frac>];\n"
471 // this rule formats the number if it's between 0 and 1. It
472 // shows only the fractional part (0.5 shows up as "1/2," not
475 // the fraction rule set. This works the same way as the one in the
476 // preceding example: We multiply the fractional part of the number
477 // being formatted by each rule's base value and use the rule that
478 // produces the result closest to 0 (or the first rule that produces 0).
479 // Since we only provide rules for the numbers from 2 to 10, we know
480 // we'll get a fraction with a denominator between 2 and 10.
481 // "<0<" causes the numerator of the fraction to be formatted
495 int len
= fracRules
.length();
497 for (int i
= 0; i
< len
; ++i
) {
498 UChar ch
= fracRules
.charAt(i
);
500 change
= 2; // change ok
501 } else if (ch
== ':') {
502 change
= 1; // change, but once we hit a non-space char, don't change
503 } else if (ch
== ' ') {
505 fracRules
.setCharAt(i
, (UChar
)0x200e);
514 UErrorCode status
= U_ZERO_ERROR
;
516 RuleBasedNumberFormat
formatter(fracRules
, Locale::getEnglish(), perror
, status
);
517 if (U_FAILURE(status
)) {
518 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
520 static const char* const testData
[][2] = {
533 { "3.125", "3 1/8" },
534 { "4.1428", "4 1/7" },
535 { "5.1667", "5 1/6" },
538 { "8.333", "8 1/3" },
543 { "1.2856", "1 2/7" },
546 doTest(&formatter
, testData
, FALSE
); // exact values aren't parsable from fractions
551 #define LLAssert(a) \
552 if (!(a)) errln("FAIL: " #a)
554 void IntlTestRBNF::TestLLongConstructors()
556 logln("Testing constructors");
558 // constant (shouldn't really be public)
559 LLAssert(llong(llong::kD32
).asDouble() == llong::kD32
);
561 // internal constructor (shouldn't really be public)
562 LLAssert(llong(0, 1).asDouble() == 1);
563 LLAssert(llong(1, 0).asDouble() == llong::kD32
);
564 LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
566 // public empty constructor
567 LLAssert(llong().asDouble() == 0);
569 // public int32_t constructor
570 LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
571 LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
572 LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
573 LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
574 LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
575 LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
577 // public int16_t constructor
578 LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
579 LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
580 LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
581 LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
582 LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
583 LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
585 // public int8_t constructor
586 LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
587 LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
588 LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
589 LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
590 LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
591 LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
593 // public uint16_t constructor
594 LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
595 LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
596 LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
597 LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
598 LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
599 LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
601 // public uint32_t constructor
602 LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
603 LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
604 LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
605 LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
606 LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
607 LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
609 // public double constructor
610 LLAssert(llong((double)0).asDouble() == (double)0);
611 LLAssert(llong((double)1).asDouble() == (double)1);
612 LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
613 LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
614 LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
616 // can't access uprv_maxmantissa, so fake it
617 double maxmantissa
= (llong((int32_t)1) << 40).asDouble();
618 LLAssert(llong(maxmantissa
).asDouble() == maxmantissa
);
619 LLAssert(llong(-maxmantissa
).asDouble() == -maxmantissa
);
622 LLAssert(llong(llong(0, 1)).asDouble() == 1);
623 LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32
);
624 LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
626 // asInt - test unsigned to signed narrowing conversion
627 LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
628 LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
630 // asUInt - test signed to unsigned narrowing conversion
631 LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
632 LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
634 // asDouble already tested
638 void IntlTestRBNF::TestLLongSimpleOperators()
640 logln("Testing simple operators");
643 LLAssert(llong() == llong(0, 0));
644 LLAssert(llong(1,0) == llong(1, 0));
645 LLAssert(llong(0,1) == llong(0, 1));
648 LLAssert(llong(1,0) != llong(1,1));
649 LLAssert(llong(0,1) != llong(1,1));
650 LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
653 LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
656 LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
659 LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
660 LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
663 LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
664 LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
667 LLAssert(llong(1, 1) > llong(1, 0));
668 LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
669 LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
670 LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
671 LLAssert(llong(1, 0) > llong(0, 0xffffffff));
672 LLAssert(llong(0, 0) > llong(0x80000000, 1));
675 LLAssert(llong(1, 0) < llong(1, 1));
676 LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
677 LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
678 LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
679 LLAssert(llong(0, 0xffffffff) < llong(1, 0));
680 LLAssert(llong(0x80000000, 1) < llong(0, 0));
683 LLAssert(llong(1, 1) >= llong(1, 0));
684 LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
685 LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
686 LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
687 LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
688 LLAssert(llong(0, 0) >= llong(0x80000000, 1));
689 LLAssert(llong() >= llong(0, 0));
690 LLAssert(llong(1,0) >= llong(1, 0));
691 LLAssert(llong(0,1) >= llong(0, 1));
694 LLAssert(llong(1, 0) <= llong(1, 1));
695 LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
696 LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
697 LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
698 LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
699 LLAssert(llong(0x80000000, 1) <= llong(0, 0));
700 LLAssert(llong() <= llong(0, 0));
701 LLAssert(llong(1,0) <= llong(1, 0));
702 LLAssert(llong(0,1) <= llong(0, 1));
705 LLAssert(llong() == (int32_t)0);
706 LLAssert(llong(0,1) == (int32_t)1);
709 LLAssert(llong(1,0) != (int32_t)0);
710 LLAssert(llong(0,1) != (int32_t)2);
711 LLAssert(llong(0,0xffffffff) != (int32_t)-1);
713 llong
negOne(0xffffffff, 0xffffffff);
716 LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
717 LLAssert(negOne
> (int32_t)-2);
718 LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
719 LLAssert(llong(0, 0) > (int32_t)-1);
722 LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
723 LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
726 LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
727 LLAssert(negOne
>= (int32_t)-2);
728 LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
729 LLAssert(llong(0, 0) >= (int32_t)-1);
730 LLAssert(llong() >= (int32_t)0);
731 LLAssert(llong(0,1) >= (int32_t)1);
734 LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
735 LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
736 LLAssert(llong() <= (int32_t)0);
737 LLAssert(llong(0,1) <= (int32_t)1);
740 LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
743 LLAssert((llong(1, 1) <<= 0) == llong(1, 1));
744 LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
745 LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
746 LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
747 LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
748 LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
751 LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
753 // operator >>= (sign extended)
754 LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
755 LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
756 LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
757 LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
758 LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
759 LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
761 // operator >> sign extended)
762 LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
764 // ushr (right shift without sign extension)
765 LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
766 LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
767 LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
768 LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
769 LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
770 LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
773 LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
776 LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
779 LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
782 LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
785 LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
788 LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
791 LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
794 LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
797 LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
800 LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
802 // operator&=(uint32)
803 LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
805 // operator|=(uint32)
806 LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
808 // operator^=(uint32)
809 LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
812 LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
815 LLAssert(llong(0,0xffffffff) == --llong(1, 0));
819 llong
n(0, 0xffffffff);
820 LLAssert(llong(0, 0xffffffff) == n
++);
821 LLAssert(llong(1, 0) == n
);
827 LLAssert(llong(1, 0) == n
--);
828 LLAssert(llong(0, 0xffffffff) == n
);
832 LLAssert(llong(0, 0) == -llong(0, 0));
833 LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
834 LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
835 LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
836 LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
841 LLAssert((n
-= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
842 LLAssert(n
== llong(0xffffffff, 0xffffffff));
845 LLAssert((n
-= llong(0, 1)) == llong(0, 0xffffffff));
846 LLAssert(n
== llong(0, 0xffffffff));
852 LLAssert((n
- llong(0, 1)) == llong(0xffffffff, 0xffffffff));
853 LLAssert(n
== llong(0, 0));
856 LLAssert((n
- llong(0, 1)) == llong(0, 0xffffffff));
857 LLAssert(n
== llong(1, 0));
862 llong
n(0xffffffff, 0xffffffff);
863 LLAssert((n
+= llong(0, 1)) == llong(0, 0));
864 LLAssert(n
== llong(0, 0));
866 n
= llong(0, 0xffffffff);
867 LLAssert((n
+= llong(0, 1)) == llong(1, 0));
868 LLAssert(n
== llong(1, 0));
873 llong
n(0xffffffff, 0xffffffff);
874 LLAssert((n
+ llong(0, 1)) == llong(0, 0));
875 LLAssert(n
== llong(0xffffffff, 0xffffffff));
877 n
= llong(0, 0xffffffff);
878 LLAssert((n
+ llong(0, 1)) == llong(1, 0));
879 LLAssert(n
== llong(0, 0xffffffff));
884 void IntlTestRBNF::TestLLong()
886 logln("Starting TestLLong");
888 TestLLongConstructors();
890 TestLLongSimpleOperators();
892 logln("Testing operator*=, operator*");
894 // operator*=, operator*
895 // small and large values, positive, &NEGative, zero
896 // also test commutivity
899 const llong
ONE(0, 1);
900 const llong
NEG_ONE((int32_t)-1);
901 const llong
THREE(0, 3);
902 const llong
NEG_THREE((int32_t)-3);
903 const llong
TWO_TO_16(0, 0x10000);
904 const llong NEG_TWO_TO_16
= -TWO_TO_16
;
905 const llong
TWO_TO_32(1, 0);
906 const llong NEG_TWO_TO_32
= -TWO_TO_32
;
908 const llong
NINE(0, 9);
909 const llong NEG_NINE
= -NINE
;
911 const llong
TWO_TO_16X3(0, 0x00030000);
912 const llong NEG_TWO_TO_16X3
= -TWO_TO_16X3
;
914 const llong
TWO_TO_32X3(3, 0);
915 const llong NEG_TWO_TO_32X3
= -TWO_TO_32X3
;
917 const llong
TWO_TO_48(0x10000, 0);
918 const llong NEG_TWO_TO_48
= -TWO_TO_48
;
920 const int32_t VALUE_WIDTH
= 9;
921 const llong
* values
[VALUE_WIDTH
] = {
922 &ZERO
, &ONE
, &NEG_ONE
, &THREE
, &NEG_THREE
, &TWO_TO_16
, &NEG_TWO_TO_16
, &TWO_TO_32
, &NEG_TWO_TO_32
925 const llong
* answers
[VALUE_WIDTH
*VALUE_WIDTH
] = {
926 &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
, &ZERO
,
927 &ZERO
, &ONE
, &NEG_ONE
, &THREE
, &NEG_THREE
, &TWO_TO_16
, &NEG_TWO_TO_16
, &TWO_TO_32
, &NEG_TWO_TO_32
,
928 &ZERO
, &NEG_ONE
, &ONE
, &NEG_THREE
, &THREE
, &NEG_TWO_TO_16
, &TWO_TO_16
, &NEG_TWO_TO_32
, &TWO_TO_32
,
929 &ZERO
, &THREE
, &NEG_THREE
, &NINE
, &NEG_NINE
, &TWO_TO_16X3
, &NEG_TWO_TO_16X3
, &TWO_TO_32X3
, &NEG_TWO_TO_32X3
,
930 &ZERO
, &NEG_THREE
, &THREE
, &NEG_NINE
, &NINE
, &NEG_TWO_TO_16X3
, &TWO_TO_16X3
, &NEG_TWO_TO_32X3
, &TWO_TO_32X3
,
931 &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
,
932 &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
,
933 &ZERO
, &TWO_TO_32
, &NEG_TWO_TO_32
, &TWO_TO_32X3
, &NEG_TWO_TO_32X3
, &TWO_TO_48
, &NEG_TWO_TO_48
, &ZERO
, &ZERO
,
934 &ZERO
, &NEG_TWO_TO_32
, &TWO_TO_32
, &NEG_TWO_TO_32X3
, &TWO_TO_32X3
, &NEG_TWO_TO_48
, &TWO_TO_48
, &ZERO
, &ZERO
937 for (int i
= 0; i
< VALUE_WIDTH
; ++i
) {
938 for (int j
= 0; j
< VALUE_WIDTH
; ++j
) {
939 llong lhs
= *values
[i
];
940 llong rhs
= *values
[j
];
941 llong ans
= *answers
[i
*VALUE_WIDTH
+ j
];
945 LLAssert((n
*= rhs
) == ans
);
949 LLAssert((n
* rhs
) == ans
);
955 logln("Testing operator/=, operator/");
956 // operator/=, operator/
957 // test num = 0, div = 0, pos/neg, > 2^32, div > num
960 const llong
ONE(0, 1);
961 const llong NEG_ONE
= -ONE
;
962 const llong
MAX(0x7fffffff, 0xffffffff);
963 const llong
MIN(0x80000000, 0);
964 const llong
TWO(0, 2);
965 const llong NEG_TWO
= -TWO
;
966 const llong
FIVE(0, 5);
967 const llong NEG_FIVE
= -FIVE
;
968 const llong
TWO_TO_32(1, 0);
969 const llong NEG_TWO_TO_32
= -TWO_TO_32
;
970 const llong TWO_TO_32d5
= llong(TWO_TO_32
.asDouble()/5.0);
971 const llong NEG_TWO_TO_32d5
= -TWO_TO_32d5
;
972 const llong TWO_TO_32X5
= TWO_TO_32
* FIVE
;
973 const llong NEG_TWO_TO_32X5
= -TWO_TO_32X5
;
975 const llong
* tuples
[] = { // lhs, rhs, ans
978 &NEG_ONE
, &ZERO
, &MIN
,
980 &ONE
, &NEG_ONE
, &NEG_ONE
,
981 &NEG_ONE
, &ONE
, &NEG_ONE
,
982 &NEG_ONE
, &NEG_ONE
, &ONE
,
984 &FIVE
, &NEG_TWO
, &NEG_TWO
,
985 &NEG_FIVE
, &TWO
, &NEG_TWO
,
986 &NEG_FIVE
, &NEG_TWO
, &TWO
,
988 &TWO
, &NEG_FIVE
, &ZERO
,
989 &NEG_TWO
, &FIVE
, &ZERO
,
990 &NEG_TWO
, &NEG_FIVE
, &ZERO
,
991 &TWO_TO_32
, &TWO_TO_32
, &ONE
,
992 &TWO_TO_32
, &NEG_TWO_TO_32
, &NEG_ONE
,
993 &NEG_TWO_TO_32
, &TWO_TO_32
, &NEG_ONE
,
994 &NEG_TWO_TO_32
, &NEG_TWO_TO_32
, &ONE
,
995 &TWO_TO_32
, &FIVE
, &TWO_TO_32d5
,
996 &TWO_TO_32
, &NEG_FIVE
, &NEG_TWO_TO_32d5
,
997 &NEG_TWO_TO_32
, &FIVE
, &NEG_TWO_TO_32d5
,
998 &NEG_TWO_TO_32
, &NEG_FIVE
, &TWO_TO_32d5
,
999 &TWO_TO_32X5
, &FIVE
, &TWO_TO_32
,
1000 &TWO_TO_32X5
, &NEG_FIVE
, &NEG_TWO_TO_32
,
1001 &NEG_TWO_TO_32X5
, &FIVE
, &NEG_TWO_TO_32
,
1002 &NEG_TWO_TO_32X5
, &NEG_FIVE
, &TWO_TO_32
,
1003 &TWO_TO_32X5
, &TWO_TO_32
, &FIVE
,
1004 &TWO_TO_32X5
, &NEG_TWO_TO_32
, &NEG_FIVE
,
1005 &NEG_TWO_TO_32X5
, &NEG_TWO_TO_32
, &FIVE
,
1006 &NEG_TWO_TO_32X5
, &TWO_TO_32
, &NEG_FIVE
1008 const int TUPLE_WIDTH
= 3;
1009 const int TUPLE_COUNT
= UPRV_LENGTHOF(tuples
)/TUPLE_WIDTH
;
1010 for (int i
= 0; i
< TUPLE_COUNT
; ++i
) {
1011 const llong lhs
= *tuples
[i
*TUPLE_WIDTH
+0];
1012 const llong rhs
= *tuples
[i
*TUPLE_WIDTH
+1];
1013 const llong ans
= *tuples
[i
*TUPLE_WIDTH
+2];
1016 if (!((n
/= rhs
) == ans
)) {
1017 errln("fail: (n /= rhs) == ans");
1022 LLAssert((n
/ rhs
) == ans
);
1027 logln("Testing operator%%=, operator%%");
1028 //operator%=, operator%
1031 const llong
ONE(0, 1);
1032 const llong
TWO(0, 2);
1033 const llong
THREE(0,3);
1034 const llong
FOUR(0, 4);
1035 const llong
FIVE(0, 5);
1036 const llong
SIX(0, 6);
1038 const llong NEG_ONE
= -ONE
;
1039 const llong NEG_TWO
= -TWO
;
1040 const llong NEG_THREE
= -THREE
;
1041 const llong NEG_FOUR
= -FOUR
;
1042 const llong NEG_FIVE
= -FIVE
;
1043 const llong NEG_SIX
= -SIX
;
1045 const llong
NINETY_NINE(0, 99);
1046 const llong
HUNDRED(0, 100);
1047 const llong
HUNDRED_ONE(0, 101);
1049 const llong
BIG(0x12345678, 0x9abcdef0);
1050 const llong
BIG_FIVE(BIG
* FIVE
);
1051 const llong BIG_FIVEm1
= BIG_FIVE
- ONE
;
1052 const llong BIG_FIVEp1
= BIG_FIVE
+ ONE
;
1054 const llong
* tuples
[] = {
1055 &ZERO
, &FIVE
, &ZERO
,
1058 &THREE
, &FIVE
, &THREE
,
1059 &FOUR
, &FIVE
, &FOUR
,
1060 &FIVE
, &FIVE
, &ZERO
,
1062 &ZERO
, &NEG_FIVE
, &ZERO
,
1063 &ONE
, &NEG_FIVE
, &ONE
,
1064 &TWO
, &NEG_FIVE
, &TWO
,
1065 &THREE
, &NEG_FIVE
, &THREE
,
1066 &FOUR
, &NEG_FIVE
, &FOUR
,
1067 &FIVE
, &NEG_FIVE
, &ZERO
,
1068 &SIX
, &NEG_FIVE
, &ONE
,
1069 &NEG_ONE
, &FIVE
, &NEG_ONE
,
1070 &NEG_TWO
, &FIVE
, &NEG_TWO
,
1071 &NEG_THREE
, &FIVE
, &NEG_THREE
,
1072 &NEG_FOUR
, &FIVE
, &NEG_FOUR
,
1073 &NEG_FIVE
, &FIVE
, &ZERO
,
1074 &NEG_SIX
, &FIVE
, &NEG_ONE
,
1075 &NEG_ONE
, &NEG_FIVE
, &NEG_ONE
,
1076 &NEG_TWO
, &NEG_FIVE
, &NEG_TWO
,
1077 &NEG_THREE
, &NEG_FIVE
, &NEG_THREE
,
1078 &NEG_FOUR
, &NEG_FIVE
, &NEG_FOUR
,
1079 &NEG_FIVE
, &NEG_FIVE
, &ZERO
,
1080 &NEG_SIX
, &NEG_FIVE
, &NEG_ONE
,
1081 &NINETY_NINE
, &FIVE
, &FOUR
,
1082 &HUNDRED
, &FIVE
, &ZERO
,
1083 &HUNDRED_ONE
, &FIVE
, &ONE
,
1084 &BIG_FIVEm1
, &FIVE
, &FOUR
,
1085 &BIG_FIVE
, &FIVE
, &ZERO
,
1086 &BIG_FIVEp1
, &FIVE
, &ONE
1088 const int TUPLE_WIDTH
= 3;
1089 const int TUPLE_COUNT
= UPRV_LENGTHOF(tuples
)/TUPLE_WIDTH
;
1090 for (int i
= 0; i
< TUPLE_COUNT
; ++i
) {
1091 const llong lhs
= *tuples
[i
*TUPLE_WIDTH
+0];
1092 const llong rhs
= *tuples
[i
*TUPLE_WIDTH
+1];
1093 const llong ans
= *tuples
[i
*TUPLE_WIDTH
+2];
1096 if (!((n
%= rhs
) == ans
)) {
1097 errln("fail: (n %= rhs) == ans");
1102 LLAssert((n
% rhs
) == ans
);
1107 logln("Testing pow");
1109 LLAssert(llong(0, 0).pow(0) == llong(0, 0));
1110 LLAssert(llong(0, 0).pow(2) == llong(0, 0));
1111 LLAssert(llong(0, 2).pow(0) == llong(0, 1));
1112 LLAssert(llong(0, 2).pow(2) == llong(0, 4));
1113 LLAssert(llong(0, 2).pow(32) == llong(1, 0));
1114 LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
1118 const llong
n(0xffffffff,0xffffffff);
1119 LLAssert(n
.abs() == llong(0, 1));
1123 logln("Testing atoll");
1125 const char empty
[] = "";
1126 const char zero
[] = "0";
1127 const char neg_one
[] = "-1";
1128 const char neg_12345
[] = "-12345";
1129 const char big1
[] = "123456789abcdef0";
1130 const char big2
[] = "fFfFfFfFfFfFfFfF";
1131 LLAssert(llong::atoll(empty
) == llong(0, 0));
1132 LLAssert(llong::atoll(zero
) == llong(0, 0));
1133 LLAssert(llong::atoll(neg_one
) == llong(0xffffffff, 0xffffffff));
1134 LLAssert(llong::atoll(neg_12345
) == -llong(0, 12345));
1135 LLAssert(llong::atoll(big1
, 16) == llong(0x12345678, 0x9abcdef0));
1136 LLAssert(llong::atoll(big2
, 16) == llong(0xffffffff, 0xffffffff));
1140 const UChar uempty
[] = { 0 };
1141 const UChar uzero
[] = { 0x30, 0 };
1142 const UChar uneg_one
[] = { 0x2d, 0x31, 0 };
1143 const UChar uneg_12345
[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1144 const UChar ubig1
[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1145 const UChar ubig2
[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1146 LLAssert(llong::utoll(uempty
) == llong(0, 0));
1147 LLAssert(llong::utoll(uzero
) == llong(0, 0));
1148 LLAssert(llong::utoll(uneg_one
) == llong(0xffffffff, 0xffffffff));
1149 LLAssert(llong::utoll(uneg_12345
) == -llong(0, 12345));
1150 LLAssert(llong::utoll(ubig1
, 16) == llong(0x12345678, 0x9abcdef0));
1151 LLAssert(llong::utoll(ubig2
, 16) == llong(0xffffffff, 0xffffffff));
1154 logln("Testing lltoa");
1157 char buf
[64]; // ascii
1158 LLAssert((llong(0, 0).lltoa(buf
, (uint32_t)sizeof(buf
)) == 1) && (strcmp(buf
, zero
) == 0));
1159 LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf
, (uint32_t)sizeof(buf
)) == 2) && (strcmp(buf
, neg_one
) == 0));
1160 LLAssert(((-llong(0, 12345)).lltoa(buf
, (uint32_t)sizeof(buf
)) == 6) && (strcmp(buf
, neg_12345
) == 0));
1161 LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf
, (uint32_t)sizeof(buf
), 16) == 16) && (strcmp(buf
, big1
) == 0));
1165 logln("Testing u_lltoa");
1169 LLAssert((llong(0, 0).lltou(buf
, (uint32_t)sizeof(buf
)) == 1) && (u_strcmp(buf
, uzero
) == 0));
1170 LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf
, (uint32_t)sizeof(buf
)) == 2) && (u_strcmp(buf
, uneg_one
) == 0));
1171 LLAssert(((-llong(0, 12345)).lltou(buf
, (uint32_t)sizeof(buf
)) == 6) && (u_strcmp(buf
, uneg_12345
) == 0));
1172 LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf
, (uint32_t)sizeof(buf
), 16) == 16) && (u_strcmp(buf
, ubig1
) == 0));
1180 IntlTestRBNF::TestEnglishSpellout()
1182 UErrorCode status
= U_ZERO_ERROR
;
1183 RuleBasedNumberFormat
* formatter
1184 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getUS(), status
);
1185 if (U_FAILURE(status
)) {
1186 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1188 static const char* const testData
[][2] = {
1191 { "15", "fifteen" },
1193 { "23", "twenty-three" },
1194 { "73", "seventy-three" },
1195 { "88", "eighty-eight" },
1196 { "100", "one hundred" },
1197 { "106", "one hundred six" },
1198 { "127", "one hundred twenty-seven" },
1199 { "200", "two hundred" },
1200 { "579", "five hundred seventy-nine" },
1201 { "1,000", "one thousand" },
1202 { "2,000", "two thousand" },
1203 { "3,004", "three thousand four" },
1204 { "4,567", "four thousand five hundred sixty-seven" },
1205 { "15,943", "fifteen thousand nine hundred forty-three" },
1206 { "2,345,678", "two million three hundred forty-five thousand six hundred seventy-eight" },
1207 { "-36", "minus thirty-six" },
1208 { "234.567", "two hundred thirty-four point five six seven" },
1212 doTest(formatter
, testData
, TRUE
);
1214 #if !UCONFIG_NO_COLLATION
1215 formatter
->setLenient(TRUE
);
1216 static const char* lpTestData
[][2] = {
1217 { "fifty-7", "57" },
1218 { " fifty-7", "57" },
1219 { " fifty-7", "57" },
1220 { "2 thousand six HUNDRED fifty-7", "2,657" },
1221 { "fifteen hundred and zero", "1,500" },
1222 { "FOurhundred thiRTY six", "436" },
1225 doLenientParseTest(formatter
, lpTestData
);
1232 IntlTestRBNF::TestOrdinalAbbreviations()
1234 UErrorCode status
= U_ZERO_ERROR
;
1235 RuleBasedNumberFormat
* formatter
1236 = new RuleBasedNumberFormat(URBNF_ORDINAL
, Locale::getUS(), status
);
1238 if (U_FAILURE(status
)) {
1239 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1241 static const char* const testData
[][2] = {
1258 { "12,345", "12,345th" },
1262 doTest(formatter
, testData
, FALSE
);
1268 IntlTestRBNF::TestDurations()
1270 UErrorCode status
= U_ZERO_ERROR
;
1271 RuleBasedNumberFormat
* formatter
1272 = new RuleBasedNumberFormat(URBNF_DURATION
, Locale::getUS(), status
);
1274 if (U_FAILURE(status
)) {
1275 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1277 static const char* const testData
[][2] = {
1278 { "3,600", "1:00:00" }, //move me and I fail
1281 { "24", "24 sec." },
1286 // { "3,600", "1:00:00" },
1287 { "3,740", "1:02:20" },
1288 { "10,293", "2:51:33" },
1292 doTest(formatter
, testData
, TRUE
);
1294 #if !UCONFIG_NO_COLLATION
1295 formatter
->setLenient(TRUE
);
1296 static const char* lpTestData
[][2] = {
1297 { "2-51-33", "10,293" },
1300 doLenientParseTest(formatter
, lpTestData
);
1307 IntlTestRBNF::TestSpanishSpellout()
1309 UErrorCode status
= U_ZERO_ERROR
;
1310 RuleBasedNumberFormat
* formatter
1311 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("es", "ES", ""), status
);
1313 if (U_FAILURE(status
)) {
1314 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1316 static const char* const testData
[][2] = {
1319 { "16", "diecis\\u00e9is" },
1321 { "24", "veinticuatro" },
1322 { "26", "veintis\\u00e9is" },
1323 { "73", "setenta y tres" },
1324 { "88", "ochenta y ocho" },
1326 { "106", "ciento seis" },
1327 { "127", "ciento veintisiete" },
1328 { "200", "doscientos" },
1329 { "579", "quinientos setenta y nueve" },
1331 { "2,000", "dos mil" },
1332 { "3,004", "tres mil cuatro" },
1333 { "4,567", "cuatro mil quinientos sesenta y siete" },
1334 { "15,943", "quince mil novecientos cuarenta y tres" },
1335 { "2,345,678", "dos millones trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1336 { "-36", "menos treinta y seis" },
1337 { "234.567", "doscientos treinta y cuatro coma cinco seis siete" },
1341 doTest(formatter
, testData
, TRUE
);
1347 IntlTestRBNF::TestFrenchSpellout()
1349 UErrorCode status
= U_ZERO_ERROR
;
1350 RuleBasedNumberFormat
* formatter
1351 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getFrance(), status
);
1353 if (U_FAILURE(status
)) {
1354 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1356 static const char* const testData
[][2] = {
1360 { "21", "vingt-et-un" },
1361 { "23", "vingt-trois" },
1362 { "62", "soixante-deux" },
1363 { "70", "soixante-dix" },
1364 { "71", "soixante-et-onze" },
1365 { "73", "soixante-treize" },
1366 { "80", "quatre-vingts" },
1367 { "88", "quatre-vingt-huit" },
1369 { "106", "cent six" },
1370 { "127", "cent vingt-sept" },
1371 { "200", "deux cents" },
1372 { "579", "cinq cent soixante-dix-neuf" },
1373 { "1,000", "mille" },
1374 { "1,123", "mille cent vingt-trois" },
1375 { "1,594", "mille cinq cent quatre-vingt-quatorze" },
1376 { "2,000", "deux mille" },
1377 { "3,004", "trois mille quatre" },
1378 { "4,567", "quatre mille cinq cent soixante-sept" },
1379 { "15,943", "quinze mille neuf cent quarante-trois" },
1380 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent soixante-dix-huit" },
1381 { "-36", "moins trente-six" },
1382 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1386 doTest(formatter
, testData
, TRUE
);
1388 #if !UCONFIG_NO_COLLATION
1389 formatter
->setLenient(TRUE
);
1390 static const char* lpTestData
[][2] = {
1391 { "trente-et-un", "31" },
1392 { "un cent quatre vingt dix huit", "198" },
1395 doLenientParseTest(formatter
, lpTestData
);
1401 static const char* const swissFrenchTestData
[][2] = {
1405 { "21", "vingt-et-un" },
1406 { "23", "vingt-trois" },
1407 { "62", "soixante-deux" },
1408 { "70", "septante" },
1409 { "71", "septante-et-un" },
1410 { "73", "septante-trois" },
1411 { "80", "huitante" },
1412 { "88", "huitante-huit" },
1414 { "106", "cent six" },
1415 { "127", "cent vingt-sept" },
1416 { "200", "deux cents" },
1417 { "579", "cinq cent septante-neuf" },
1418 { "1,000", "mille" },
1419 { "1,123", "mille cent vingt-trois" },
1420 { "1,594", "mille cinq cent nonante-quatre" },
1421 { "2,000", "deux mille" },
1422 { "3,004", "trois mille quatre" },
1423 { "4,567", "quatre mille cinq cent soixante-sept" },
1424 { "15,943", "quinze mille neuf cent quarante-trois" },
1425 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1426 { "-36", "moins trente-six" },
1427 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1432 IntlTestRBNF::TestSwissFrenchSpellout()
1434 UErrorCode status
= U_ZERO_ERROR
;
1435 RuleBasedNumberFormat
* formatter
1436 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("fr", "CH", ""), status
);
1438 if (U_FAILURE(status
)) {
1439 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1441 doTest(formatter
, swissFrenchTestData
, TRUE
);
1446 static const char* const belgianFrenchTestData
[][2] = {
1450 { "21", "vingt-et-un" },
1451 { "23", "vingt-trois" },
1452 { "62", "soixante-deux" },
1453 { "70", "septante" },
1454 { "71", "septante-et-un" },
1455 { "73", "septante-trois" },
1456 { "80", "quatre-vingts" },
1457 { "88", "quatre-vingt huit" },
1458 { "90", "nonante" },
1459 { "91", "nonante-et-un" },
1460 { "95", "nonante-cinq" },
1462 { "106", "cent six" },
1463 { "127", "cent vingt-sept" },
1464 { "200", "deux cents" },
1465 { "579", "cinq cent septante-neuf" },
1466 { "1,000", "mille" },
1467 { "1,123", "mille cent vingt-trois" },
1468 { "1,594", "mille cinq cent nonante-quatre" },
1469 { "2,000", "deux mille" },
1470 { "3,004", "trois mille quatre" },
1471 { "4,567", "quatre mille cinq cent soixante-sept" },
1472 { "15,943", "quinze mille neuf cent quarante-trois" },
1473 { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1474 { "-36", "moins trente-six" },
1475 { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1481 IntlTestRBNF::TestBelgianFrenchSpellout()
1483 UErrorCode status
= U_ZERO_ERROR
;
1484 RuleBasedNumberFormat
* formatter
1485 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("fr", "BE", ""), status
);
1487 if (U_FAILURE(status
)) {
1488 errcheckln(status
, "rbnf status: 0x%x (%s)\n", status
, u_errorName(status
));
1489 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1491 // Belgian french should match Swiss french.
1492 doTest(formatter
, belgianFrenchTestData
, TRUE
);
1498 IntlTestRBNF::TestItalianSpellout()
1500 UErrorCode status
= U_ZERO_ERROR
;
1501 RuleBasedNumberFormat
* formatter
1502 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getItalian(), status
);
1504 if (U_FAILURE(status
)) {
1505 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1507 static const char* const testData
[][2] = {
1509 { "15", "quindici" },
1511 { "23", "venti\\u00ADtr\\u00E9" },
1512 { "73", "settanta\\u00ADtr\\u00E9" },
1513 { "88", "ottant\\u00ADotto" },
1515 { "101", "cento\\u00ADuno" },
1516 { "103", "cento\\u00ADtr\\u00E9" },
1517 { "106", "cento\\u00ADsei" },
1518 { "108", "cent\\u00ADotto" },
1519 { "127", "cento\\u00ADventi\\u00ADsette" },
1520 { "181", "cent\\u00ADottant\\u00ADuno" },
1521 { "200", "due\\u00ADcento" },
1522 { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" },
1523 { "1,000", "mille" },
1524 { "2,000", "due\\u00ADmila" },
1525 { "3,004", "tre\\u00ADmila\\u00ADquattro" },
1526 { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessanta\\u00ADsette" },
1527 { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaranta\\u00ADtr\\u00E9" },
1528 { "-36", "meno trenta\\u00ADsei" },
1529 { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cinque sei sette" },
1533 doTest(formatter
, testData
, TRUE
);
1539 IntlTestRBNF::TestPortugueseSpellout()
1541 UErrorCode status
= U_ZERO_ERROR
;
1542 RuleBasedNumberFormat
* formatter
1543 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("pt","BR",""), status
);
1545 if (U_FAILURE(status
)) {
1546 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1548 static const char* const testData
[][2] = {
1552 { "23", "vinte e tr\\u00EAs" },
1553 { "73", "setenta e tr\\u00EAs" },
1554 { "88", "oitenta e oito" },
1556 { "106", "cento e seis" },
1557 { "108", "cento e oito" },
1558 { "127", "cento e vinte e sete" },
1559 { "181", "cento e oitenta e um" },
1560 { "200", "duzentos" },
1561 { "579", "quinhentos e setenta e nove" },
1563 { "2,000", "dois mil" },
1564 { "3,004", "tr\\u00EAs mil e quatro" },
1565 { "4,567", "quatro mil e quinhentos e sessenta e sete" },
1566 { "15,943", "quinze mil e novecentos e quarenta e tr\\u00EAs" },
1567 { "-36", "menos trinta e seis" },
1568 { "234.567", "duzentos e trinta e quatro v\\u00EDrgula cinco seis sete" },
1572 doTest(formatter
, testData
, TRUE
);
1577 IntlTestRBNF::TestGermanSpellout()
1579 UErrorCode status
= U_ZERO_ERROR
;
1580 RuleBasedNumberFormat
* formatter
1581 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale::getGermany(), status
);
1583 if (U_FAILURE(status
)) {
1584 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1586 static const char* const testData
[][2] = {
1588 { "15", "f\\u00fcnfzehn" },
1589 { "20", "zwanzig" },
1590 { "23", "drei\\u00ADund\\u00ADzwanzig" },
1591 { "73", "drei\\u00ADund\\u00ADsiebzig" },
1592 { "88", "acht\\u00ADund\\u00ADachtzig" },
1593 { "100", "ein\\u00ADhundert" },
1594 { "106", "ein\\u00ADhundert\\u00ADsechs" },
1595 { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" },
1596 { "200", "zwei\\u00ADhundert" },
1597 { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzig" },
1598 { "1,000", "ein\\u00ADtausend" },
1599 { "2,000", "zwei\\u00ADtausend" },
1600 { "3,004", "drei\\u00ADtausend\\u00ADvier" },
1601 { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADsechzig" },
1602 { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\u00ADdrei\\u00ADund\\u00ADvierzig" },
1603 { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00ADund\\u00ADsiebzig" },
1607 doTest(formatter
, testData
, TRUE
);
1609 #if !UCONFIG_NO_COLLATION
1610 formatter
->setLenient(TRUE
);
1611 static const char* lpTestData
[][2] = {
1612 { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1615 doLenientParseTest(formatter
, lpTestData
);
1622 IntlTestRBNF::TestThaiSpellout()
1624 UErrorCode status
= U_ZERO_ERROR
;
1625 RuleBasedNumberFormat
* formatter
1626 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("th"), status
);
1628 if (U_FAILURE(status
)) {
1629 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1631 static const char* const testData
[][2] = {
1632 { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1633 { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1634 { "10", "\\u0e2a\\u0e34\\u0e1a" },
1635 { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1636 { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1637 { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1638 { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1642 doTest(formatter
, testData
, TRUE
);
1648 IntlTestRBNF::TestSwedishSpellout()
1650 UErrorCode status
= U_ZERO_ERROR
;
1651 RuleBasedNumberFormat
* formatter
1652 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("sv"), status
);
1654 if (U_FAILURE(status
)) {
1655 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1657 static const char* testDataDefault
[][2] = {
1658 { "101", "ett\\u00adhundra\\u00adett" },
1659 { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" },
1660 { "1,001", "et\\u00adtusen ett" },
1661 { "1,100", "et\\u00adtusen ett\\u00adhundra" },
1662 { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1663 { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00adfyra" },
1664 { "10,001", "tio\\u00adtusen ett" },
1665 { "11,000", "elva\\u00adtusen" },
1666 { "12,000", "tolv\\u00adtusen" },
1667 { "20,000", "tjugo\\u00adtusen" },
1668 { "21,000", "tjugo\\u00adet\\u00adtusen" },
1669 { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1670 { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" },
1671 { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" },
1672 { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhundra" },
1673 { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1674 { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adfem\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" },
1675 { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" },
1676 { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrtio\\u00adfem komma sex sju \\u00e5tta" },
1679 doTest(formatter
, testDataDefault
, TRUE
);
1681 static const char* testDataNeutrum
[][2] = {
1682 { "101", "ett\\u00adhundra\\u00adett" },
1683 { "1,001", "et\\u00adtusen ett" },
1684 { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1685 { "10,001", "tio\\u00adtusen ett" },
1686 { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1690 formatter
->setDefaultRuleSet("%spellout-cardinal-neuter", status
);
1691 if (U_SUCCESS(status
)) {
1692 logln(" testing spellout-cardinal-neuter rules");
1693 doTest(formatter
, testDataNeutrum
, TRUE
);
1696 errln("Can't test spellout-cardinal-neuter rules");
1699 static const char* testDataYear
[][2] = {
1700 { "101", "ett\\u00adhundra\\u00adett" },
1701 { "900", "nio\\u00adhundra" },
1702 { "1,001", "et\\u00adtusen ett" },
1703 { "1,100", "elva\\u00adhundra" },
1704 { "1,101", "elva\\u00adhundra\\u00adett" },
1705 { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" },
1706 { "2,001", "tjugo\\u00adhundra\\u00adett" },
1707 { "10,001", "tio\\u00adtusen ett" },
1711 status
= U_ZERO_ERROR
;
1712 formatter
->setDefaultRuleSet("%spellout-numbering-year", status
);
1713 if (U_SUCCESS(status
)) {
1714 logln("testing year rules");
1715 doTest(formatter
, testDataYear
, TRUE
);
1718 errln("Can't test year rules");
1726 IntlTestRBNF::TestSmallValues()
1728 UErrorCode status
= U_ZERO_ERROR
;
1729 RuleBasedNumberFormat
* formatter
1730 = new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale("en_US"), status
);
1732 if (U_FAILURE(status
)) {
1733 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1735 static const char* const testDataDefault
[][2] = {
1736 { "0.001", "zero point zero zero one" },
1737 { "0.0001", "zero point zero zero zero one" },
1738 { "0.00001", "zero point zero zero zero zero one" },
1739 { "0.000001", "zero point zero zero zero zero zero one" },
1740 { "0.0000001", "zero point zero zero zero zero zero zero one" },
1741 { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1742 { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1743 { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1744 { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1745 { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1746 { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1747 { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1748 { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1749 { "10,000,000.001", "ten million point zero zero one" },
1750 { "10,000,000.0001", "ten million point zero zero zero one" },
1751 { "10,000,000.00001", "ten million point zero zero zero zero one" },
1752 { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1753 { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1754 // { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1755 // { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1756 { "10,000,000", "ten million" },
1757 // { "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" },
1758 // { "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" },
1759 // { "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" },
1760 { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
1761 { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
1762 { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
1763 { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
1764 { "123.321", "one hundred twenty-three point three two one" },
1765 { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1766 { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1770 doTest(formatter
, testDataDefault
, TRUE
);
1777 IntlTestRBNF::TestLocalizations(void)
1780 UnicodeString
rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1781 "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1783 UErrorCode status
= U_ZERO_ERROR
;
1785 RuleBasedNumberFormat
formatter(rules
, perror
, status
);
1786 if (U_FAILURE(status
)) {
1787 errcheckln(status
, "FAIL: could not construct formatter - %s", u_errorName(status
));
1790 static const char* const testData
[][2] = {
1792 { "5", "yah, some" },
1793 { "423", "plenty" },
1794 { "12345", "more'n you'll ever need" },
1797 doTest(&formatter
, testData
, FALSE
);
1801 UnicodeString
loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1802 static const char* const testData
[][2] = {
1806 { "12345", "tons" },
1809 RuleBasedNumberFormat
formatter0(rules
, loc
, perror
, status
);
1810 if (U_FAILURE(status
)) {
1811 errln("failed to build second formatter");
1813 doTest(&formatter0
, testData
, FALSE
);
1816 // exercise localization info
1817 Locale
locale0("en__VALLEY@turkey=gobblegobble");
1818 Locale
locale1("de_DE_FOO");
1819 Locale
locale2("ja_JP");
1820 UnicodeString name
= formatter0
.getRuleSetName(0);
1821 if ( formatter0
.getRuleSetDisplayName(0, locale0
) == "Main"
1822 && formatter0
.getRuleSetDisplayName(0, locale1
) == "das Main"
1823 && formatter0
.getRuleSetDisplayName(0, locale2
) == "%main"
1824 && formatter0
.getRuleSetDisplayName(name
, locale0
) == "Main"
1825 && formatter0
.getRuleSetDisplayName(name
, locale1
) == "das Main"
1826 && formatter0
.getRuleSetDisplayName(name
, locale2
) == "%main"){
1827 logln("getRuleSetDisplayName tested");
1829 errln("failed to getRuleSetDisplayName");
1833 for (i
= 0; i
< formatter0
.getNumberOfRuleSetDisplayNameLocales(); ++i
) {
1834 Locale locale
= formatter0
.getRuleSetDisplayNameLocale(i
, status
);
1835 if (U_SUCCESS(status
)) {
1836 for (int j
= 0; j
< formatter0
.getNumberOfRuleSetNames(); ++j
) {
1837 UnicodeString name
= formatter0
.getRuleSetName(j
);
1838 UnicodeString lname
= formatter0
.getRuleSetDisplayName(j
, locale
);
1839 UnicodeString msg
= locale
.getName();
1852 static const char* goodLocs
[] = {
1853 "", // zero-length ok, same as providing no localization data
1854 "<<>>", // no public rule sets ok
1855 "<<%main>>", // no localizations ok
1856 "<<%main,>,<en, Main,>>", // comma before close angle ok
1857 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1858 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1859 " \n <\n <\n %main\n >\n , \t <\t en\t , \tfoo \t\t > \n\n > \n ", // Pattern_White_Space ok
1861 int32_t goodLocsLen
= UPRV_LENGTHOF(goodLocs
);
1863 static const char* badLocs
[] = {
1864 " ", // non-zero length
1865 "<>", // empty array
1866 "<", // unclosed outer array
1867 "<<", // unclosed inner array
1868 "<<,>>", // unexpected comma
1869 "<<''>>", // empty string
1870 " x<<%main>>", // first non space char not open angle bracket
1871 "<%main>", // missing inner array
1872 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1873 "<<%main><en, Main>>", // arrays missing separating comma
1874 "<<%main>,<en, main, foo>>", // too many elements in locale data
1875 "<<%main>,<en>>", // too few elements in locale data
1876 "<<<%main>>>", // unexpected open angle
1877 "<<%main<>>>", // unexpected open angle
1878 "<<%main, %other>,<en,,>>", // implicit empty strings
1879 "<<%main>,<en,''>>", // empty string
1880 "<<%main>, < en, '>>", // unterminated quote
1881 "<<%main>, < en, \"<>>", // unterminated quote
1882 "<<%main\">>", // quote in string
1883 "<<%main'>>", // quote in string
1884 "<<%main<>>", // open angle in string
1885 "<<%main>> x", // extra non-space text at end
1888 int32_t badLocsLen
= UPRV_LENGTHOF(badLocs
);
1890 for (i
= 0; i
< goodLocsLen
; ++i
) {
1891 logln("[%d] '%s'", i
, goodLocs
[i
]);
1892 UErrorCode status
= U_ZERO_ERROR
;
1893 UnicodeString
loc(goodLocs
[i
]);
1894 RuleBasedNumberFormat
fmt(rules
, loc
, perror
, status
);
1895 if (U_FAILURE(status
)) {
1896 errln("Failed parse of good localization string: '%s'", goodLocs
[i
]);
1900 for (i
= 0; i
< badLocsLen
; ++i
) {
1901 logln("[%d] '%s'", i
, badLocs
[i
]);
1902 UErrorCode status
= U_ZERO_ERROR
;
1903 UnicodeString
loc(badLocs
[i
]);
1904 RuleBasedNumberFormat
fmt(rules
, loc
, perror
, status
);
1905 if (U_SUCCESS(status
)) {
1906 errln("Successful parse of bad localization string: '%s'", badLocs
[i
]);
1914 IntlTestRBNF::TestAllLocales()
1916 const char* names
[] = {
1919 // " (duration) " // This is English only, and it's not really supported in CLDR anymore.
1921 double numbers
[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
1924 const Locale
* locales
= Locale::getAvailableLocales(count
);
1925 for (int i
= 0; i
< count
; ++i
) {
1926 const Locale
* loc
= &locales
[i
];
1928 for (int j
= 0; j
< 2; ++j
) {
1929 UErrorCode status
= U_ZERO_ERROR
;
1930 RuleBasedNumberFormat
* f
= new RuleBasedNumberFormat((URBNFRuleSetTag
)j
, *loc
, status
);
1932 if (status
== U_USING_DEFAULT_WARNING
|| status
== U_USING_FALLBACK_WARNING
) {
1937 if (U_FAILURE(status
)) {
1938 errln(UnicodeString(loc
->getName()) + names
[j
]
1939 + "ERROR could not instantiate -> " + u_errorName(status
));
1942 #if !UCONFIG_NO_COLLATION
1943 for (unsigned int numidx
= 0; numidx
< UPRV_LENGTHOF(numbers
); numidx
++) {
1944 double n
= numbers
[numidx
];
1949 logln(UnicodeString(loc
->getName()) + names
[j
]
1950 + "success: " + n
+ " -> " + str
);
1953 // We do not validate the result in this test case,
1954 // because there are cases which do not round trip by design.
1958 status
= U_ZERO_ERROR
;
1959 f
->setLenient(FALSE
);
1960 f
->parse(str
, num
, status
);
1961 if (U_FAILURE(status
)) {
1962 errln(UnicodeString(loc
->getName()) + names
[j
]
1963 + "ERROR could not parse '" + str
+ "' -> " + u_errorName(status
));
1965 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1967 if (num
.getType() == Formattable::kLong
&& num
.getLong() != n
) {
1968 errln(UnicodeString(loc
->getName()) + names
[j
]
1969 + UnicodeString("ERROR could not roundtrip ") + n
1970 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getLong());
1972 else if (num
.getType() == Formattable::kDouble
&& (int64_t)(num
.getDouble() * 1000) != (int64_t)(n
*1000)) {
1973 // The epsilon difference is too high.
1974 errln(UnicodeString(loc
->getName()) + names
[j
]
1975 + UnicodeString("ERROR could not roundtrip ") + n
1976 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getDouble());
1979 if (!quick
&& !logKnownIssue("9503") ) {
1981 status
= U_ZERO_ERROR
;
1982 f
->setLenient(TRUE
);
1983 f
->parse(str
, num
, status
);
1984 if (U_FAILURE(status
)) {
1985 errln(UnicodeString(loc
->getName()) + names
[j
]
1986 + "ERROR could not parse(lenient) '" + str
+ "' -> " + u_errorName(status
));
1988 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1990 if (num
.getType() == Formattable::kLong
&& num
.getLong() != n
) {
1991 errln(UnicodeString(loc
->getName()) + names
[j
]
1992 + UnicodeString("ERROR could not roundtrip ") + n
1993 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getLong());
1995 else if (num
.getType() == Formattable::kDouble
&& (int64_t)(num
.getDouble() * 1000) != (int64_t)(n
*1000)) {
1996 // The epsilon difference is too high.
1997 errln(UnicodeString(loc
->getName()) + names
[j
]
1998 + UnicodeString("ERROR could not roundtrip ") + n
1999 + UnicodeString(" -> ") + str
+ UnicodeString(" -> ") + num
.getDouble());
2011 IntlTestRBNF::TestMultiplierSubstitution(void) {
2012 UnicodeString
rules("=#,##0=;1,000,000: <##0.###< million;");
2013 UErrorCode status
= U_ZERO_ERROR
;
2014 UParseError parse_error
;
2015 RuleBasedNumberFormat
*rbnf
=
2016 new RuleBasedNumberFormat(rules
, Locale::getUS(), parse_error
, status
);
2017 if (U_SUCCESS(status
)) {
2020 double n
= 1234000.0;
2021 rbnf
->format(n
, res
, pos
);
2024 UnicodeString
expected(UNICODE_STRING_SIMPLE("1.234 million"));
2025 if (expected
!= res
) {
2026 UnicodeString msg
= "Expected: ";
2027 msg
.append(expected
);
2028 msg
.append(" but got ");
2036 IntlTestRBNF::TestSetDecimalFormatSymbols() {
2037 UErrorCode status
= U_ZERO_ERROR
;
2039 RuleBasedNumberFormat
rbnf(URBNF_ORDINAL
, Locale::getEnglish(), status
);
2040 if (U_FAILURE(status
)) {
2041 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2045 DecimalFormatSymbols
dfs(Locale::getEnglish(), status
);
2046 if (U_FAILURE(status
)) {
2047 errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status
)));
2051 UnicodeString expected
[] = {
2052 UnicodeString("1,001st"),
2053 UnicodeString("1&001st")
2056 double number
= 1001;
2058 UnicodeString result
;
2060 rbnf
.format(number
, result
);
2061 if (result
!= expected
[0]) {
2062 errln("Format Error - Got: " + result
+ " Expected: " + expected
[0]);
2067 /* Set new symbol for testing */
2068 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, UnicodeString("&"), TRUE
);
2069 rbnf
.setDecimalFormatSymbols(dfs
);
2071 rbnf
.format(number
, result
);
2072 if (result
!= expected
[1]) {
2073 errln("Format Error - Got: " + result
+ " Expected: " + expected
[1]);
2077 void IntlTestRBNF::TestPluralRules() {
2078 UErrorCode status
= U_ZERO_ERROR
;
2079 UnicodeString
enRules("%digits-ordinal:-x: ->>;0: =#,##0=$(ordinal,one{st}two{nd}few{rd}other{th})$;");
2080 UParseError parseError
;
2081 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2082 if (U_FAILURE(status
)) {
2083 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2086 const char* const enTestData
[][2] = {
2102 doTest(&enFormatter
, enTestData
, TRUE
);
2104 // This is trying to model the feminine form, but don't worry about the details too much.
2105 // We're trying to test the plural rules.
2106 UnicodeString
ruRules("%spellout-numbering:"
2137 "100: hundred[ >>];"
2138 "200: << hundred[ >>];"
2139 "300: << hundreds[ >>];"
2140 "500: << hundredss[ >>];"
2141 "1000: << $(cardinal,one{thousand}few{thousands}other{thousandss})$[ >>];"
2142 "1000000: << $(cardinal,one{million}few{millions}other{millionss})$[ >>];");
2143 RuleBasedNumberFormat
ruFormatter(ruRules
, Locale("ru"), parseError
, status
);
2144 const char* const ruTestData
[][2] = {
2146 { "100", "hundred" },
2147 { "125", "hundred twenty-five" },
2148 { "399", "three hundreds ninety-nine" },
2149 { "1,000", "one thousand" },
2150 { "1,001", "one thousand one" },
2151 { "2,000", "two thousands" },
2152 { "2,001", "two thousands one" },
2153 { "2,002", "two thousands two" },
2154 { "3,333", "three thousands three hundreds thirty-three" },
2155 { "5,000", "five thousandss" },
2156 { "11,000", "eleven thousandss" },
2157 { "21,000", "twenty-one thousand" },
2158 { "22,000", "twenty-two thousands" },
2159 { "25,001", "twenty-five thousandss one" },
2163 if (U_FAILURE(status
)) {
2164 errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2167 doTest(&ruFormatter
, ruTestData
, TRUE
);
2169 // Make sure there are no divide by 0 errors.
2170 UnicodeString result
;
2171 RuleBasedNumberFormat(ruRules
, Locale("ru"), parseError
, status
).format((int32_t)21000, result
);
2172 if (result
.compare(UNICODE_STRING_SIMPLE("twenty-one thousand")) != 0) {
2173 errln("Got " + result
+ " for 21000");
2178 void IntlTestRBNF::TestInfinityNaN() {
2179 UErrorCode status
= U_ZERO_ERROR
;
2180 UParseError parseError
;
2181 UnicodeString
enRules("%default:"
2184 "NaN: not a number;"
2186 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2187 const char * const enTestData
[][2] = {
2189 {"\\u221E", "infinite"},
2190 {"-\\u221E", "minus infinite"},
2191 {"NaN", "not a number"},
2194 if (U_FAILURE(status
)) {
2195 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2199 doTest(&enFormatter
, enTestData
, true);
2201 // Test the default behavior when the rules are undefined.
2202 UnicodeString
enRules2("%default:"
2205 RuleBasedNumberFormat
enFormatter2(enRules2
, Locale::getEnglish(), parseError
, status
);
2206 if (U_FAILURE(status
)) {
2207 errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2210 const char * const enDefaultTestData
[][2] = {
2212 {"\\u221E", "\\u221E"},
2213 {"-\\u221E", "-\\u221E"},
2218 doTest(&enFormatter2
, enDefaultTestData
, true);
2221 void IntlTestRBNF::TestVariableDecimalPoint() {
2222 UErrorCode status
= U_ZERO_ERROR
;
2223 UParseError parseError
;
2224 UnicodeString
enRules("%spellout-numbering:"
2240 RuleBasedNumberFormat
enFormatter(enRules
, Locale::getEnglish(), parseError
, status
);
2241 const char * const enTestPointData
[][2] = {
2242 {"1.1", "one point one"},
2243 {"1.23", "one point two three"},
2244 {"0.4", "xpoint four"},
2247 if (U_FAILURE(status
)) {
2248 dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status
)));
2251 doTest(&enFormatter
, enTestPointData
, true);
2253 DecimalFormatSymbols
decimalFormatSymbols(Locale::getEnglish(), status
);
2254 decimalFormatSymbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UNICODE_STRING_SIMPLE(","));
2255 enFormatter
.setDecimalFormatSymbols(decimalFormatSymbols
);
2256 const char * const enTestCommaData
[][2] = {
2257 {"1.1", "one comma one"},
2258 {"1.23", "one comma two three"},
2259 {"0.4", "xcomma four"},
2262 doTest(&enFormatter
, enTestCommaData
, true);
2265 void IntlTestRBNF::TestLargeNumbers() {
2266 UErrorCode status
= U_ZERO_ERROR
;
2267 RuleBasedNumberFormat
rbnf(URBNF_SPELLOUT
, Locale::getEnglish(), status
);
2269 const char * const enTestFullData
[][2] = {
2270 {"-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
2271 {"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
2272 {"-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
2273 {"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
2274 {"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"},
2275 {"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"},
2276 {"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"},
2277 {"1000000000000000000", "1,000,000,000,000,000,000"}, // The rules don't go to 1 quintillion yet
2278 {"-9223372036854775809", "-9,223,372,036,854,775,809"}, // We've gone beyond 64-bit precision
2279 {"-9223372036854775808", "-9,223,372,036,854,775,808"}, // We've gone beyond +64-bit precision
2280 {"-9223372036854775807", "minus 9,223,372,036,854,775,807"}, // Minimum 64-bit precision
2281 {"-9223372036854775806", "minus 9,223,372,036,854,775,806"}, // Minimum 64-bit precision + 1
2282 {"9223372036854774111", "9,223,372,036,854,774,111"}, // Below 64-bit precision
2283 {"9223372036854774999", "9,223,372,036,854,774,999"}, // Below 64-bit precision
2284 {"9223372036854775000", "9,223,372,036,854,775,000"}, // Below 64-bit precision
2285 {"9223372036854775806", "9,223,372,036,854,775,806"}, // Maximum 64-bit precision - 1
2286 {"9223372036854775807", "9,223,372,036,854,775,807"}, // Maximum 64-bit precision
2287 {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2290 doTest(&rbnf
, enTestFullData
, false);
2293 void IntlTestRBNF::TestCompactDecimalFormatStyle() {
2294 UErrorCode status
= U_ZERO_ERROR
;
2295 UParseError parseError
;
2296 // This is not a common use case, but we're testing it anyway.
2297 UnicodeString
numberPattern("=###0.#####=;"
2298 "1000: <###0.00< K;"
2299 "1000000: <###0.00< M;"
2300 "1000000000: <###0.00< B;"
2301 "1000000000000: <###0.00< T;"
2302 "1000000000000000: <###0.00< Q;");
2303 RuleBasedNumberFormat
rbnf(numberPattern
, UnicodeString(), Locale::getEnglish(), parseError
, status
);
2305 const char * const enTestFullData
[][2] = {
2308 {"999994", "999.99 K"},
2309 {"999995", "1000.00 K"},
2310 {"1000000", "1.00 M"},
2311 {"1200000", "1.20 M"},
2312 {"1200000000", "1.20 B"},
2313 {"1200000000000", "1.20 T"},
2314 {"1200000000000000", "1.20 Q"},
2315 {"4503599627370495", "4.50 Q"},
2316 {"4503599627370496", "4.50 Q"},
2317 {"8990000000000000", "8.99 Q"},
2318 {"9008000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2319 {"9456000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2320 {"10000000000000000", "10.00 Q"}, // Number doesn't precisely fit into a double
2321 {"9223372036854775807", "9223.00 Q"}, // Maximum 64-bit precision
2322 {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2325 doTest(&rbnf
, enTestFullData
, false);
2329 IntlTestRBNF::doTest(RuleBasedNumberFormat
* formatter
, const char* const testData
[][2], UBool testParsing
)
2331 // man, error reporting would be easier with printf-style syntax for unicode string and formattable
2333 UErrorCode status
= U_ZERO_ERROR
;
2334 DecimalFormatSymbols
dfs("en", status
);
2335 // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2336 DecimalFormat
decFmt("#,###.################", dfs
, status
);
2337 if (U_FAILURE(status
)) {
2338 errcheckln(status
, "FAIL: could not create NumberFormat - %s", u_errorName(status
));
2340 for (int i
= 0; testData
[i
][0]; ++i
) {
2341 const char* numString
= testData
[i
][0];
2342 const char* expectedWords
= testData
[i
][1];
2344 log("[%i] %s = ", i
, numString
);
2345 Formattable expectedNumber
;
2346 UnicodeString escapedNumString
= UnicodeString(numString
, -1, US_INV
).unescape();
2347 decFmt
.parse(escapedNumString
, expectedNumber
, status
);
2348 if (U_FAILURE(status
)) {
2349 errln("FAIL: decFmt could not parse %s", numString
);
2352 UnicodeString actualString
;
2354 formatter
->format(expectedNumber
, actualString
/* , pos*/, status
);
2355 if (U_FAILURE(status
)) {
2356 UnicodeString msg
= "Fail: formatter could not format ";
2357 decFmt
.format(expectedNumber
, msg
, status
);
2361 UnicodeString expectedString
= UnicodeString(expectedWords
, -1, US_INV
).unescape();
2362 if (actualString
!= expectedString
) {
2363 UnicodeString msg
= "FAIL: check failed for ";
2364 decFmt
.format(expectedNumber
, msg
, status
);
2365 msg
.append(", expected ");
2366 msg
.append(expectedString
);
2367 msg
.append(" but got ");
2368 msg
.append(actualString
);
2372 logln(actualString
);
2374 Formattable parsedNumber
;
2375 formatter
->parse(actualString
, parsedNumber
, status
);
2376 if (U_FAILURE(status
)) {
2377 UnicodeString msg
= "FAIL: formatter could not parse ";
2378 msg
.append(actualString
);
2379 msg
.append(" status code: " );
2380 msg
.append(u_errorName(status
));
2384 if (parsedNumber
!= expectedNumber
2385 && (!uprv_isNaN(parsedNumber
.getDouble()) || !uprv_isNaN(expectedNumber
.getDouble())))
2387 UnicodeString msg
= "FAIL: parse failed for ";
2388 msg
.append(actualString
);
2389 msg
.append(", expected ");
2390 decFmt
.format(expectedNumber
, msg
, status
);
2391 msg
.append(", but got ");
2392 decFmt
.format(parsedNumber
, msg
, status
);
2406 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat
* formatter
, const char* testData
[][2])
2408 UErrorCode status
= U_ZERO_ERROR
;
2409 NumberFormat
* decFmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2410 if (U_FAILURE(status
)) {
2411 errcheckln(status
, "FAIL: could not create NumberFormat - %s", u_errorName(status
));
2413 for (int i
= 0; testData
[i
][0]; ++i
) {
2414 const char* spelledNumber
= testData
[i
][0]; // spelled-out number
2415 const char* asciiUSNumber
= testData
[i
][1]; // number as ascii digits formatted for US locale
2417 UnicodeString spelledNumberString
= UnicodeString(spelledNumber
).unescape();
2418 Formattable actualNumber
;
2419 formatter
->parse(spelledNumberString
, actualNumber
, status
);
2420 if (U_FAILURE(status
)) {
2421 UnicodeString msg
= "FAIL: formatter could not parse ";
2422 msg
.append(spelledNumberString
);
2426 // I changed the logic of this test somewhat from Java-- instead of comparing the
2427 // strings, I compare the Formattables. Hmmm, but the Formattables don't compare,
2428 // so change it back.
2430 UnicodeString asciiUSNumberString
= asciiUSNumber
;
2431 Formattable expectedNumber
;
2432 decFmt
->parse(asciiUSNumberString
, expectedNumber
, status
);
2433 if (U_FAILURE(status
)) {
2434 UnicodeString msg
= "FAIL: decFmt could not parse ";
2435 msg
.append(asciiUSNumberString
);
2439 UnicodeString actualNumberString
;
2440 UnicodeString expectedNumberString
;
2441 decFmt
->format(actualNumber
, actualNumberString
, status
);
2442 decFmt
->format(expectedNumber
, expectedNumberString
, status
);
2443 if (actualNumberString
!= expectedNumberString
) {
2444 UnicodeString msg
= "FAIL: parsing";
2445 msg
.append(asciiUSNumberString
);
2447 msg
.append(" lenient parse failed for ");
2448 msg
.append(spelledNumberString
);
2449 msg
.append(", expected ");
2450 msg
.append(expectedNumberString
);
2451 msg
.append(", but got ");
2452 msg
.append(actualNumberString
);
2467 IntlTestRBNF::TestRBNFDisabled() {
2468 errln("*** RBNF currently disabled on this platform ***\n");
2474 #endif /* #if !UCONFIG_NO_FORMATTING */