• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  *******************************************************************************
5  * Copyright (C) 1996-2016, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  *******************************************************************************
8  */
9 
10 #include "unicode/utypes.h"
11 
12 #if !UCONFIG_NO_FORMATTING
13 
14 #include "itrbnf.h"
15 
16 #include "unicode/umachine.h"
17 
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"
24 #include "cmemory.h"
25 #include "putilimp.h"
26 #include "testutil.h"
27 
28 #include <string.h>
29 
30 // import com.ibm.text.RuleBasedNumberFormat;
31 // import com.ibm.test.TestFmwk;
32 
33 // import java.util.Locale;
34 // import java.text.NumberFormat;
35 
36 // current macro not in icu1.8.1
37 #define TESTCASE(id,test)             \
38     case id:                          \
39         name = #test;                 \
40         if (exec) {                   \
41             logln(#test "---");       \
42             logln();                  \
43             test();                   \
44         }                             \
45         break
46 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)47 void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
48 {
49     if (exec) logln("TestSuite RuleBasedNumberFormat");
50     switch (index) {
51 #if U_HAVE_RBNF
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);
61         TESTCASE(9, TestAPI);
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);
80         TESTCASE(28, TestNorwegianSpellout);
81 #else
82         TESTCASE(0, TestRBNFDisabled);
83 #endif
84     default:
85         name = "";
86         break;
87     }
88 }
89 
90 #if U_HAVE_RBNF
91 
TestHebrewFraction()92 void IntlTestRBNF::TestHebrewFraction() {
93 
94     // this is the expected output for 123.45, with no '<' in it.
95     UChar text1[] = {
96         0x05de, 0x05d0, 0x05d4, 0x0020,
97         0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
98         0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
99         0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
100         0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020,
101         0x05d7, 0x05de, 0x05e9, 0x0000,
102     };
103     UChar text2[] = {
104         0x05DE, 0x05D0, 0x05D4, 0x0020,
105         0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020,
106         0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020,
107         0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020,
108         0x05D0, 0x05E4, 0x05E1, 0x0020,
109         0x05D0, 0x05E4, 0x05E1, 0x0020,
110         0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020,
111         0x05D7, 0x05DE, 0x05E9, 0x0000,
112     };
113     UErrorCode status = U_ZERO_ERROR;
114     RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(URBNF_SPELLOUT, "he_IL", status);
115     if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
116         errcheckln(status, "Failed in constructing RuleBasedNumberFormat - %s", u_errorName(status));
117         delete formatter;
118         return;
119     }
120     UnicodeString result;
121     Formattable parseResult;
122     ParsePosition pp(0);
123     {
124         UnicodeString expected(text1);
125         formatter->format(123.45, result);
126         if (result != expected) {
127             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
128         } else {
129 //            formatter->parse(result, parseResult, pp);
130 //            if (parseResult.getDouble() != 123.45) {
131 //                errln("expected 123.45 but got: %g", parseResult.getDouble());
132 //            }
133         }
134     }
135     {
136         UnicodeString expected(text2);
137         result.remove();
138         formatter->format(123.0045, result);
139         if (result != expected) {
140             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
141         } else {
142             pp.setIndex(0);
143 //            formatter->parse(result, parseResult, pp);
144 //            if (parseResult.getDouble() != 123.0045) {
145 //                errln("expected 123.0045 but got: %g", parseResult.getDouble());
146 //            }
147         }
148     }
149     delete formatter;
150 }
151 
152 void
TestAPI()153 IntlTestRBNF::TestAPI() {
154   // This test goes through the APIs that were not tested before.
155   // These tests are too small to have separate test classes/functions
156 
157   UErrorCode status = U_ZERO_ERROR;
158   RuleBasedNumberFormat* formatter
159       = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
160   if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
161     dataerrln("Unable to create formatter. - %s", u_errorName(status));
162     delete formatter;
163     return;
164   }
165 
166   logln("RBNF API test starting");
167   // test clone
168   {
169     logln("Testing Clone");
170     RuleBasedNumberFormat* rbnfClone = formatter->clone();
171     if(rbnfClone != NULL) {
172       if(!(*rbnfClone == *formatter)) {
173         errln("Clone should be semantically equivalent to the original!");
174       }
175       delete rbnfClone;
176     } else {
177       errln("Cloning failed!");
178     }
179   }
180 
181   // test assignment
182   {
183     logln("Testing assignment operator");
184     RuleBasedNumberFormat assignResult(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
185     assignResult = *formatter;
186     if(!(assignResult == *formatter)) {
187       errln("Assignment result should be semantically equivalent to the original!");
188     }
189   }
190 
191   // test rule constructor
192   {
193     logln("Testing rule constructor");
194     LocalUResourceBundlePointer en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf", "en", &status));
195     if(U_FAILURE(status)) {
196       errln("Unable to access resource bundle with data!");
197     } else {
198       int32_t ruleLen = 0;
199       int32_t len = 0;
200       LocalUResourceBundlePointer rbnfRules(ures_getByKey(en.getAlias(), "RBNFRules", NULL, &status));
201       LocalUResourceBundlePointer ruleSets(ures_getByKey(rbnfRules.getAlias(), "SpelloutRules", NULL, &status));
202       UnicodeString desc;
203       while (ures_hasNext(ruleSets.getAlias())) {
204            const UChar* currentString = ures_getNextString(ruleSets.getAlias(), &len, NULL, &status);
205            ruleLen += len;
206            desc.append(currentString);
207       }
208 
209       const UChar *spelloutRules = desc.getTerminatedBuffer();
210 
211       if(U_FAILURE(status) || ruleLen == 0 || spelloutRules == NULL) {
212         errln("Unable to access the rules string!");
213       } else {
214         UParseError perror;
215         RuleBasedNumberFormat ruleCtorResult(spelloutRules, Locale::getUS(), perror, status);
216         if(!(ruleCtorResult == *formatter)) {
217           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
218         }
219 
220         // Jitterbug 4452, for coverage
221         RuleBasedNumberFormat nf(spelloutRules, (UnicodeString)"", Locale::getUS(), perror, status);
222         if(!(nf == *formatter)) {
223           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
224         }
225       }
226     }
227   }
228 
229   // test getRules
230   {
231     logln("Testing getRules function");
232     UnicodeString rules = formatter->getRules();
233     UParseError perror;
234     RuleBasedNumberFormat fromRulesResult(rules, Locale::getUS(), perror, status);
235 
236     if(!(fromRulesResult == *formatter)) {
237       errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
238     }
239   }
240 
241 
242   {
243     logln("Testing copy constructor");
244     RuleBasedNumberFormat copyCtorResult(*formatter);
245     if(!(copyCtorResult == *formatter)) {
246       errln("Copy constructor result result should be semantically equivalent to the original!");
247     }
248   }
249 
250 #if !UCONFIG_NO_COLLATION
251   // test ruleset names
252   {
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");
257     }
258     UnicodeString ruleSetName;
259     int32_t i = 0;
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 
268       ruleSetName = formatter->getRuleSetName(i);
269       log("Rule set name %i is ", i);
270       log(ruleSetName);
271       logln(". Format results are: ");
272       intFormatResult = formatter->format(intFormatNum, ruleSetName, intFormatResult, pos1, status);
273       doubleFormatResult = formatter->format(doubleFormatNum, ruleSetName, doubleFormatResult, pos2, status);
274       if(U_FAILURE(status)) {
275         errln("Format using a rule set failed");
276         break;
277       }
278       logln(intFormatResult);
279       logln(doubleFormatResult);
280       formatter->setLenient(TRUE);
281       formatter->parse(intFormatResult, intParseResult, status);
282       formatter->parse(doubleFormatResult, doubleParseResult, status);
283 
284       logln("Parse results for lenient = TRUE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
285 
286       formatter->setLenient(FALSE);
287       formatter->parse(intFormatResult, intParseResult, status);
288       formatter->parse(doubleFormatResult, doubleParseResult, status);
289 
290       logln("Parse results for lenient = FALSE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
291 
292       if(U_FAILURE(status)) {
293         errln("Error during parsing");
294       }
295 
296       intFormatResult = formatter->format(intFormatNum, "BLABLA", intFormatResult, pos1, status);
297       if(U_SUCCESS(status)) {
298         errln("Using invalid rule set name should have failed");
299         break;
300       }
301       status = U_ZERO_ERROR;
302       doubleFormatResult = formatter->format(doubleFormatNum, "TRUC", doubleFormatResult, pos2, status);
303       if(U_SUCCESS(status)) {
304         errln("Using invalid rule set name should have failed");
305         break;
306       }
307       status = U_ZERO_ERROR;
308     }
309     status = U_ZERO_ERROR;
310   }
311 #endif
312 
313   // test API
314   UnicodeString expected("four point five","");
315   logln("Testing format(double)");
316   UnicodeString result;
317   formatter->format(4.5,result);
318   if(result != expected) {
319       errln("Formatted 4.5, expected " + expected + " got " + result);
320   } else {
321       logln("Formatted 4.5, expected " + expected + " got " + result);
322   }
323   result.remove();
324   expected = "four";
325   formatter->format((int32_t)4,result);
326   if(result != expected) {
327       errln("Formatted 4, expected " + expected + " got " + result);
328   } else {
329       logln("Formatted 4, expected " + expected + " got " + result);
330   }
331 
332   result.remove();
333   FieldPosition pos;
334   formatter->format((int64_t)4, result, pos, status = U_ZERO_ERROR);
335   if(result != expected) {
336       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
337   } else {
338       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
339   }
340 
341   //Jitterbug 4452, for coverage
342   result.remove();
343   FieldPosition pos2;
344   formatter->format((int64_t)4, formatter->getRuleSetName(0), result, pos2, status = U_ZERO_ERROR);
345   if(result != expected) {
346       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
347   } else {
348       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
349   }
350 
351   // clean up
352   logln("Cleaning up");
353   delete formatter;
354 }
355 
356 /**
357  * Perform a simple spot check on the parsing going into an infinite loop for alternate rules.
358  */
TestMultiplePluralRules()359 void IntlTestRBNF::TestMultiplePluralRules() {
360     // This is trying to model the feminine form, but don't worry about the details too much.
361     // We're trying to test the plural rules where there are different prefixes.
362     UnicodeString rules("%spellout-cardinal-feminine-genitive:"
363                 "0: zero;"
364                 "1: ono;"
365                 "2: two;"
366                 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
367                 "%spellout-cardinal-feminine:"
368                 "x.x: [<< $(cardinal,one{singleton}other{plurality})$ ]>%%fractions>;"
369                 "0: zero;"
370                 "1: one;"
371                 "2: two;"
372                 "1000: << $(cardinal,one{thousand}few{thousanF}other{thousanO})$[ >>];"
373                 "%%fractions:"
374                 "10: <%spellout-cardinal-feminine< $(cardinal,one{oneth}other{tenth})$;"
375                 "100: <%spellout-cardinal-feminine< $(cardinal,one{1hundredth}other{hundredth})$;");
376     UErrorCode status = U_ZERO_ERROR;
377     UParseError pError;
378     RuleBasedNumberFormat formatter(rules, Locale("ru"), pError, status);
379     Formattable result;
380     UnicodeString resultStr;
381     FieldPosition pos;
382 
383     if (U_FAILURE(status)) {
384         dataerrln("Unable to create formatter - %s", u_errorName(status));
385         return;
386     }
387 
388     formatter.parse(formatter.format(1000.0, resultStr, pos, status), result, status);
389     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("one thousand")) {
390         errln("RuleBasedNumberFormat did not return the correct value. Got: %d", result.getLong());
391         errln(resultStr);
392     }
393     resultStr.remove();
394     formatter.parse(formatter.format(1000.0, UnicodeString("%spellout-cardinal-feminine-genitive"), resultStr, pos, status), result, status);
395     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("ono thousand")) {
396         errln("RuleBasedNumberFormat(cardinal-feminine-genitive) did not return the correct value. Got: %d", result.getLong());
397         errln(resultStr);
398     }
399     resultStr.remove();
400     formatter.parse(formatter.format(1000.0, UnicodeString("%spellout-cardinal-feminine"), resultStr, pos, status), result, status);
401     if (1000 != result.getLong() || resultStr != UNICODE_STRING_SIMPLE("one thousand")) {
402         errln("RuleBasedNumberFormat(spellout-cardinal-feminine) did not return the correct value. Got: %d", result.getLong());
403         errln(resultStr);
404     }
405     static const char* const testData[][2] = {
406         { "0", "zero" },
407         { "1", "one" },
408         { "2", "two" },
409         { "0.1", "one oneth" },
410         { "0.2", "two tenth" },
411         { "1.1", "one singleton one oneth" },
412         { "1.2", "one singleton two tenth" },
413         { "2.1", "two plurality one oneth" },
414         { "2.2", "two plurality two tenth" },
415         { "0.01", "one 1hundredth" },
416         { "0.02", "two hundredth" },
417         { NULL, NULL }
418     };
419     doTest(&formatter, testData, TRUE);
420 }
421 
TestFractionalRuleSet()422 void IntlTestRBNF::TestFractionalRuleSet()
423 {
424     UnicodeString fracRules(
425         "%main:\n"
426                // this rule formats the number if it's 1 or more.  It formats
427                // the integral part using a DecimalFormat ("#,##0" puts
428                // thousands separators in the right places) and the fractional
429                // part using %%frac.  If there is no fractional part, it
430                // just shows the integral part.
431         "    x.0: <#,##0<[ >%%frac>];\n"
432                // this rule formats the number if it's between 0 and 1.  It
433                // shows only the fractional part (0.5 shows up as "1/2," not
434                // "0 1/2")
435         "    0.x: >%%frac>;\n"
436         // the fraction rule set.  This works the same way as the one in the
437         // preceding example: We multiply the fractional part of the number
438         // being formatted by each rule's base value and use the rule that
439         // produces the result closest to 0 (or the first rule that produces 0).
440         // Since we only provide rules for the numbers from 2 to 10, we know
441         // we'll get a fraction with a denominator between 2 and 10.
442         // "<0<" causes the numerator of the fraction to be formatted
443         // using numerals
444         "%%frac:\n"
445         "    2: 1/2;\n"
446         "    3: <0</3;\n"
447         "    4: <0</4;\n"
448         "    5: <0</5;\n"
449         "    6: <0</6;\n"
450         "    7: <0</7;\n"
451         "    8: <0</8;\n"
452         "    9: <0</9;\n"
453         "   10: <0</10;\n");
454 
455     // mondo hack
456     int len = fracRules.length();
457     int change = 2;
458     for (int i = 0; i < len; ++i) {
459         UChar ch = fracRules.charAt(i);
460         if (ch == '\n') {
461             change = 2; // change ok
462         } else if (ch == ':') {
463             change = 1; // change, but once we hit a non-space char, don't change
464         } else if (ch == ' ') {
465             if (change != 0) {
466                 fracRules.setCharAt(i, (UChar)0x200e);
467             }
468         } else {
469             if (change == 1) {
470                 change = 0;
471             }
472         }
473     }
474 
475     UErrorCode status = U_ZERO_ERROR;
476     UParseError perror;
477     RuleBasedNumberFormat formatter(fracRules, Locale::getEnglish(), perror, status);
478     if (U_FAILURE(status)) {
479         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
480     } else {
481         static const char* const testData[][2] = {
482             { "0", "0" },
483             { ".1", "1/10" },
484             { ".11", "1/9" },
485             { ".125", "1/8" },
486             { ".1428", "1/7" },
487             { ".1667", "1/6" },
488             { ".2", "1/5" },
489             { ".25", "1/4" },
490             { ".333", "1/3" },
491             { ".5", "1/2" },
492             { "1.1", "1 1/10" },
493             { "2.11", "2 1/9" },
494             { "3.125", "3 1/8" },
495             { "4.1428", "4 1/7" },
496             { "5.1667", "5 1/6" },
497             { "6.2", "6 1/5" },
498             { "7.25", "7 1/4" },
499             { "8.333", "8 1/3" },
500             { "9.5", "9 1/2" },
501             { ".2222", "2/9" },
502             { ".4444", "4/9" },
503             { ".5555", "5/9" },
504             { "1.2856", "1 2/7" },
505             { NULL, NULL }
506         };
507         doTest(&formatter, testData, FALSE); // exact values aren't parsable from fractions
508     }
509 }
510 
511 #if 0
512 #define LLAssert(a) \
513   if (!(a)) errln("FAIL: " #a)
514 
515 void IntlTestRBNF::TestLLongConstructors()
516 {
517     logln("Testing constructors");
518 
519     // constant (shouldn't really be public)
520     LLAssert(llong(llong::kD32).asDouble() == llong::kD32);
521 
522     // internal constructor (shouldn't really be public)
523     LLAssert(llong(0, 1).asDouble() == 1);
524     LLAssert(llong(1, 0).asDouble() == llong::kD32);
525     LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
526 
527     // public empty constructor
528     LLAssert(llong().asDouble() == 0);
529 
530     // public int32_t constructor
531     LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
532     LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
533     LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
534     LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
535     LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
536     LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
537 
538     // public int16_t constructor
539     LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
540     LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
541     LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
542     LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
543     LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
544     LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
545 
546     // public int8_t constructor
547     LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
548     LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
549     LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
550     LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
551     LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
552     LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
553 
554     // public uint16_t constructor
555     LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
556     LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
557     LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
558     LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
559     LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
560     LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
561 
562     // public uint32_t constructor
563     LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
564     LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
565     LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
566     LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
567     LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
568     LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
569 
570     // public double constructor
571     LLAssert(llong((double)0).asDouble() == (double)0);
572     LLAssert(llong((double)1).asDouble() == (double)1);
573     LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
574     LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
575     LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
576 
577     // can't access uprv_maxmantissa, so fake it
578     double maxmantissa = (llong((int32_t)1) << 40).asDouble();
579     LLAssert(llong(maxmantissa).asDouble() == maxmantissa);
580     LLAssert(llong(-maxmantissa).asDouble() == -maxmantissa);
581 
582     // copy constructor
583     LLAssert(llong(llong(0, 1)).asDouble() == 1);
584     LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32);
585     LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
586 
587     // asInt - test unsigned to signed narrowing conversion
588     LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
589     LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
590 
591     // asUInt - test signed to unsigned narrowing conversion
592     LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
593     LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
594 
595     // asDouble already tested
596 
597 }
598 
599 void IntlTestRBNF::TestLLongSimpleOperators()
600 {
601     logln("Testing simple operators");
602 
603     // operator==
604     LLAssert(llong() == llong(0, 0));
605     LLAssert(llong(1,0) == llong(1, 0));
606     LLAssert(llong(0,1) == llong(0, 1));
607 
608     // operator!=
609     LLAssert(llong(1,0) != llong(1,1));
610     LLAssert(llong(0,1) != llong(1,1));
611     LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
612 
613     // unsigned >
614     LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
615 
616     // unsigned <
617     LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
618 
619     // unsigned >=
620     LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
621     LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
622 
623     // unsigned <=
624     LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
625     LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
626 
627     // operator>
628     LLAssert(llong(1, 1) > llong(1, 0));
629     LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
630     LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
631     LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
632     LLAssert(llong(1, 0) > llong(0, 0xffffffff));
633     LLAssert(llong(0, 0) > llong(0x80000000, 1));
634 
635     // operator<
636     LLAssert(llong(1, 0) < llong(1, 1));
637     LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
638     LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
639     LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
640     LLAssert(llong(0, 0xffffffff) < llong(1, 0));
641     LLAssert(llong(0x80000000, 1) < llong(0, 0));
642 
643     // operator>=
644     LLAssert(llong(1, 1) >= llong(1, 0));
645     LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
646     LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
647     LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
648     LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
649     LLAssert(llong(0, 0) >= llong(0x80000000, 1));
650     LLAssert(llong() >= llong(0, 0));
651     LLAssert(llong(1,0) >= llong(1, 0));
652     LLAssert(llong(0,1) >= llong(0, 1));
653 
654     // operator<=
655     LLAssert(llong(1, 0) <= llong(1, 1));
656     LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
657     LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
658     LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
659     LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
660     LLAssert(llong(0x80000000, 1) <= llong(0, 0));
661     LLAssert(llong() <= llong(0, 0));
662     LLAssert(llong(1,0) <= llong(1, 0));
663     LLAssert(llong(0,1) <= llong(0, 1));
664 
665     // operator==(int32)
666     LLAssert(llong() == (int32_t)0);
667     LLAssert(llong(0,1) == (int32_t)1);
668 
669     // operator!=(int32)
670     LLAssert(llong(1,0) != (int32_t)0);
671     LLAssert(llong(0,1) != (int32_t)2);
672     LLAssert(llong(0,0xffffffff) != (int32_t)-1);
673 
674     llong negOne(0xffffffff, 0xffffffff);
675 
676     // operator>(int32)
677     LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
678     LLAssert(negOne > (int32_t)-2);
679     LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
680     LLAssert(llong(0, 0) > (int32_t)-1);
681 
682     // operator<(int32)
683     LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
684     LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
685 
686     // operator>=(int32)
687     LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
688     LLAssert(negOne >= (int32_t)-2);
689     LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
690     LLAssert(llong(0, 0) >= (int32_t)-1);
691     LLAssert(llong() >= (int32_t)0);
692     LLAssert(llong(0,1) >= (int32_t)1);
693 
694     // operator<=(int32)
695     LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
696     LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
697     LLAssert(llong() <= (int32_t)0);
698     LLAssert(llong(0,1) <= (int32_t)1);
699 
700     // operator=
701     LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
702 
703     // operator <<=
704     LLAssert((llong(1, 1) <<= 0) ==  llong(1, 1));
705     LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
706     LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
707     LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
708     LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
709     LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
710 
711     // operator <<
712     LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
713 
714     // operator >>= (sign extended)
715     LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
716     LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
717     LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
718     LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
719     LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
720     LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
721 
722     // operator >> sign extended)
723     LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
724 
725     // ushr (right shift without sign extension)
726     LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
727     LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
728     LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
729     LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
730     LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
731     LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
732 
733     // operator&(llong)
734     LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
735 
736     // operator|(llong)
737     LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
738 
739     // operator^(llong)
740     LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
741 
742     // operator&(uint32)
743     LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
744 
745     // operator|(uint32)
746     LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
747 
748     // operator^(uint32)
749     LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
750 
751     // operator~
752     LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
753 
754     // operator&=(llong)
755     LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
756 
757     // operator|=(llong)
758     LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
759 
760     // operator^=(llong)
761     LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
762 
763     // operator&=(uint32)
764     LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
765 
766     // operator|=(uint32)
767     LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
768 
769     // operator^=(uint32)
770     LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
771 
772     // prefix inc
773     LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
774 
775     // prefix dec
776     LLAssert(llong(0,0xffffffff) == --llong(1, 0));
777 
778     // postfix inc
779     {
780         llong n(0, 0xffffffff);
781         LLAssert(llong(0, 0xffffffff) == n++);
782         LLAssert(llong(1, 0) == n);
783     }
784 
785     // postfix dec
786     {
787         llong n(1, 0);
788         LLAssert(llong(1, 0) == n--);
789         LLAssert(llong(0, 0xffffffff) == n);
790     }
791 
792     // unary minus
793     LLAssert(llong(0, 0) == -llong(0, 0));
794     LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
795     LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
796     LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
797     LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
798 
799     // operator-=
800     {
801         llong n;
802         LLAssert((n -= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
803         LLAssert(n == llong(0xffffffff, 0xffffffff));
804 
805         n = llong(1, 0);
806         LLAssert((n -= llong(0, 1)) == llong(0, 0xffffffff));
807         LLAssert(n == llong(0, 0xffffffff));
808     }
809 
810     // operator-
811     {
812         llong n;
813         LLAssert((n - llong(0, 1)) == llong(0xffffffff, 0xffffffff));
814         LLAssert(n == llong(0, 0));
815 
816         n = llong(1, 0);
817         LLAssert((n - llong(0, 1)) == llong(0, 0xffffffff));
818         LLAssert(n == llong(1, 0));
819     }
820 
821     // operator+=
822     {
823         llong n(0xffffffff, 0xffffffff);
824         LLAssert((n += llong(0, 1)) == llong(0, 0));
825         LLAssert(n == llong(0, 0));
826 
827         n = llong(0, 0xffffffff);
828         LLAssert((n += llong(0, 1)) == llong(1, 0));
829         LLAssert(n == llong(1, 0));
830     }
831 
832     // operator+
833     {
834         llong n(0xffffffff, 0xffffffff);
835         LLAssert((n + llong(0, 1)) == llong(0, 0));
836         LLAssert(n == llong(0xffffffff, 0xffffffff));
837 
838         n = llong(0, 0xffffffff);
839         LLAssert((n + llong(0, 1)) == llong(1, 0));
840         LLAssert(n == llong(0, 0xffffffff));
841     }
842 
843 }
844 
845 void IntlTestRBNF::TestLLong()
846 {
847     logln("Starting TestLLong");
848 
849     TestLLongConstructors();
850 
851     TestLLongSimpleOperators();
852 
853     logln("Testing operator*=, operator*");
854 
855     // operator*=, operator*
856     // small and large values, positive, &NEGative, zero
857     // also test commutivity
858     {
859         const llong ZERO;
860         const llong ONE(0, 1);
861         const llong NEG_ONE((int32_t)-1);
862         const llong THREE(0, 3);
863         const llong NEG_THREE((int32_t)-3);
864         const llong TWO_TO_16(0, 0x10000);
865         const llong NEG_TWO_TO_16 = -TWO_TO_16;
866         const llong TWO_TO_32(1, 0);
867         const llong NEG_TWO_TO_32 = -TWO_TO_32;
868 
869         const llong NINE(0, 9);
870         const llong NEG_NINE = -NINE;
871 
872         const llong TWO_TO_16X3(0, 0x00030000);
873         const llong NEG_TWO_TO_16X3 = -TWO_TO_16X3;
874 
875         const llong TWO_TO_32X3(3, 0);
876         const llong NEG_TWO_TO_32X3 = -TWO_TO_32X3;
877 
878         const llong TWO_TO_48(0x10000, 0);
879         const llong NEG_TWO_TO_48 = -TWO_TO_48;
880 
881         const int32_t VALUE_WIDTH = 9;
882         const llong* values[VALUE_WIDTH] = {
883             &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32
884         };
885 
886         const llong* answers[VALUE_WIDTH*VALUE_WIDTH] = {
887             &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO,
888             &ZERO, &ONE,  &NEG_ONE, &THREE, &NEG_THREE,  &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32,
889             &ZERO, &NEG_ONE, &ONE, &NEG_THREE, &THREE, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_32, &TWO_TO_32,
890             &ZERO, &THREE, &NEG_THREE, &NINE, &NEG_NINE, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32X3, &NEG_TWO_TO_32X3,
891             &ZERO, &NEG_THREE, &THREE, &NEG_NINE, &NINE, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32X3, &TWO_TO_32X3,
892             &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,
893             &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,
894             &ZERO, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_32X3, &NEG_TWO_TO_32X3, &TWO_TO_48, &NEG_TWO_TO_48, &ZERO, &ZERO,
895             &ZERO, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_32X3, &TWO_TO_32X3, &NEG_TWO_TO_48, &TWO_TO_48, &ZERO, &ZERO
896         };
897 
898         for (int i = 0; i < VALUE_WIDTH; ++i) {
899             for (int j = 0; j < VALUE_WIDTH; ++j) {
900                 llong lhs = *values[i];
901                 llong rhs = *values[j];
902                 llong ans = *answers[i*VALUE_WIDTH + j];
903 
904                 llong n = lhs;
905 
906                 LLAssert((n *= rhs) == ans);
907                 LLAssert(n == ans);
908 
909                 n = lhs;
910                 LLAssert((n * rhs) == ans);
911                 LLAssert(n == lhs);
912             }
913         }
914     }
915 
916     logln("Testing operator/=, operator/");
917     // operator/=, operator/
918     // test num = 0, div = 0, pos/neg, > 2^32, div > num
919     {
920         const llong ZERO;
921         const llong ONE(0, 1);
922         const llong NEG_ONE = -ONE;
923         const llong MAX(0x7fffffff, 0xffffffff);
924         const llong MIN(0x80000000, 0);
925         const llong TWO(0, 2);
926         const llong NEG_TWO = -TWO;
927         const llong FIVE(0, 5);
928         const llong NEG_FIVE = -FIVE;
929         const llong TWO_TO_32(1, 0);
930         const llong NEG_TWO_TO_32 = -TWO_TO_32;
931         const llong TWO_TO_32d5 = llong(TWO_TO_32.asDouble()/5.0);
932         const llong NEG_TWO_TO_32d5 = -TWO_TO_32d5;
933         const llong TWO_TO_32X5 = TWO_TO_32 * FIVE;
934         const llong NEG_TWO_TO_32X5 = -TWO_TO_32X5;
935 
936         const llong* tuples[] = { // lhs, rhs, ans
937             &ZERO, &ZERO, &ZERO,
938             &ONE, &ZERO,&MAX,
939             &NEG_ONE, &ZERO, &MIN,
940             &ONE, &ONE, &ONE,
941             &ONE, &NEG_ONE, &NEG_ONE,
942             &NEG_ONE, &ONE, &NEG_ONE,
943             &NEG_ONE, &NEG_ONE, &ONE,
944             &FIVE, &TWO, &TWO,
945             &FIVE, &NEG_TWO, &NEG_TWO,
946             &NEG_FIVE, &TWO, &NEG_TWO,
947             &NEG_FIVE, &NEG_TWO, &TWO,
948             &TWO, &FIVE, &ZERO,
949             &TWO, &NEG_FIVE, &ZERO,
950             &NEG_TWO, &FIVE, &ZERO,
951             &NEG_TWO, &NEG_FIVE, &ZERO,
952             &TWO_TO_32, &TWO_TO_32, &ONE,
953             &TWO_TO_32, &NEG_TWO_TO_32, &NEG_ONE,
954             &NEG_TWO_TO_32, &TWO_TO_32, &NEG_ONE,
955             &NEG_TWO_TO_32, &NEG_TWO_TO_32, &ONE,
956             &TWO_TO_32, &FIVE, &TWO_TO_32d5,
957             &TWO_TO_32, &NEG_FIVE, &NEG_TWO_TO_32d5,
958             &NEG_TWO_TO_32, &FIVE, &NEG_TWO_TO_32d5,
959             &NEG_TWO_TO_32, &NEG_FIVE, &TWO_TO_32d5,
960             &TWO_TO_32X5, &FIVE, &TWO_TO_32,
961             &TWO_TO_32X5, &NEG_FIVE, &NEG_TWO_TO_32,
962             &NEG_TWO_TO_32X5, &FIVE, &NEG_TWO_TO_32,
963             &NEG_TWO_TO_32X5, &NEG_FIVE, &TWO_TO_32,
964             &TWO_TO_32X5, &TWO_TO_32, &FIVE,
965             &TWO_TO_32X5, &NEG_TWO_TO_32, &NEG_FIVE,
966             &NEG_TWO_TO_32X5, &NEG_TWO_TO_32, &FIVE,
967             &NEG_TWO_TO_32X5, &TWO_TO_32, &NEG_FIVE
968         };
969         const int TUPLE_WIDTH = 3;
970         const int TUPLE_COUNT = UPRV_LENGTHOF(tuples)/TUPLE_WIDTH;
971         for (int i = 0; i < TUPLE_COUNT; ++i) {
972             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
973             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
974             const llong ans = *tuples[i*TUPLE_WIDTH+2];
975 
976             llong n = lhs;
977             if (!((n /= rhs) == ans)) {
978                 errln("fail: (n /= rhs) == ans");
979             }
980             LLAssert(n == ans);
981 
982             n = lhs;
983             LLAssert((n / rhs) == ans);
984             LLAssert(n == lhs);
985         }
986     }
987 
988     logln("Testing operator%%=, operator%%");
989     //operator%=, operator%
990     {
991         const llong ZERO;
992         const llong ONE(0, 1);
993         const llong TWO(0, 2);
994         const llong THREE(0,3);
995         const llong FOUR(0, 4);
996         const llong FIVE(0, 5);
997         const llong SIX(0, 6);
998 
999         const llong NEG_ONE = -ONE;
1000         const llong NEG_TWO = -TWO;
1001         const llong NEG_THREE = -THREE;
1002         const llong NEG_FOUR = -FOUR;
1003         const llong NEG_FIVE = -FIVE;
1004         const llong NEG_SIX = -SIX;
1005 
1006         const llong NINETY_NINE(0, 99);
1007         const llong HUNDRED(0, 100);
1008         const llong HUNDRED_ONE(0, 101);
1009 
1010         const llong BIG(0x12345678, 0x9abcdef0);
1011         const llong BIG_FIVE(BIG * FIVE);
1012         const llong BIG_FIVEm1 = BIG_FIVE - ONE;
1013         const llong BIG_FIVEp1 = BIG_FIVE + ONE;
1014 
1015         const llong* tuples[] = {
1016             &ZERO, &FIVE, &ZERO,
1017             &ONE, &FIVE, &ONE,
1018             &TWO, &FIVE, &TWO,
1019             &THREE, &FIVE, &THREE,
1020             &FOUR, &FIVE, &FOUR,
1021             &FIVE, &FIVE, &ZERO,
1022             &SIX, &FIVE, &ONE,
1023             &ZERO, &NEG_FIVE, &ZERO,
1024             &ONE, &NEG_FIVE, &ONE,
1025             &TWO, &NEG_FIVE, &TWO,
1026             &THREE, &NEG_FIVE, &THREE,
1027             &FOUR, &NEG_FIVE, &FOUR,
1028             &FIVE, &NEG_FIVE, &ZERO,
1029             &SIX, &NEG_FIVE, &ONE,
1030             &NEG_ONE, &FIVE, &NEG_ONE,
1031             &NEG_TWO, &FIVE, &NEG_TWO,
1032             &NEG_THREE, &FIVE, &NEG_THREE,
1033             &NEG_FOUR, &FIVE, &NEG_FOUR,
1034             &NEG_FIVE, &FIVE, &ZERO,
1035             &NEG_SIX, &FIVE, &NEG_ONE,
1036             &NEG_ONE, &NEG_FIVE, &NEG_ONE,
1037             &NEG_TWO, &NEG_FIVE, &NEG_TWO,
1038             &NEG_THREE, &NEG_FIVE, &NEG_THREE,
1039             &NEG_FOUR, &NEG_FIVE, &NEG_FOUR,
1040             &NEG_FIVE, &NEG_FIVE, &ZERO,
1041             &NEG_SIX, &NEG_FIVE, &NEG_ONE,
1042             &NINETY_NINE, &FIVE, &FOUR,
1043             &HUNDRED, &FIVE, &ZERO,
1044             &HUNDRED_ONE, &FIVE, &ONE,
1045             &BIG_FIVEm1, &FIVE, &FOUR,
1046             &BIG_FIVE, &FIVE, &ZERO,
1047             &BIG_FIVEp1, &FIVE, &ONE
1048         };
1049         const int TUPLE_WIDTH = 3;
1050         const int TUPLE_COUNT = UPRV_LENGTHOF(tuples)/TUPLE_WIDTH;
1051         for (int i = 0; i < TUPLE_COUNT; ++i) {
1052             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
1053             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
1054             const llong ans = *tuples[i*TUPLE_WIDTH+2];
1055 
1056             llong n = lhs;
1057             if (!((n %= rhs) == ans)) {
1058                 errln("fail: (n %= rhs) == ans");
1059             }
1060             LLAssert(n == ans);
1061 
1062             n = lhs;
1063             LLAssert((n % rhs) == ans);
1064             LLAssert(n == lhs);
1065         }
1066     }
1067 
1068     logln("Testing pow");
1069     // pow
1070     LLAssert(llong(0, 0).pow(0) == llong(0, 0));
1071     LLAssert(llong(0, 0).pow(2) == llong(0, 0));
1072     LLAssert(llong(0, 2).pow(0) == llong(0, 1));
1073     LLAssert(llong(0, 2).pow(2) == llong(0, 4));
1074     LLAssert(llong(0, 2).pow(32) == llong(1, 0));
1075     LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
1076 
1077     // absolute value
1078     {
1079         const llong n(0xffffffff,0xffffffff);
1080         LLAssert(n.abs() == llong(0, 1));
1081     }
1082 
1083 #ifdef RBNF_DEBUG
1084     logln("Testing atoll");
1085     // atoll
1086     const char empty[] = "";
1087     const char zero[] = "0";
1088     const char neg_one[] = "-1";
1089     const char neg_12345[] = "-12345";
1090     const char big1[] = "123456789abcdef0";
1091     const char big2[] = "fFfFfFfFfFfFfFfF";
1092     LLAssert(llong::atoll(empty) == llong(0, 0));
1093     LLAssert(llong::atoll(zero) == llong(0, 0));
1094     LLAssert(llong::atoll(neg_one) == llong(0xffffffff, 0xffffffff));
1095     LLAssert(llong::atoll(neg_12345) == -llong(0, 12345));
1096     LLAssert(llong::atoll(big1, 16) == llong(0x12345678, 0x9abcdef0));
1097     LLAssert(llong::atoll(big2, 16) == llong(0xffffffff, 0xffffffff));
1098 #endif
1099 
1100     // u_atoll
1101     const UChar uempty[] = { 0 };
1102     const UChar uzero[] = { 0x30, 0 };
1103     const UChar uneg_one[] = { 0x2d, 0x31, 0 };
1104     const UChar uneg_12345[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1105     const UChar ubig1[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1106     const UChar ubig2[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1107     LLAssert(llong::utoll(uempty) == llong(0, 0));
1108     LLAssert(llong::utoll(uzero) == llong(0, 0));
1109     LLAssert(llong::utoll(uneg_one) == llong(0xffffffff, 0xffffffff));
1110     LLAssert(llong::utoll(uneg_12345) == -llong(0, 12345));
1111     LLAssert(llong::utoll(ubig1, 16) == llong(0x12345678, 0x9abcdef0));
1112     LLAssert(llong::utoll(ubig2, 16) == llong(0xffffffff, 0xffffffff));
1113 
1114 #ifdef RBNF_DEBUG
1115     logln("Testing lltoa");
1116     // lltoa
1117     {
1118         char buf[64]; // ascii
1119         LLAssert((llong(0, 0).lltoa(buf, (uint32_t)sizeof(buf)) == 1) && (strcmp(buf, zero) == 0));
1120         LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf, (uint32_t)sizeof(buf)) == 2) && (strcmp(buf, neg_one) == 0));
1121         LLAssert(((-llong(0, 12345)).lltoa(buf, (uint32_t)sizeof(buf)) == 6) && (strcmp(buf, neg_12345) == 0));
1122         LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf, (uint32_t)sizeof(buf), 16) == 16) && (strcmp(buf, big1) == 0));
1123     }
1124 #endif
1125 
1126     logln("Testing u_lltoa");
1127     // u_lltoa
1128     {
1129         UChar buf[64];
1130         LLAssert((llong(0, 0).lltou(buf, (uint32_t)sizeof(buf)) == 1) && (u_strcmp(buf, uzero) == 0));
1131         LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf, (uint32_t)sizeof(buf)) == 2) && (u_strcmp(buf, uneg_one) == 0));
1132         LLAssert(((-llong(0, 12345)).lltou(buf, (uint32_t)sizeof(buf)) == 6) && (u_strcmp(buf, uneg_12345) == 0));
1133         LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf, (uint32_t)sizeof(buf), 16) == 16) && (u_strcmp(buf, ubig1) == 0));
1134     }
1135 }
1136 
1137 /* if 0 */
1138 #endif
1139 
1140 void
TestEnglishSpellout()1141 IntlTestRBNF::TestEnglishSpellout()
1142 {
1143     UErrorCode status = U_ZERO_ERROR;
1144     RuleBasedNumberFormat* formatter
1145         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
1146     if (U_FAILURE(status)) {
1147         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1148     } else {
1149         static const char* const testData[][2] = {
1150             { "1", "one" },
1151             { "2", "two" },
1152             { "15", "fifteen" },
1153             { "20", "twenty" },
1154             { "23", "twenty-three" },
1155             { "73", "seventy-three" },
1156             { "88", "eighty-eight" },
1157             { "100", "one hundred" },
1158             { "106", "one hundred six" },
1159             { "127", "one hundred twenty-seven" },
1160             { "200", "two hundred" },
1161             { "579", "five hundred seventy-nine" },
1162             { "1,000", "one thousand" },
1163             { "2,000", "two thousand" },
1164             { "3,004", "three thousand four" },
1165             { "4,567", "four thousand five hundred sixty-seven" },
1166             { "15,943", "fifteen thousand nine hundred forty-three" },
1167             { "2,345,678", "two million three hundred forty-five thousand six hundred seventy-eight" },
1168             { "-36", "minus thirty-six" },
1169             { "234.567", "two hundred thirty-four point five six seven" },
1170             { NULL, NULL}
1171         };
1172 
1173         doTest(formatter, testData, TRUE);
1174 
1175 #if !UCONFIG_NO_COLLATION
1176         formatter->setLenient(TRUE);
1177         static const char* lpTestData[][2] = {
1178             { "fifty-7", "57" },
1179             { " fifty-7", "57" },
1180             { "  fifty-7", "57" },
1181             { "2 thousand six    HUNDRED fifty-7", "2,657" },
1182             { "fifteen hundred and zero", "1,500" },
1183             { "FOurhundred     thiRTY six", "436" },
1184             { NULL, NULL}
1185         };
1186         doLenientParseTest(formatter, lpTestData);
1187 #endif
1188     }
1189     delete formatter;
1190 }
1191 
1192 void
TestOrdinalAbbreviations()1193 IntlTestRBNF::TestOrdinalAbbreviations()
1194 {
1195     UErrorCode status = U_ZERO_ERROR;
1196     RuleBasedNumberFormat* formatter
1197         = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale::getUS(), status);
1198 
1199     if (U_FAILURE(status)) {
1200         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1201     } else {
1202         static const char* const testData[][2] = {
1203             { "1", "1st" },
1204             { "2", "2nd" },
1205             { "3", "3rd" },
1206             { "4", "4th" },
1207             { "7", "7th" },
1208             { "10", "10th" },
1209             { "11", "11th" },
1210             { "13", "13th" },
1211             { "20", "20th" },
1212             { "21", "21st" },
1213             { "22", "22nd" },
1214             { "23", "23rd" },
1215             { "24", "24th" },
1216             { "33", "33rd" },
1217             { "102", "102nd" },
1218             { "312", "312th" },
1219             { "12,345", "12,345th" },
1220             { NULL, NULL}
1221         };
1222 
1223         doTest(formatter, testData, FALSE);
1224     }
1225     delete formatter;
1226 }
1227 
1228 void
TestDurations()1229 IntlTestRBNF::TestDurations()
1230 {
1231     UErrorCode status = U_ZERO_ERROR;
1232     RuleBasedNumberFormat* formatter
1233         = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status);
1234 
1235     if (U_FAILURE(status)) {
1236         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1237     } else {
1238         static const char* const testData[][2] = {
1239             { "3,600", "1:00:00" },     //move me and I fail
1240             { "0", "0 sec." },
1241             { "1", "1 sec." },
1242             { "24", "24 sec." },
1243             { "60", "1:00" },
1244             { "73", "1:13" },
1245             { "145", "2:25" },
1246             { "666", "11:06" },
1247             //            { "3,600", "1:00:00" },
1248             { "3,740", "1:02:20" },
1249             { "10,293", "2:51:33" },
1250             { NULL, NULL}
1251         };
1252 
1253         doTest(formatter, testData, TRUE);
1254 
1255 #if !UCONFIG_NO_COLLATION
1256         formatter->setLenient(TRUE);
1257         static const char* lpTestData[][2] = {
1258             { "2-51-33", "10,293" },
1259             { NULL, NULL}
1260         };
1261         doLenientParseTest(formatter, lpTestData);
1262 #endif
1263     }
1264     delete formatter;
1265 }
1266 
1267 void
TestSpanishSpellout()1268 IntlTestRBNF::TestSpanishSpellout()
1269 {
1270     UErrorCode status = U_ZERO_ERROR;
1271     RuleBasedNumberFormat* formatter
1272         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
1273 
1274     if (U_FAILURE(status)) {
1275         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1276     } else {
1277         static const char* const testData[][2] = {
1278             { "1", "uno" },
1279             { "6", "seis" },
1280             { "16", "diecis\\u00e9is" },
1281             { "20", "veinte" },
1282             { "24", "veinticuatro" },
1283             { "26", "veintis\\u00e9is" },
1284             { "73", "setenta y tres" },
1285             { "88", "ochenta y ocho" },
1286             { "100", "cien" },
1287             { "106", "ciento seis" },
1288             { "127", "ciento veintisiete" },
1289             { "200", "doscientos" },
1290             { "579", "quinientos setenta y nueve" },
1291             { "1,000", "mil" },
1292             { "2,000", "dos mil" },
1293             { "3,004", "tres mil cuatro" },
1294             { "4,567", "cuatro mil quinientos sesenta y siete" },
1295             { "15,943", "quince mil novecientos cuarenta y tres" },
1296             { "2,345,678", "dos millones trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1297             { "-36", "menos treinta y seis" },
1298             { "234.567", "doscientos treinta y cuatro coma cinco seis siete" },
1299             { NULL, NULL}
1300         };
1301 
1302         doTest(formatter, testData, TRUE);
1303     }
1304     delete formatter;
1305 }
1306 
1307 void
TestFrenchSpellout()1308 IntlTestRBNF::TestFrenchSpellout()
1309 {
1310     UErrorCode status = U_ZERO_ERROR;
1311     RuleBasedNumberFormat* formatter
1312         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status);
1313 
1314     if (U_FAILURE(status)) {
1315         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1316     } else {
1317         static const char* const testData[][2] = {
1318             { "1", "un" },
1319             { "15", "quinze" },
1320             { "20", "vingt" },
1321             { "21", "vingt-et-un" },
1322             { "23", "vingt-trois" },
1323             { "62", "soixante-deux" },
1324             { "70", "soixante-dix" },
1325             { "71", "soixante-et-onze" },
1326             { "73", "soixante-treize" },
1327             { "80", "quatre-vingts" },
1328             { "88", "quatre-vingt-huit" },
1329             { "100", "cent" },
1330             { "106", "cent six" },
1331             { "127", "cent vingt-sept" },
1332             { "200", "deux cents" },
1333             { "579", "cinq cent soixante-dix-neuf" },
1334             { "1,000", "mille" },
1335             { "1,123", "mille cent vingt-trois" },
1336             { "1,594", "mille cinq cent quatre-vingt-quatorze" },
1337             { "2,000", "deux mille" },
1338             { "3,004", "trois mille quatre" },
1339             { "4,567", "quatre mille cinq cent soixante-sept" },
1340             { "15,943", "quinze mille neuf cent quarante-trois" },
1341             { "2,345,678", "deux millions trois cent quarante-cinq mille six cent soixante-dix-huit" },
1342             { "-36", "moins trente-six" },
1343             { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1344             { NULL, NULL}
1345         };
1346 
1347         doTest(formatter, testData, TRUE);
1348 
1349 #if !UCONFIG_NO_COLLATION
1350         formatter->setLenient(TRUE);
1351         static const char* lpTestData[][2] = {
1352             { "trente-et-un", "31" },
1353             { "un cent quatre vingt dix huit", "198" },
1354             { NULL, NULL}
1355         };
1356         doLenientParseTest(formatter, lpTestData);
1357 #endif
1358     }
1359     delete formatter;
1360 }
1361 
1362 static const char* const swissFrenchTestData[][2] = {
1363     { "1", "un" },
1364     { "15", "quinze" },
1365     { "20", "vingt" },
1366     { "21", "vingt-et-un" },
1367     { "23", "vingt-trois" },
1368     { "62", "soixante-deux" },
1369     { "70", "septante" },
1370     { "71", "septante-et-un" },
1371     { "73", "septante-trois" },
1372     { "80", "huitante" },
1373     { "88", "huitante-huit" },
1374     { "100", "cent" },
1375     { "106", "cent six" },
1376     { "127", "cent vingt-sept" },
1377     { "200", "deux cents" },
1378     { "579", "cinq cent septante-neuf" },
1379     { "1,000", "mille" },
1380     { "1,123", "mille cent vingt-trois" },
1381     { "1,594", "mille cinq cent nonante-quatre" },
1382     { "2,000", "deux mille" },
1383     { "3,004", "trois mille quatre" },
1384     { "4,567", "quatre mille cinq cent soixante-sept" },
1385     { "15,943", "quinze mille neuf cent quarante-trois" },
1386     { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1387     { "-36", "moins trente-six" },
1388     { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1389     { NULL, NULL}
1390 };
1391 
1392 void
TestSwissFrenchSpellout()1393 IntlTestRBNF::TestSwissFrenchSpellout()
1394 {
1395     UErrorCode status = U_ZERO_ERROR;
1396     RuleBasedNumberFormat* formatter
1397         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH", ""), status);
1398 
1399     if (U_FAILURE(status)) {
1400         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1401     } else {
1402         doTest(formatter, swissFrenchTestData, TRUE);
1403     }
1404     delete formatter;
1405 }
1406 
1407 static const char* const belgianFrenchTestData[][2] = {
1408     { "1", "un" },
1409     { "15", "quinze" },
1410     { "20", "vingt" },
1411     { "21", "vingt-et-un" },
1412     { "23", "vingt-trois" },
1413     { "62", "soixante-deux" },
1414     { "70", "septante" },
1415     { "71", "septante-et-un" },
1416     { "73", "septante-trois" },
1417     { "80", "quatre-vingts" },
1418     { "88", "quatre-vingt huit" },
1419     { "90", "nonante" },
1420     { "91", "nonante-et-un" },
1421     { "95", "nonante-cinq" },
1422     { "100", "cent" },
1423     { "106", "cent six" },
1424     { "127", "cent vingt-sept" },
1425     { "200", "deux cents" },
1426     { "579", "cinq cent septante-neuf" },
1427     { "1,000", "mille" },
1428     { "1,123", "mille cent vingt-trois" },
1429     { "1,594", "mille cinq cent nonante-quatre" },
1430     { "2,000", "deux mille" },
1431     { "3,004", "trois mille quatre" },
1432     { "4,567", "quatre mille cinq cent soixante-sept" },
1433     { "15,943", "quinze mille neuf cent quarante-trois" },
1434     { "2,345,678", "deux millions trois cent quarante-cinq mille six cent septante-huit" },
1435     { "-36", "moins trente-six" },
1436     { "234.567", "deux cent trente-quatre virgule cinq six sept" },
1437     { NULL, NULL}
1438 };
1439 
1440 
1441 void
TestBelgianFrenchSpellout()1442 IntlTestRBNF::TestBelgianFrenchSpellout()
1443 {
1444     UErrorCode status = U_ZERO_ERROR;
1445     RuleBasedNumberFormat* formatter
1446         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "BE", ""), status);
1447 
1448     if (U_FAILURE(status)) {
1449         errcheckln(status, "rbnf status: 0x%x (%s)\n", status, u_errorName(status));
1450         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1451     } else {
1452         // Belgian french should match Swiss french.
1453         doTest(formatter, belgianFrenchTestData, TRUE);
1454     }
1455     delete formatter;
1456 }
1457 
1458 void
TestItalianSpellout()1459 IntlTestRBNF::TestItalianSpellout()
1460 {
1461     UErrorCode status = U_ZERO_ERROR;
1462     RuleBasedNumberFormat* formatter
1463         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status);
1464 
1465     if (U_FAILURE(status)) {
1466         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1467     } else {
1468         static const char* const testData[][2] = {
1469             { "1", "uno" },
1470             { "15", "quindici" },
1471             { "20", "venti" },
1472             { "23", "venti\\u00ADtr\\u00E9" },
1473             { "73", "settanta\\u00ADtr\\u00E9" },
1474             { "88", "ottant\\u00ADotto" },
1475             { "100", "cento" },
1476             { "101", "cento\\u00ADuno" },
1477             { "103", "cento\\u00ADtr\\u00E9" },
1478             { "106", "cento\\u00ADsei" },
1479             { "108", "cent\\u00ADotto" },
1480             { "127", "cento\\u00ADventi\\u00ADsette" },
1481             { "181", "cent\\u00ADottant\\u00ADuno" },
1482             { "200", "due\\u00ADcento" },
1483             { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" },
1484             { "1,000", "mille" },
1485             { "2,000", "due\\u00ADmila" },
1486             { "3,004", "tre\\u00ADmila\\u00ADquattro" },
1487             { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessanta\\u00ADsette" },
1488             { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaranta\\u00ADtr\\u00E9" },
1489             { "-36", "meno trenta\\u00ADsei" },
1490             { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cinque sei sette" },
1491             { NULL, NULL}
1492         };
1493 
1494         doTest(formatter, testData, TRUE);
1495     }
1496     delete formatter;
1497 }
1498 
1499 void
TestPortugueseSpellout()1500 IntlTestRBNF::TestPortugueseSpellout()
1501 {
1502     UErrorCode status = U_ZERO_ERROR;
1503     RuleBasedNumberFormat* formatter
1504         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("pt","BR",""), status);
1505 
1506     if (U_FAILURE(status)) {
1507         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1508     } else {
1509         static const char* const testData[][2] = {
1510             { "1", "um" },
1511             { "15", "quinze" },
1512             { "20", "vinte" },
1513             { "23", "vinte e tr\\u00EAs" },
1514             { "73", "setenta e tr\\u00EAs" },
1515             { "88", "oitenta e oito" },
1516             { "100", "cem" },
1517             { "106", "cento e seis" },
1518             { "108", "cento e oito" },
1519             { "127", "cento e vinte e sete" },
1520             { "181", "cento e oitenta e um" },
1521             { "200", "duzentos" },
1522             { "579", "quinhentos e setenta e nove" },
1523             { "1,000", "mil" },
1524             { "2,000", "dois mil" },
1525             { "3,004", "tr\\u00EAs mil e quatro" },
1526             { "4,567", "quatro mil quinhentos e sessenta e sete" },
1527             { "15,943", "quinze mil novecentos e quarenta e tr\\u00EAs" },
1528             { "-36", "menos trinta e seis" },
1529             { "234.567", "duzentos e trinta e quatro v\\u00EDrgula cinco seis sete" },
1530             { NULL, NULL}
1531         };
1532 
1533         doTest(formatter, testData, TRUE);
1534     }
1535     delete formatter;
1536 }
1537 void
TestGermanSpellout()1538 IntlTestRBNF::TestGermanSpellout()
1539 {
1540     UErrorCode status = U_ZERO_ERROR;
1541     RuleBasedNumberFormat* formatter
1542         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status);
1543 
1544     if (U_FAILURE(status)) {
1545         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1546     } else {
1547         static const char* const testData[][2] = {
1548             { "1", "eins" },
1549             { "15", "f\\u00fcnfzehn" },
1550             { "20", "zwanzig" },
1551             { "23", "drei\\u00ADund\\u00ADzwanzig" },
1552             { "73", "drei\\u00ADund\\u00ADsiebzig" },
1553             { "88", "acht\\u00ADund\\u00ADachtzig" },
1554             { "100", "ein\\u00ADhundert" },
1555             { "106", "ein\\u00ADhundert\\u00ADsechs" },
1556             { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" },
1557             { "200", "zwei\\u00ADhundert" },
1558             { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzig" },
1559             { "1,000", "ein\\u00ADtausend" },
1560             { "2,000", "zwei\\u00ADtausend" },
1561             { "3,004", "drei\\u00ADtausend\\u00ADvier" },
1562             { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADsechzig" },
1563             { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\u00ADdrei\\u00ADund\\u00ADvierzig" },
1564             { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00ADund\\u00ADsiebzig" },
1565             { NULL, NULL}
1566         };
1567 
1568         doTest(formatter, testData, TRUE);
1569 
1570 #if !UCONFIG_NO_COLLATION
1571         formatter->setLenient(TRUE);
1572         static const char* lpTestData[][2] = {
1573             { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1574             { NULL, NULL}
1575         };
1576         doLenientParseTest(formatter, lpTestData);
1577 #endif
1578     }
1579     delete formatter;
1580 }
1581 
1582 void
TestThaiSpellout()1583 IntlTestRBNF::TestThaiSpellout()
1584 {
1585     UErrorCode status = U_ZERO_ERROR;
1586     RuleBasedNumberFormat* formatter
1587         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("th"), status);
1588 
1589     if (U_FAILURE(status)) {
1590         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1591     } else {
1592         static const char* const testData[][2] = {
1593             { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1594             { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1595             { "10", "\\u0e2a\\u0e34\\u0e1a" },
1596             { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1597             { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1598             { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1599             { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1600             { NULL, NULL}
1601         };
1602 
1603         doTest(formatter, testData, TRUE);
1604     }
1605     delete formatter;
1606 }
1607 
1608 void
TestNorwegianSpellout()1609 IntlTestRBNF::TestNorwegianSpellout()
1610 {
1611     UErrorCode status = U_ZERO_ERROR;
1612     RuleBasedNumberFormat* noFormatter
1613         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("no"), status);
1614     RuleBasedNumberFormat* nbFormatter
1615         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("nb"), status);
1616 
1617     if (U_FAILURE(status)) {
1618         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1619     } else {
1620         static const char* testDataDefault[][2] = {
1621             { "1", "\\u00E9n" },
1622             { "2", "to" },
1623             { "3", "tre" },
1624             { "4", "fire" },
1625             { "101", "hundre og \\u00E9n" },
1626             { "123", "hundre og tjue\\u00ADtre" },
1627             { "1,001", "tusen og \\u00E9n" },
1628             { "1,100", "tusen hundre" },
1629             { "6.789", "seks komma sju \\u00E5tte ni" },
1630             { "-5.678", "minus fem komma seks sju \\u00E5tte" },
1631             { NULL, NULL }
1632         };
1633         doTest(noFormatter, testDataDefault, TRUE);
1634         doTest(nbFormatter, testDataDefault, TRUE);
1635     }
1636     delete nbFormatter;
1637     delete noFormatter;
1638 }
1639 
1640 void
TestSwedishSpellout()1641 IntlTestRBNF::TestSwedishSpellout()
1642 {
1643     UErrorCode status = U_ZERO_ERROR;
1644     RuleBasedNumberFormat* formatter
1645         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv"), status);
1646 
1647     if (U_FAILURE(status)) {
1648         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1649     } else {
1650         static const char* testDataDefault[][2] = {
1651             { "101", "ett\\u00adhundra\\u00adett" },
1652             { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" },
1653             { "1,001", "et\\u00adtusen ett" },
1654             { "1,100", "et\\u00adtusen ett\\u00adhundra" },
1655             { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1656             { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00adfyra" },
1657             { "10,001", "tio\\u00adtusen ett" },
1658             { "11,000", "elva\\u00adtusen" },
1659             { "12,000", "tolv\\u00adtusen" },
1660             { "20,000", "tjugo\\u00adtusen" },
1661             { "21,000", "tjugo\\u00adet\\u00adtusen" },
1662             { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1663             { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" },
1664             { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" },
1665             { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhundra" },
1666             { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1667             { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adfem\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" },
1668             { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" },
1669             { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrtio\\u00adfem komma sex sju \\u00e5tta" },
1670             { NULL, NULL }
1671         };
1672         doTest(formatter, testDataDefault, TRUE);
1673 
1674           static const char* testDataNeutrum[][2] = {
1675               { "101", "ett\\u00adhundra\\u00adett" },
1676               { "1,001", "et\\u00adtusen ett" },
1677               { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1678               { "10,001", "tio\\u00adtusen ett" },
1679               { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1680               { NULL, NULL }
1681           };
1682 
1683           formatter->setDefaultRuleSet("%spellout-cardinal-neuter", status);
1684           if (U_SUCCESS(status)) {
1685           logln("        testing spellout-cardinal-neuter rules");
1686           doTest(formatter, testDataNeutrum, TRUE);
1687           }
1688           else {
1689           errln("Can't test spellout-cardinal-neuter rules");
1690           }
1691 
1692         static const char* testDataYear[][2] = {
1693             { "101", "ett\\u00adhundra\\u00adett" },
1694             { "900", "nio\\u00adhundra" },
1695             { "1,001", "et\\u00adtusen ett" },
1696             { "1,100", "elva\\u00adhundra" },
1697             { "1,101", "elva\\u00adhundra\\u00adett" },
1698             { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" },
1699             { "2,001", "tjugo\\u00adhundra\\u00adett" },
1700             { "10,001", "tio\\u00adtusen ett" },
1701             { NULL, NULL }
1702         };
1703 
1704         status = U_ZERO_ERROR;
1705         formatter->setDefaultRuleSet("%spellout-numbering-year", status);
1706         if (U_SUCCESS(status)) {
1707             logln("testing year rules");
1708             doTest(formatter, testDataYear, TRUE);
1709         }
1710         else {
1711             errln("Can't test year rules");
1712         }
1713 
1714     }
1715     delete formatter;
1716 }
1717 
1718 void
TestSmallValues()1719 IntlTestRBNF::TestSmallValues()
1720 {
1721     UErrorCode status = U_ZERO_ERROR;
1722     RuleBasedNumberFormat* formatter
1723         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("en_US"), status);
1724 
1725     if (U_FAILURE(status)) {
1726         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1727     } else {
1728         static const char* const testDataDefault[][2] = {
1729         { "0.001", "zero point zero zero one" },
1730         { "0.0001", "zero point zero zero zero one" },
1731         { "0.00001", "zero point zero zero zero zero one" },
1732         { "0.000001", "zero point zero zero zero zero zero one" },
1733         { "0.0000001", "zero point zero zero zero zero zero zero one" },
1734         { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1735         { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1736         { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1737         { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1738         { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1739         { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1740         { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1741         { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1742         { "10,000,000.001", "ten million point zero zero one" },
1743         { "10,000,000.0001", "ten million point zero zero zero one" },
1744         { "10,000,000.00001", "ten million point zero zero zero zero one" },
1745         { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1746         { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1747 //        { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1748 //        { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1749         { "10,000,000", "ten million" },
1750 //        { "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" },
1751 //        { "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" },
1752 //        { "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" },
1753         { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
1754         { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
1755         { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
1756         { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
1757         { "123.321", "one hundred twenty-three point three two one" },
1758         { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1759         { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1760         { NULL, NULL }
1761         };
1762 
1763         doTest(formatter, testDataDefault, TRUE);
1764 
1765         delete formatter;
1766     }
1767 }
1768 
1769 void
TestLocalizations(void)1770 IntlTestRBNF::TestLocalizations(void)
1771 {
1772     int i;
1773     UnicodeString rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1774         "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1775 
1776     UErrorCode status = U_ZERO_ERROR;
1777     UParseError perror;
1778     RuleBasedNumberFormat formatter(rules, perror, status);
1779     if (U_FAILURE(status)) {
1780         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1781     } else {
1782         {
1783             static const char* const testData[][2] = {
1784                 { "0", "nada" },
1785                 { "5", "yah, some" },
1786                 { "423", "plenty" },
1787                 { "12345", "more'n you'll ever need" },
1788                 { NULL, NULL }
1789             };
1790             doTest(&formatter, testData, FALSE);
1791         }
1792 
1793         {
1794             UnicodeString loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1795             static const char* const testData[][2] = {
1796                 { "0", "no" },
1797                 { "5", "some" },
1798                 { "423", "a lot" },
1799                 { "12345", "tons" },
1800                 { NULL, NULL }
1801             };
1802             RuleBasedNumberFormat formatter0(rules, loc, perror, status);
1803             if (U_FAILURE(status)) {
1804                 errln("failed to build second formatter");
1805             } else {
1806                 doTest(&formatter0, testData, FALSE);
1807 
1808                 {
1809                 // exercise localization info
1810                     Locale locale0("en__VALLEY@turkey=gobblegobble");
1811                     Locale locale1("de_DE_FOO");
1812                     Locale locale2("ja_JP");
1813                     UnicodeString name = formatter0.getRuleSetName(0);
1814                     if ( formatter0.getRuleSetDisplayName(0, locale0) == "Main"
1815                       && formatter0.getRuleSetDisplayName(0, locale1) == "das Main"
1816                       && formatter0.getRuleSetDisplayName(0, locale2) == "%main"
1817                       && formatter0.getRuleSetDisplayName(name, locale0) == "Main"
1818                       && formatter0.getRuleSetDisplayName(name, locale1) == "das Main"
1819                       && formatter0.getRuleSetDisplayName(name, locale2) == "%main"){
1820                           logln("getRuleSetDisplayName tested");
1821                     }else {
1822                         errln("failed to getRuleSetDisplayName");
1823                     }
1824                 }
1825 
1826                 for (i = 0; i < formatter0.getNumberOfRuleSetDisplayNameLocales(); ++i) {
1827                     Locale locale = formatter0.getRuleSetDisplayNameLocale(i, status);
1828                     if (U_SUCCESS(status)) {
1829                         for (int j = 0; j < formatter0.getNumberOfRuleSetNames(); ++j) {
1830                             UnicodeString name = formatter0.getRuleSetName(j);
1831                             UnicodeString lname = formatter0.getRuleSetDisplayName(j, locale);
1832                             UnicodeString msg = locale.getName();
1833                             msg.append(": ");
1834                             msg.append(name);
1835                             msg.append(" = ");
1836                             msg.append(lname);
1837                             logln(msg);
1838                         }
1839                     }
1840                 }
1841             }
1842         }
1843 
1844         {
1845             static const char* goodLocs[] = {
1846                 "", // zero-length ok, same as providing no localization data
1847                 "<<>>", // no public rule sets ok
1848                 "<<%main>>", // no localizations ok
1849                 "<<%main,>,<en, Main,>>", // comma before close angle ok
1850                 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1851                 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1852                 "  \n <\n  <\n  %main\n  >\n  , \t <\t   en\t  ,  \tfoo \t\t > \n\n >  \n ", // Pattern_White_Space ok
1853            };
1854             int32_t goodLocsLen = UPRV_LENGTHOF(goodLocs);
1855 
1856             static const char* badLocs[] = {
1857                 " ", // non-zero length
1858                 "<>", // empty array
1859                 "<", // unclosed outer array
1860                 "<<", // unclosed inner array
1861                 "<<,>>", // unexpected comma
1862                 "<<''>>", // empty string
1863                 "  x<<%main>>", // first non space char not open angle bracket
1864                 "<%main>", // missing inner array
1865                 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1866                 "<<%main><en, Main>>", // arrays missing separating comma
1867                 "<<%main>,<en, main, foo>>", // too many elements in locale data
1868                 "<<%main>,<en>>", // too few elements in locale data
1869                 "<<<%main>>>", // unexpected open angle
1870                 "<<%main<>>>", // unexpected open angle
1871                 "<<%main, %other>,<en,,>>", // implicit empty strings
1872                 "<<%main>,<en,''>>", // empty string
1873                 "<<%main>, < en, '>>", // unterminated quote
1874                 "<<%main>, < en, \"<>>", // unterminated quote
1875                 "<<%main\">>", // quote in string
1876                 "<<%main'>>", // quote in string
1877                 "<<%main<>>", // open angle in string
1878                 "<<%main>> x", // extra non-space text at end
1879 
1880             };
1881             int32_t badLocsLen = UPRV_LENGTHOF(badLocs);
1882 
1883             for (i = 0; i < goodLocsLen; ++i) {
1884                 logln("[%d] '%s'", i, goodLocs[i]);
1885                 UErrorCode status = U_ZERO_ERROR;
1886                 UnicodeString loc(goodLocs[i]);
1887                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1888                 if (U_FAILURE(status)) {
1889                     errln("Failed parse of good localization string: '%s'", goodLocs[i]);
1890                 }
1891             }
1892 
1893             for (i = 0; i < badLocsLen; ++i) {
1894                 logln("[%d] '%s'", i, badLocs[i]);
1895                 UErrorCode status = U_ZERO_ERROR;
1896                 UnicodeString loc(badLocs[i]);
1897                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1898                 if (U_SUCCESS(status)) {
1899                     errln("Successful parse of bad localization string: '%s'", badLocs[i]);
1900                 }
1901             }
1902         }
1903     }
1904 }
1905 
1906 void
TestAllLocales()1907 IntlTestRBNF::TestAllLocales()
1908 {
1909     const char* names[] = {
1910         " (spellout) ",
1911         " (ordinal)  "
1912         // " (duration) " // This is English only, and it's not really supported in CLDR anymore.
1913     };
1914     double numbers[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
1915 
1916     int32_t count = 0;
1917     const Locale* locales = Locale::getAvailableLocales(count);
1918     for (int i = 0; i < count; ++i) {
1919         const Locale* loc = &locales[i];
1920 
1921         for (int j = 0; j < 2; ++j) {
1922             UErrorCode status = U_ZERO_ERROR;
1923             RuleBasedNumberFormat* f = new RuleBasedNumberFormat((URBNFRuleSetTag)j, *loc, status);
1924 
1925             if (U_FAILURE(status)) {
1926                 errln(UnicodeString(loc->getName()) + names[j]
1927                     + "ERROR could not instantiate -> " + u_errorName(status));
1928                 continue;
1929             }
1930 
1931             Locale actualLocale = f->getLocale(ULOC_ACTUAL_LOCALE, status);
1932             if (actualLocale != *loc) {
1933                 // Skip the redundancy
1934                 delete f;
1935                 break;
1936             }
1937 
1938 #if !UCONFIG_NO_COLLATION
1939             for (unsigned int numidx = 0; numidx < UPRV_LENGTHOF(numbers); numidx++) {
1940                 double n = numbers[numidx];
1941                 UnicodeString str;
1942                 f->format(n, str);
1943 
1944                 if (verbose) {
1945                     logln(UnicodeString(loc->getName()) + names[j]
1946                         + "success: " + n + " -> " + str);
1947                 }
1948 
1949                 // We do not validate the result in this test case,
1950                 // because there are cases which do not round trip by design.
1951                 Formattable num;
1952 
1953                 // regular parse
1954                 status = U_ZERO_ERROR;
1955                 f->setLenient(FALSE);
1956                 f->parse(str, num, status);
1957                 if (U_FAILURE(status)) {
1958                     errln(UnicodeString(loc->getName()) + names[j]
1959                         + "ERROR could not parse '" + str + "' -> " + u_errorName(status));
1960                 }
1961                 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1962                 if (j == 0) {
1963                     if (num.getType() == Formattable::kLong && num.getLong() != n) {
1964                         errln(UnicodeString(loc->getName()) + names[j]
1965                             + UnicodeString("ERROR could not roundtrip ") + n
1966                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getLong());
1967                     }
1968                     else if (num.getType() == Formattable::kDouble && (int64_t)(num.getDouble() * 1000) != (int64_t)(n*1000)) {
1969                         // The epsilon difference is too high.
1970                         errln(UnicodeString(loc->getName()) + names[j]
1971                             + UnicodeString("ERROR could not roundtrip ") + n
1972                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getDouble());
1973                     }
1974                 }
1975                 // lenient parse
1976                 status = U_ZERO_ERROR;
1977                 f->setLenient(TRUE);
1978                 f->parse(str, num, status);
1979                 if (U_FAILURE(status)) {
1980                     errln(UnicodeString(loc->getName()) + names[j]
1981                         + "ERROR could not parse(lenient) '" + str + "' -> " + u_errorName(status));
1982                 }
1983                 // We only check the spellout. The behavior is undefined for numbers < 1 and fractional numbers.
1984                 if (j == 0) {
1985                     if (num.getType() == Formattable::kLong && num.getLong() != n) {
1986                         errln(UnicodeString(loc->getName()) + names[j]
1987                             + UnicodeString("ERROR could not roundtrip ") + n
1988                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getLong());
1989                     }
1990                     else if (num.getType() == Formattable::kDouble && (int64_t)(num.getDouble() * 1000) != (int64_t)(n*1000)) {
1991                         // The epsilon difference is too high.
1992                         errln(UnicodeString(loc->getName()) + names[j]
1993                             + UnicodeString("ERROR could not roundtrip ") + n
1994                             + UnicodeString(" -> ") + str + UnicodeString(" -> ") + num.getDouble());
1995                     }
1996                 }
1997             }
1998 #endif
1999             delete f;
2000         }
2001     }
2002 }
2003 
2004 void
TestMultiplierSubstitution(void)2005 IntlTestRBNF::TestMultiplierSubstitution(void) {
2006     UnicodeString rules("=#,##0=;1,000,000: <##0.###< million;");
2007     UErrorCode status = U_ZERO_ERROR;
2008     UParseError parse_error;
2009     RuleBasedNumberFormat *rbnf =
2010         new RuleBasedNumberFormat(rules, Locale::getUS(), parse_error, status);
2011     if (U_SUCCESS(status)) {
2012         UnicodeString res;
2013         FieldPosition pos;
2014         double n = 1234000.0;
2015         rbnf->format(n, res, pos);
2016         delete rbnf;
2017 
2018         UnicodeString expected(UNICODE_STRING_SIMPLE("1.234 million"));
2019         if (expected != res) {
2020             UnicodeString msg = "Expected: ";
2021             msg.append(expected);
2022             msg.append(" but got ");
2023             msg.append(res);
2024             errln(msg);
2025         }
2026     }
2027 }
2028 
2029 void
TestSetDecimalFormatSymbols()2030 IntlTestRBNF::TestSetDecimalFormatSymbols() {
2031     UErrorCode status = U_ZERO_ERROR;
2032 
2033     RuleBasedNumberFormat rbnf(URBNF_ORDINAL, Locale::getEnglish(), status);
2034     if (U_FAILURE(status)) {
2035         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2036         return;
2037     }
2038 
2039     DecimalFormatSymbols dfs(Locale::getEnglish(), status);
2040     if (U_FAILURE(status)) {
2041         errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status)));
2042         return;
2043     }
2044 
2045     UnicodeString expected[] = {
2046             UnicodeString("1,001st"),
2047             UnicodeString("1&001st")
2048     };
2049 
2050     double number = 1001;
2051 
2052     UnicodeString result;
2053 
2054     rbnf.format(number, result);
2055     if (result != expected[0]) {
2056         errln("Format Error - Got: " + result + " Expected: " + expected[0]);
2057     }
2058 
2059     result.remove();
2060 
2061     /* Set new symbol for testing */
2062     dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, UnicodeString("&"), TRUE);
2063     rbnf.setDecimalFormatSymbols(dfs);
2064 
2065     rbnf.format(number, result);
2066     if (result != expected[1]) {
2067         errln("Format Error - Got: " + result + " Expected: " + expected[1]);
2068     }
2069 }
2070 
TestPluralRules()2071 void IntlTestRBNF::TestPluralRules() {
2072     UErrorCode status = U_ZERO_ERROR;
2073     UnicodeString enRules("%digits-ordinal:-x: ->>;0: =#,##0=$(ordinal,one{st}two{nd}few{rd}other{th})$;");
2074     UParseError parseError;
2075     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2076     if (U_FAILURE(status)) {
2077         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2078         return;
2079     }
2080     const char* const enTestData[][2] = {
2081             { "1", "1st" },
2082             { "2", "2nd" },
2083             { "3", "3rd" },
2084             { "4", "4th" },
2085             { "11", "11th" },
2086             { "12", "12th" },
2087             { "13", "13th" },
2088             { "14", "14th" },
2089             { "21", "21st" },
2090             { "22", "22nd" },
2091             { "23", "23rd" },
2092             { "24", "24th" },
2093             { NULL, NULL }
2094     };
2095 
2096     doTest(&enFormatter, enTestData, TRUE);
2097 
2098     // This is trying to model the feminine form, but don't worry about the details too much.
2099     // We're trying to test the plural rules.
2100     UnicodeString ruRules("%spellout-numbering:"
2101             "-x: minus >>;"
2102             "x.x: << point >>;"
2103             "0: zero;"
2104             "1: one;"
2105             "2: two;"
2106             "3: three;"
2107             "4: four;"
2108             "5: five;"
2109             "6: six;"
2110             "7: seven;"
2111             "8: eight;"
2112             "9: nine;"
2113             "10: ten;"
2114             "11: eleven;"
2115             "12: twelve;"
2116             "13: thirteen;"
2117             "14: fourteen;"
2118             "15: fifteen;"
2119             "16: sixteen;"
2120             "17: seventeen;"
2121             "18: eighteen;"
2122             "19: nineteen;"
2123             "20: twenty[->>];"
2124             "30: thirty[->>];"
2125             "40: forty[->>];"
2126             "50: fifty[->>];"
2127             "60: sixty[->>];"
2128             "70: seventy[->>];"
2129             "80: eighty[->>];"
2130             "90: ninety[->>];"
2131             "100: hundred[ >>];"
2132             "200: << hundred[ >>];"
2133             "300: << hundreds[ >>];"
2134             "500: << hundredss[ >>];"
2135             "1000: << $(cardinal,one{thousand}few{thousands}other{thousandss})$[ >>];"
2136             "1000000: << $(cardinal,one{million}few{millions}other{millionss})$[ >>];");
2137     RuleBasedNumberFormat ruFormatter(ruRules, Locale("ru"), parseError, status);
2138     const char* const ruTestData[][2] = {
2139             { "1", "one" },
2140             { "100", "hundred" },
2141             { "125", "hundred twenty-five" },
2142             { "399", "three hundreds ninety-nine" },
2143             { "1,000", "one thousand" },
2144             { "1,001", "one thousand one" },
2145             { "2,000", "two thousands" },
2146             { "2,001", "two thousands one" },
2147             { "2,002", "two thousands two" },
2148             { "3,333", "three thousands three hundreds thirty-three" },
2149             { "5,000", "five thousandss" },
2150             { "11,000", "eleven thousandss" },
2151             { "21,000", "twenty-one thousand" },
2152             { "22,000", "twenty-two thousands" },
2153             { "25,001", "twenty-five thousandss one" },
2154             { NULL, NULL }
2155     };
2156 
2157     if (U_FAILURE(status)) {
2158         errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2159         return;
2160     }
2161     doTest(&ruFormatter, ruTestData, TRUE);
2162 
2163     // Make sure there are no divide by 0 errors.
2164     UnicodeString result;
2165     RuleBasedNumberFormat(ruRules, Locale("ru"), parseError, status).format((int32_t)21000, result);
2166     if (result.compare(UNICODE_STRING_SIMPLE("twenty-one thousand")) != 0) {
2167         errln("Got " + result + " for 21000");
2168     }
2169 
2170 }
2171 
TestInfinityNaN()2172 void IntlTestRBNF::TestInfinityNaN() {
2173     UErrorCode status = U_ZERO_ERROR;
2174     UParseError parseError;
2175     UnicodeString enRules("%default:"
2176             "-x: minus >>;"
2177             "Inf: infinite;"
2178             "NaN: not a number;"
2179             "0: =#,##0=;");
2180     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2181     const char * const enTestData[][2] = {
2182             {"1", "1"},
2183             {"\\u221E", "infinite"},
2184             {"-\\u221E", "minus infinite"},
2185             {"NaN", "not a number"},
2186             { NULL, NULL }
2187     };
2188     if (U_FAILURE(status)) {
2189         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2190         return;
2191     }
2192 
2193     doTest(&enFormatter, enTestData, true);
2194 
2195     // Test the default behavior when the rules are undefined.
2196     UnicodeString enRules2("%default:"
2197             "-x: ->>;"
2198             "0: =#,##0=;");
2199     RuleBasedNumberFormat enFormatter2(enRules2, Locale::getEnglish(), parseError, status);
2200     if (U_FAILURE(status)) {
2201         errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2202         return;
2203     }
2204     const char * const enDefaultTestData[][2] = {
2205             {"1", "1"},
2206             {"\\u221E", "\\u221E"},
2207             {"-\\u221E", "-\\u221E"},
2208             {"NaN", "NaN"},
2209             { NULL, NULL }
2210     };
2211 
2212     doTest(&enFormatter2, enDefaultTestData, true);
2213 }
2214 
TestVariableDecimalPoint()2215 void IntlTestRBNF::TestVariableDecimalPoint() {
2216     UErrorCode status = U_ZERO_ERROR;
2217     UParseError parseError;
2218     UnicodeString enRules("%spellout-numbering:"
2219             "-x: minus >>;"
2220             "x.x: << point >>;"
2221             "x,x: << comma >>;"
2222             "0.x: xpoint >>;"
2223             "0,x: xcomma >>;"
2224             "0: zero;"
2225             "1: one;"
2226             "2: two;"
2227             "3: three;"
2228             "4: four;"
2229             "5: five;"
2230             "6: six;"
2231             "7: seven;"
2232             "8: eight;"
2233             "9: nine;");
2234     RuleBasedNumberFormat enFormatter(enRules, Locale::getEnglish(), parseError, status);
2235     const char * const enTestPointData[][2] = {
2236             {"1.1", "one point one"},
2237             {"1.23", "one point two three"},
2238             {"0.4", "xpoint four"},
2239             { NULL, NULL }
2240     };
2241     if (U_FAILURE(status)) {
2242         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
2243         return;
2244     }
2245     doTest(&enFormatter, enTestPointData, true);
2246 
2247     DecimalFormatSymbols decimalFormatSymbols(Locale::getEnglish(), status);
2248     decimalFormatSymbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UNICODE_STRING_SIMPLE(","));
2249     enFormatter.setDecimalFormatSymbols(decimalFormatSymbols);
2250     const char * const enTestCommaData[][2] = {
2251             {"1.1", "one comma one"},
2252             {"1.23", "one comma two three"},
2253             {"0.4", "xcomma four"},
2254             { NULL, NULL }
2255     };
2256     doTest(&enFormatter, enTestCommaData, true);
2257 }
2258 
TestLargeNumbers()2259 void IntlTestRBNF::TestLargeNumbers() {
2260     UErrorCode status = U_ZERO_ERROR;
2261     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, Locale::getEnglish(), status);
2262 
2263     const char * const enTestFullData[][2] = {
2264             {"-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
2265             {"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
2266             {"-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
2267             {"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
2268             {"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"},
2269             {"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"},
2270             {"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"},
2271             {"1000000000000000000", "1,000,000,000,000,000,000"}, // The rules don't go to 1 quintillion yet
2272             {"-9223372036854775809", "-9,223,372,036,854,775,809"}, // We've gone beyond 64-bit precision
2273             {"-9223372036854775808", "-9,223,372,036,854,775,808"}, // We've gone beyond +64-bit precision
2274             {"-9223372036854775807", "minus 9,223,372,036,854,775,807"}, // Minimum 64-bit precision
2275             {"-9223372036854775806", "minus 9,223,372,036,854,775,806"}, // Minimum 64-bit precision + 1
2276             {"9223372036854774111", "9,223,372,036,854,774,111"}, // Below 64-bit precision
2277             {"9223372036854774999", "9,223,372,036,854,774,999"}, // Below 64-bit precision
2278             {"9223372036854775000", "9,223,372,036,854,775,000"}, // Below 64-bit precision
2279             {"9223372036854775806", "9,223,372,036,854,775,806"}, // Maximum 64-bit precision - 1
2280             {"9223372036854775807", "9,223,372,036,854,775,807"}, // Maximum 64-bit precision
2281             {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2282             { NULL, NULL }
2283     };
2284     doTest(&rbnf, enTestFullData, false);
2285 }
2286 
TestCompactDecimalFormatStyle()2287 void IntlTestRBNF::TestCompactDecimalFormatStyle() {
2288     UErrorCode status = U_ZERO_ERROR;
2289     UParseError parseError;
2290     // This is not a common use case, but we're testing it anyway.
2291     UnicodeString numberPattern("=###0.#####=;"
2292             "1000: <###0.00< K;"
2293             "1000000: <###0.00< M;"
2294             "1000000000: <###0.00< B;"
2295             "1000000000000: <###0.00< T;"
2296             "1000000000000000: <###0.00< Q;");
2297     RuleBasedNumberFormat rbnf(numberPattern, UnicodeString(), Locale::getEnglish(), parseError, status);
2298 
2299     const char * const enTestFullData[][2] = {
2300             {"1000", "1.00 K"},
2301             {"1234", "1.23 K"},
2302             {"999994", "999.99 K"},
2303             {"999995", "1000.00 K"},
2304             {"1000000", "1.00 M"},
2305             {"1200000", "1.20 M"},
2306             {"1200000000", "1.20 B"},
2307             {"1200000000000", "1.20 T"},
2308             {"1200000000000000", "1.20 Q"},
2309             {"4503599627370495", "4.50 Q"},
2310             {"4503599627370496", "4.50 Q"},
2311             {"8990000000000000", "8.99 Q"},
2312             {"9008000000000000", "9.00 Q"}, // Number doesn't precisely fit into a double
2313             {"9456000000000000", "9.00 Q"},  // Number doesn't precisely fit into a double
2314             {"10000000000000000", "10.00 Q"},  // Number doesn't precisely fit into a double
2315             {"9223372036854775807", "9223.00 Q"}, // Maximum 64-bit precision
2316             {"9223372036854775808", "9,223,372,036,854,775,808"}, // We've gone beyond 64-bit precision. This can only be represented with BigDecimal.
2317             { NULL, NULL }
2318     };
2319     doTest(&rbnf, enTestFullData, false);
2320 }
2321 
TestParseFailure()2322 void IntlTestRBNF::TestParseFailure() {
2323     UErrorCode status = U_ZERO_ERROR;
2324     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, Locale::getJapanese(), status);
2325     static const UChar* testData[] = {
2326         u"・・・・・・・・・・・・・・・・・・・・・・・・"
2327     };
2328     if (assertSuccess("", status, true, __FILE__, __LINE__)) {
2329         for (int i = 0; i < UPRV_LENGTHOF(testData); ++i) {
2330             UnicodeString spelledNumberString(testData[i]);
2331             Formattable actualNumber;
2332             rbnf.parse(spelledNumberString, actualNumber, status);
2333             if (status != U_INVALID_FORMAT_ERROR) { // I would have expected U_PARSE_ERROR, but NumberFormat::parse gives U_INVALID_FORMAT_ERROR
2334                 errln("FAIL: string should be unparseable index=%d %s", i, u_errorName(status));
2335             }
2336         }
2337     }
2338 }
2339 
TestMinMaxIntegerDigitsIgnored()2340 void IntlTestRBNF::TestMinMaxIntegerDigitsIgnored() {
2341     IcuTestErrorCode status(*this, "TestMinMaxIntegerDigitsIgnored");
2342 
2343     // NOTE: SimpleDateFormat has an optimization that depends on the fact that min/max integer digits
2344     // do not affect RBNF (see SimpleDateFormat#zeroPaddingNumber).
2345     RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, "en", status);
2346     if (status.isSuccess()) {
2347         rbnf.setMinimumIntegerDigits(2);
2348         rbnf.setMaximumIntegerDigits(3);
2349         UnicodeString result;
2350         rbnf.format(3, result.remove(), status);
2351         assertEquals("Min integer digits are ignored", u"three", result);
2352         rbnf.format(1012, result.remove(), status);
2353         assertEquals("Max integer digits are ignored", u"one thousand twelve", result);
2354     }
2355 }
2356 
2357 void
doTest(RuleBasedNumberFormat * formatter,const char * const testData[][2],UBool testParsing)2358 IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing)
2359 {
2360   // man, error reporting would be easier with printf-style syntax for unicode string and formattable
2361 
2362     UErrorCode status = U_ZERO_ERROR;
2363     DecimalFormatSymbols dfs("en", status);
2364     // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2365     DecimalFormat decFmt("#,###.################", dfs, status);
2366     if (U_FAILURE(status)) {
2367         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
2368     } else {
2369         for (int i = 0; testData[i][0]; ++i) {
2370             const char* numString = testData[i][0];
2371             const char* expectedWords = testData[i][1];
2372 
2373             log("[%i] %s = ", i, numString);
2374             Formattable expectedNumber;
2375             UnicodeString escapedNumString = UnicodeString(numString, -1, US_INV).unescape();
2376             decFmt.parse(escapedNumString, expectedNumber, status);
2377             if (U_FAILURE(status)) {
2378                 errln("FAIL: decFmt could not parse %s", numString);
2379                 break;
2380             } else {
2381                 UnicodeString actualString;
2382                 FieldPosition pos;
2383                 formatter->format(expectedNumber, actualString/* , pos*/, status);
2384                 if (U_FAILURE(status)) {
2385                     UnicodeString msg = "Fail: formatter could not format ";
2386                     decFmt.format(expectedNumber, msg, status);
2387                     errln(msg);
2388                     break;
2389                 } else {
2390                     UnicodeString expectedString = UnicodeString(expectedWords, -1, US_INV).unescape();
2391                     if (actualString != expectedString) {
2392                         UnicodeString msg = "FAIL: check failed for ";
2393                         decFmt.format(expectedNumber, msg, status);
2394                         msg.append(", expected ");
2395                         msg.append(expectedString);
2396                         msg.append(" but got ");
2397                         msg.append(actualString);
2398                         errln(msg);
2399                         break;
2400                     } else {
2401                         logln(actualString);
2402                         if (testParsing) {
2403                             Formattable parsedNumber;
2404                             formatter->parse(actualString, parsedNumber, status);
2405                             if (U_FAILURE(status)) {
2406                                 UnicodeString msg = "FAIL: formatter could not parse ";
2407                                 msg.append(actualString);
2408                                 msg.append(" status code: " );
2409                                 msg.append(u_errorName(status));
2410                                 errln(msg);
2411                                 break;
2412                             } else {
2413                                 if (parsedNumber != expectedNumber
2414                                     && (!uprv_isNaN(parsedNumber.getDouble()) || !uprv_isNaN(expectedNumber.getDouble())))
2415                                 {
2416                                     UnicodeString msg = "FAIL: parse failed for ";
2417                                     msg.append(actualString);
2418                                     msg.append(", expected ");
2419                                     decFmt.format(expectedNumber, msg, status);
2420                                     msg.append(", but got ");
2421                                     decFmt.format(parsedNumber, msg, status);
2422                                     errln(msg);
2423                                     break;
2424                                 }
2425                             }
2426                         }
2427                     }
2428                 }
2429             }
2430         }
2431     }
2432 }
2433 
2434 void
doLenientParseTest(RuleBasedNumberFormat * formatter,const char * testData[][2])2435 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat* formatter, const char* testData[][2])
2436 {
2437     UErrorCode status = U_ZERO_ERROR;
2438     NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2439     if (U_FAILURE(status)) {
2440         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
2441     } else {
2442         for (int i = 0; testData[i][0]; ++i) {
2443             const char* spelledNumber = testData[i][0]; // spelled-out number
2444             const char* asciiUSNumber = testData[i][1]; // number as ascii digits formatted for US locale
2445 
2446             UnicodeString spelledNumberString = UnicodeString(spelledNumber).unescape();
2447             Formattable actualNumber;
2448             formatter->parse(spelledNumberString, actualNumber, status);
2449             if (U_FAILURE(status)) {
2450                 UnicodeString msg = "FAIL: formatter could not parse ";
2451                 msg.append(spelledNumberString);
2452                 errln(msg);
2453                 break;
2454             } else {
2455                 // I changed the logic of this test somewhat from Java-- instead of comparing the
2456                 // strings, I compare the Formattables.  Hmmm, but the Formattables don't compare,
2457                 // so change it back.
2458 
2459                 UnicodeString asciiUSNumberString = asciiUSNumber;
2460                 Formattable expectedNumber;
2461                 decFmt->parse(asciiUSNumberString, expectedNumber, status);
2462                 if (U_FAILURE(status)) {
2463                     UnicodeString msg = "FAIL: decFmt could not parse ";
2464                     msg.append(asciiUSNumberString);
2465                     errln(msg);
2466                     break;
2467                 } else {
2468                     UnicodeString actualNumberString;
2469                     UnicodeString expectedNumberString;
2470                     decFmt->format(actualNumber, actualNumberString, status);
2471                     decFmt->format(expectedNumber, expectedNumberString, status);
2472                     if (actualNumberString != expectedNumberString) {
2473                         UnicodeString msg = "FAIL: parsing";
2474                         msg.append(asciiUSNumberString);
2475                         msg.append("\n");
2476                         msg.append("  lenient parse failed for ");
2477                         msg.append(spelledNumberString);
2478                         msg.append(", expected ");
2479                         msg.append(expectedNumberString);
2480                         msg.append(", but got ");
2481                         msg.append(actualNumberString);
2482                         errln(msg);
2483                         break;
2484                     }
2485                 }
2486             }
2487         }
2488         delete decFmt;
2489     }
2490 }
2491 
2492 /* U_HAVE_RBNF */
2493 #else
2494 
2495 void
TestRBNFDisabled()2496 IntlTestRBNF::TestRBNFDisabled() {
2497     errln("*** RBNF currently disabled on this platform ***\n");
2498 }
2499 
2500 /* U_HAVE_RBNF */
2501 #endif
2502 
2503 #endif /* #if !UCONFIG_NO_FORMATTING */
2504