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