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