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