1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 * Copyright (C) 2015, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 * 7 * file name: decimfmtimpl.cpp 8 */ 9 10 #include "unicode/utypes.h" 11 12 #if !UCONFIG_NO_FORMATTING 13 14 #include <math.h> 15 #include "unicode/numfmt.h" 16 #include "unicode/plurrule.h" 17 #include "unicode/ustring.h" 18 #include "decimalformatpattern.h" 19 #include "decimalformatpatternimpl.h" 20 #include "decimfmtimpl.h" 21 #include "fphdlimp.h" 22 #include "plurrule_impl.h" 23 #include "valueformatter.h" 24 #include "visibledigits.h" 25 26 U_NAMESPACE_BEGIN 27 28 static const int32_t kMaxScientificIntegerDigits = 8; 29 30 static const int32_t kFormattingPosPrefix = (1 << 0); 31 static const int32_t kFormattingNegPrefix = (1 << 1); 32 static const int32_t kFormattingPosSuffix = (1 << 2); 33 static const int32_t kFormattingNegSuffix = (1 << 3); 34 static const int32_t kFormattingSymbols = (1 << 4); 35 static const int32_t kFormattingCurrency = (1 << 5); 36 static const int32_t kFormattingUsesCurrency = (1 << 6); 37 static const int32_t kFormattingPluralRules = (1 << 7); 38 static const int32_t kFormattingAffixParser = (1 << 8); 39 static const int32_t kFormattingCurrencyAffixInfo = (1 << 9); 40 static const int32_t kFormattingAll = (1 << 10) - 1; 41 static const int32_t kFormattingAffixes = 42 kFormattingPosPrefix | kFormattingPosSuffix | 43 kFormattingNegPrefix | kFormattingNegSuffix; 44 static const int32_t kFormattingAffixParserWithCurrency = 45 kFormattingAffixParser | kFormattingCurrencyAffixInfo; 46 47 DecimalFormatImpl::DecimalFormatImpl( 48 NumberFormat *super, 49 const Locale &locale, 50 const UnicodeString &pattern, 51 UErrorCode &status) 52 : fSuper(super), 53 fScale(0), 54 fRoundingMode(DecimalFormat::kRoundHalfEven), 55 fSymbols(NULL), 56 fCurrencyUsage(UCURR_USAGE_STANDARD), 57 fRules(NULL), 58 fMonetary(FALSE) { 59 if (U_FAILURE(status)) { 60 return; 61 } 62 fSymbols = new DecimalFormatSymbols( 63 locale, status); 64 if (fSymbols == NULL) { 65 status = U_MEMORY_ALLOCATION_ERROR; 66 return; 67 } 68 UParseError parseError; 69 applyPattern(pattern, FALSE, parseError, status); 70 updateAll(status); 71 } 72 73 DecimalFormatImpl::DecimalFormatImpl( 74 NumberFormat *super, 75 const UnicodeString &pattern, 76 DecimalFormatSymbols *symbolsToAdopt, 77 UParseError &parseError, 78 UErrorCode &status) 79 : fSuper(super), 80 fScale(0), 81 fRoundingMode(DecimalFormat::kRoundHalfEven), 82 fSymbols(symbolsToAdopt), 83 fCurrencyUsage(UCURR_USAGE_STANDARD), 84 fRules(NULL), 85 fMonetary(FALSE) { 86 applyPattern(pattern, FALSE, parseError, status); 87 updateAll(status); 88 } 89 90 DecimalFormatImpl::DecimalFormatImpl( 91 NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) : 92 fSuper(super), 93 fMultiplier(other.fMultiplier), 94 fScale(other.fScale), 95 fRoundingMode(other.fRoundingMode), 96 fMinSigDigits(other.fMinSigDigits), 97 fMaxSigDigits(other.fMaxSigDigits), 98 fUseScientific(other.fUseScientific), 99 fUseSigDigits(other.fUseSigDigits), 100 fGrouping(other.fGrouping), 101 fPositivePrefixPattern(other.fPositivePrefixPattern), 102 fNegativePrefixPattern(other.fNegativePrefixPattern), 103 fPositiveSuffixPattern(other.fPositiveSuffixPattern), 104 fNegativeSuffixPattern(other.fNegativeSuffixPattern), 105 fSymbols(other.fSymbols), 106 fCurrencyUsage(other.fCurrencyUsage), 107 fRules(NULL), 108 fMonetary(other.fMonetary), 109 fAffixParser(other.fAffixParser), 110 fCurrencyAffixInfo(other.fCurrencyAffixInfo), 111 fEffPrecision(other.fEffPrecision), 112 fEffGrouping(other.fEffGrouping), 113 fOptions(other.fOptions), 114 fFormatter(other.fFormatter), 115 fAffixes(other.fAffixes) { 116 fSymbols = new DecimalFormatSymbols(*fSymbols); 117 if (fSymbols == NULL && U_SUCCESS(status)) { 118 status = U_MEMORY_ALLOCATION_ERROR; 119 } 120 if (other.fRules != NULL) { 121 fRules = new PluralRules(*other.fRules); 122 if (fRules == NULL && U_SUCCESS(status)) { 123 status = U_MEMORY_ALLOCATION_ERROR; 124 } 125 } 126 } 127 128 129 DecimalFormatImpl & 130 DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) { 131 if (U_FAILURE(status) || this == &other) { 132 return (*this); 133 } 134 UObject::operator=(other); 135 fMultiplier = other.fMultiplier; 136 fScale = other.fScale; 137 fRoundingMode = other.fRoundingMode; 138 fMinSigDigits = other.fMinSigDigits; 139 fMaxSigDigits = other.fMaxSigDigits; 140 fUseScientific = other.fUseScientific; 141 fUseSigDigits = other.fUseSigDigits; 142 fGrouping = other.fGrouping; 143 fPositivePrefixPattern = other.fPositivePrefixPattern; 144 fNegativePrefixPattern = other.fNegativePrefixPattern; 145 fPositiveSuffixPattern = other.fPositiveSuffixPattern; 146 fNegativeSuffixPattern = other.fNegativeSuffixPattern; 147 fCurrencyUsage = other.fCurrencyUsage; 148 fMonetary = other.fMonetary; 149 fAffixParser = other.fAffixParser; 150 fCurrencyAffixInfo = other.fCurrencyAffixInfo; 151 fEffPrecision = other.fEffPrecision; 152 fEffGrouping = other.fEffGrouping; 153 fOptions = other.fOptions; 154 fFormatter = other.fFormatter; 155 fAffixes = other.fAffixes; 156 *fSymbols = *other.fSymbols; 157 if (fRules != NULL && other.fRules != NULL) { 158 *fRules = *other.fRules; 159 } else { 160 delete fRules; 161 fRules = other.fRules; 162 if (fRules != NULL) { 163 fRules = new PluralRules(*fRules); 164 if (fRules == NULL) { 165 status = U_MEMORY_ALLOCATION_ERROR; 166 return *this; 167 } 168 } 169 } 170 return *this; 171 } 172 173 UBool 174 DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const { 175 if (this == &other) { 176 return TRUE; 177 } 178 return (fMultiplier == other.fMultiplier) 179 && (fScale == other.fScale) 180 && (fRoundingMode == other.fRoundingMode) 181 && (fMinSigDigits == other.fMinSigDigits) 182 && (fMaxSigDigits == other.fMaxSigDigits) 183 && (fUseScientific == other.fUseScientific) 184 && (fUseSigDigits == other.fUseSigDigits) 185 && fGrouping.equals(other.fGrouping) 186 && fPositivePrefixPattern.equals(other.fPositivePrefixPattern) 187 && fNegativePrefixPattern.equals(other.fNegativePrefixPattern) 188 && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern) 189 && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern) 190 && fCurrencyUsage == other.fCurrencyUsage 191 && fAffixParser.equals(other.fAffixParser) 192 && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo) 193 && fEffPrecision.equals(other.fEffPrecision) 194 && fEffGrouping.equals(other.fEffGrouping) 195 && fOptions.equals(other.fOptions) 196 && fFormatter.equals(other.fFormatter) 197 && fAffixes.equals(other.fAffixes) 198 && (*fSymbols == *other.fSymbols) 199 && ((fRules == other.fRules) || ( 200 (fRules != NULL) && (other.fRules != NULL) 201 && (*fRules == *other.fRules))) 202 && (fMonetary == other.fMonetary); 203 } 204 205 DecimalFormatImpl::~DecimalFormatImpl() { 206 delete fSymbols; 207 delete fRules; 208 } 209 210 ValueFormatter & 211 DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const { 212 if (fUseScientific) { 213 vf.prepareScientificFormatting( 214 fFormatter, fEffPrecision, fOptions); 215 return vf; 216 } 217 vf.prepareFixedDecimalFormatting( 218 fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantissa); 219 return vf; 220 } 221 222 int32_t 223 DecimalFormatImpl::getPatternScale() const { 224 UBool usesPercent = fPositivePrefixPattern.usesPercent() || 225 fPositiveSuffixPattern.usesPercent() || 226 fNegativePrefixPattern.usesPercent() || 227 fNegativeSuffixPattern.usesPercent(); 228 if (usesPercent) { 229 return 2; 230 } 231 UBool usesPermill = fPositivePrefixPattern.usesPermill() || 232 fPositiveSuffixPattern.usesPermill() || 233 fNegativePrefixPattern.usesPermill() || 234 fNegativeSuffixPattern.usesPermill(); 235 if (usesPermill) { 236 return 3; 237 } 238 return 0; 239 } 240 241 void 242 DecimalFormatImpl::setMultiplierScale(int32_t scale) { 243 if (scale == 0) { 244 // Needed to preserve equality. fMultiplier == 0 means 245 // multiplier is 1. 246 fMultiplier.set((int32_t)0); 247 } else { 248 fMultiplier.set((int32_t)1); 249 fMultiplier.shiftDecimalRight(scale); 250 } 251 } 252 253 UnicodeString & 254 DecimalFormatImpl::format( 255 int32_t number, 256 UnicodeString &appendTo, 257 FieldPosition &pos, 258 UErrorCode &status) const { 259 FieldPositionOnlyHandler handler(pos); 260 return formatInt32(number, appendTo, handler, status); 261 } 262 263 UnicodeString & 264 DecimalFormatImpl::format( 265 int32_t number, 266 UnicodeString &appendTo, 267 FieldPositionIterator *posIter, 268 UErrorCode &status) const { 269 FieldPositionIteratorHandler handler(posIter, status); 270 return formatInt32(number, appendTo, handler, status); 271 } 272 273 template<class T> 274 UBool DecimalFormatImpl::maybeFormatWithDigitList( 275 T number, 276 UnicodeString &appendTo, 277 FieldPositionHandler &handler, 278 UErrorCode &status) const { 279 if (!fMultiplier.isZero()) { 280 DigitList digits; 281 digits.set(number); 282 digits.mult(fMultiplier, status); 283 digits.shiftDecimalRight(fScale); 284 formatAdjustedDigitList(digits, appendTo, handler, status); 285 return TRUE; 286 } 287 if (fScale != 0) { 288 DigitList digits; 289 digits.set(number); 290 digits.shiftDecimalRight(fScale); 291 formatAdjustedDigitList(digits, appendTo, handler, status); 292 return TRUE; 293 } 294 return FALSE; 295 } 296 297 template<class T> 298 UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList( 299 T number, 300 VisibleDigitsWithExponent &visibleDigits, 301 UErrorCode &status) const { 302 if (!fMultiplier.isZero()) { 303 DigitList digits; 304 digits.set(number); 305 digits.mult(fMultiplier, status); 306 digits.shiftDecimalRight(fScale); 307 initVisibleDigitsFromAdjusted(digits, visibleDigits, status); 308 return TRUE; 309 } 310 if (fScale != 0) { 311 DigitList digits; 312 digits.set(number); 313 digits.shiftDecimalRight(fScale); 314 initVisibleDigitsFromAdjusted(digits, visibleDigits, status); 315 return TRUE; 316 } 317 return FALSE; 318 } 319 320 UnicodeString & 321 DecimalFormatImpl::formatInt32( 322 int32_t number, 323 UnicodeString &appendTo, 324 FieldPositionHandler &handler, 325 UErrorCode &status) const { 326 if (maybeFormatWithDigitList(number, appendTo, handler, status)) { 327 return appendTo; 328 } 329 ValueFormatter vf; 330 return fAffixes.formatInt32( 331 number, 332 prepareValueFormatter(vf), 333 handler, 334 fRules, 335 appendTo, 336 status); 337 } 338 339 UnicodeString & 340 DecimalFormatImpl::formatInt64( 341 int64_t number, 342 UnicodeString &appendTo, 343 FieldPositionHandler &handler, 344 UErrorCode &status) const { 345 if (number >= INT32_MIN && number <= INT32_MAX) { 346 return formatInt32((int32_t) number, appendTo, handler, status); 347 } 348 VisibleDigitsWithExponent digits; 349 initVisibleDigitsWithExponent(number, digits, status); 350 return formatVisibleDigitsWithExponent( 351 digits, appendTo, handler, status); 352 } 353 354 UnicodeString & 355 DecimalFormatImpl::formatDouble( 356 double number, 357 UnicodeString &appendTo, 358 FieldPositionHandler &handler, 359 UErrorCode &status) const { 360 VisibleDigitsWithExponent digits; 361 initVisibleDigitsWithExponent(number, digits, status); 362 return formatVisibleDigitsWithExponent( 363 digits, appendTo, handler, status); 364 } 365 366 UnicodeString & 367 DecimalFormatImpl::format( 368 double number, 369 UnicodeString &appendTo, 370 FieldPosition &pos, 371 UErrorCode &status) const { 372 FieldPositionOnlyHandler handler(pos); 373 return formatDouble(number, appendTo, handler, status); 374 } 375 376 UnicodeString & 377 DecimalFormatImpl::format( 378 const DigitList &number, 379 UnicodeString &appendTo, 380 FieldPosition &pos, 381 UErrorCode &status) const { 382 DigitList dl(number); 383 FieldPositionOnlyHandler handler(pos); 384 return formatDigitList(dl, appendTo, handler, status); 385 } 386 387 UnicodeString & 388 DecimalFormatImpl::format( 389 int64_t number, 390 UnicodeString &appendTo, 391 FieldPosition &pos, 392 UErrorCode &status) const { 393 FieldPositionOnlyHandler handler(pos); 394 return formatInt64(number, appendTo, handler, status); 395 } 396 397 UnicodeString & 398 DecimalFormatImpl::format( 399 int64_t number, 400 UnicodeString &appendTo, 401 FieldPositionIterator *posIter, 402 UErrorCode &status) const { 403 FieldPositionIteratorHandler handler(posIter, status); 404 return formatInt64(number, appendTo, handler, status); 405 } 406 407 UnicodeString & 408 DecimalFormatImpl::format( 409 double number, 410 UnicodeString &appendTo, 411 FieldPositionIterator *posIter, 412 UErrorCode &status) const { 413 FieldPositionIteratorHandler handler(posIter, status); 414 return formatDouble(number, appendTo, handler, status); 415 } 416 417 UnicodeString & 418 DecimalFormatImpl::format( 419 const DigitList &number, 420 UnicodeString &appendTo, 421 FieldPositionIterator *posIter, 422 UErrorCode &status) const { 423 DigitList dl(number); 424 FieldPositionIteratorHandler handler(posIter, status); 425 return formatDigitList(dl, appendTo, handler, status); 426 } 427 428 UnicodeString & 429 DecimalFormatImpl::format( 430 StringPiece number, 431 UnicodeString &appendTo, 432 FieldPositionIterator *posIter, 433 UErrorCode &status) const { 434 DigitList dl; 435 dl.set(number, status); 436 FieldPositionIteratorHandler handler(posIter, status); 437 return formatDigitList(dl, appendTo, handler, status); 438 } 439 440 UnicodeString & 441 DecimalFormatImpl::format( 442 const VisibleDigitsWithExponent &digits, 443 UnicodeString &appendTo, 444 FieldPosition &pos, 445 UErrorCode &status) const { 446 FieldPositionOnlyHandler handler(pos); 447 return formatVisibleDigitsWithExponent( 448 digits, appendTo, handler, status); 449 } 450 451 UnicodeString & 452 DecimalFormatImpl::format( 453 const VisibleDigitsWithExponent &digits, 454 UnicodeString &appendTo, 455 FieldPositionIterator *posIter, 456 UErrorCode &status) const { 457 FieldPositionIteratorHandler handler(posIter, status); 458 return formatVisibleDigitsWithExponent( 459 digits, appendTo, handler, status); 460 } 461 462 DigitList & 463 DecimalFormatImpl::adjustDigitList( 464 DigitList &number, UErrorCode &status) const { 465 number.setRoundingMode(fRoundingMode); 466 if (!fMultiplier.isZero()) { 467 number.mult(fMultiplier, status); 468 } 469 if (fScale != 0) { 470 number.shiftDecimalRight(fScale); 471 } 472 number.reduce(); 473 return number; 474 } 475 476 UnicodeString & 477 DecimalFormatImpl::formatDigitList( 478 DigitList &number, 479 UnicodeString &appendTo, 480 FieldPositionHandler &handler, 481 UErrorCode &status) const { 482 VisibleDigitsWithExponent digits; 483 initVisibleDigitsWithExponent(number, digits, status); 484 return formatVisibleDigitsWithExponent( 485 digits, appendTo, handler, status); 486 } 487 488 UnicodeString & 489 DecimalFormatImpl::formatAdjustedDigitList( 490 DigitList &number, 491 UnicodeString &appendTo, 492 FieldPositionHandler &handler, 493 UErrorCode &status) const { 494 ValueFormatter vf; 495 return fAffixes.format( 496 number, 497 prepareValueFormatter(vf), 498 handler, 499 fRules, 500 appendTo, 501 status); 502 } 503 504 UnicodeString & 505 DecimalFormatImpl::formatVisibleDigitsWithExponent( 506 const VisibleDigitsWithExponent &digits, 507 UnicodeString &appendTo, 508 FieldPositionHandler &handler, 509 UErrorCode &status) const { 510 ValueFormatter vf; 511 return fAffixes.format( 512 digits, 513 prepareValueFormatter(vf), 514 handler, 515 fRules, 516 appendTo, 517 status); 518 } 519 520 static FixedDecimal &initFixedDecimal( 521 const VisibleDigits &digits, FixedDecimal &result) { 522 result.source = 0.0; 523 result.isNegative = digits.isNegative(); 524 result._isNaN = digits.isNaN(); 525 result._isInfinite = digits.isInfinite(); 526 digits.getFixedDecimal( 527 result.source, result.intValue, result.decimalDigits, 528 result.decimalDigitsWithoutTrailingZeros, 529 result.visibleDecimalDigitCount, result.hasIntegerValue); 530 return result; 531 } 532 533 FixedDecimal & 534 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const { 535 if (U_FAILURE(status)) { 536 return result; 537 } 538 VisibleDigits digits; 539 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); 540 return initFixedDecimal(digits, result); 541 } 542 543 FixedDecimal & 544 DecimalFormatImpl::getFixedDecimal( 545 DigitList &number, FixedDecimal &result, UErrorCode &status) const { 546 if (U_FAILURE(status)) { 547 return result; 548 } 549 VisibleDigits digits; 550 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); 551 return initFixedDecimal(digits, result); 552 } 553 554 VisibleDigitsWithExponent & 555 DecimalFormatImpl::initVisibleDigitsWithExponent( 556 int64_t number, 557 VisibleDigitsWithExponent &digits, 558 UErrorCode &status) const { 559 if (maybeInitVisibleDigitsFromDigitList( 560 number, digits, status)) { 561 return digits; 562 } 563 if (fUseScientific) { 564 fEffPrecision.initVisibleDigitsWithExponent( 565 number, digits, status); 566 } else { 567 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 568 number, digits, status); 569 } 570 return digits; 571 } 572 573 VisibleDigitsWithExponent & 574 DecimalFormatImpl::initVisibleDigitsWithExponent( 575 double number, 576 VisibleDigitsWithExponent &digits, 577 UErrorCode &status) const { 578 if (maybeInitVisibleDigitsFromDigitList( 579 number, digits, status)) { 580 return digits; 581 } 582 if (fUseScientific) { 583 fEffPrecision.initVisibleDigitsWithExponent( 584 number, digits, status); 585 } else { 586 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 587 number, digits, status); 588 } 589 return digits; 590 } 591 592 VisibleDigitsWithExponent & 593 DecimalFormatImpl::initVisibleDigitsWithExponent( 594 DigitList &number, 595 VisibleDigitsWithExponent &digits, 596 UErrorCode &status) const { 597 adjustDigitList(number, status); 598 return initVisibleDigitsFromAdjusted(number, digits, status); 599 } 600 601 VisibleDigitsWithExponent & 602 DecimalFormatImpl::initVisibleDigitsFromAdjusted( 603 DigitList &number, 604 VisibleDigitsWithExponent &digits, 605 UErrorCode &status) const { 606 if (fUseScientific) { 607 fEffPrecision.initVisibleDigitsWithExponent( 608 number, digits, status); 609 } else { 610 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 611 number, digits, status); 612 } 613 return digits; 614 } 615 616 DigitList & 617 DecimalFormatImpl::round( 618 DigitList &number, UErrorCode &status) const { 619 if (number.isNaN() || number.isInfinite()) { 620 return number; 621 } 622 adjustDigitList(number, status); 623 ValueFormatter vf; 624 prepareValueFormatter(vf); 625 return vf.round(number, status); 626 } 627 628 void 629 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) { 630 fMinSigDigits = newValue; 631 fUseSigDigits = TRUE; // ticket 9936 632 updatePrecision(); 633 } 634 635 void 636 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) { 637 fMaxSigDigits = newValue; 638 fUseSigDigits = TRUE; // ticket 9936 639 updatePrecision(); 640 } 641 642 void 643 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) { 644 fMinSigDigits = min; 645 fMaxSigDigits = max; 646 fUseSigDigits = TRUE; // ticket 9936 647 updatePrecision(); 648 } 649 650 void 651 DecimalFormatImpl::setScientificNotation(UBool newValue) { 652 fUseScientific = newValue; 653 updatePrecision(); 654 } 655 656 void 657 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) { 658 fUseSigDigits = newValue; 659 updatePrecision(); 660 } 661 662 void 663 DecimalFormatImpl::setGroupingSize(int32_t newValue) { 664 fGrouping.fGrouping = newValue; 665 updateGrouping(); 666 } 667 668 void 669 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) { 670 fGrouping.fGrouping2 = newValue; 671 updateGrouping(); 672 } 673 674 void 675 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) { 676 fGrouping.fMinGrouping = newValue; 677 updateGrouping(); 678 } 679 680 void 681 DecimalFormatImpl::setCurrencyUsage( 682 UCurrencyUsage currencyUsage, UErrorCode &status) { 683 fCurrencyUsage = currencyUsage; 684 updateFormatting(kFormattingCurrency, status); 685 } 686 687 void 688 DecimalFormatImpl::setRoundingIncrement(double d) { 689 if (d > 0.0) { 690 fEffPrecision.fMantissa.fRoundingIncrement.set(d); 691 } else { 692 fEffPrecision.fMantissa.fRoundingIncrement.set(0.0); 693 } 694 } 695 696 double 697 DecimalFormatImpl::getRoundingIncrement() const { 698 return fEffPrecision.fMantissa.fRoundingIncrement.getDouble(); 699 } 700 701 int32_t 702 DecimalFormatImpl::getMultiplier() const { 703 if (fMultiplier.isZero()) { 704 return 1; 705 } 706 return (int32_t) fMultiplier.getDouble(); 707 } 708 709 void 710 DecimalFormatImpl::setMultiplier(int32_t m) { 711 if (m == 0 || m == 1) { 712 fMultiplier.set((int32_t)0); 713 } else { 714 fMultiplier.set(m); 715 } 716 } 717 718 void 719 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) { 720 fPositivePrefixPattern.remove(); 721 fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); 722 UErrorCode status = U_ZERO_ERROR; 723 updateFormatting(kFormattingPosPrefix, status); 724 } 725 726 void 727 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) { 728 fPositiveSuffixPattern.remove(); 729 fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); 730 UErrorCode status = U_ZERO_ERROR; 731 updateFormatting(kFormattingPosSuffix, status); 732 } 733 734 void 735 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) { 736 fNegativePrefixPattern.remove(); 737 fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); 738 UErrorCode status = U_ZERO_ERROR; 739 updateFormatting(kFormattingNegPrefix, status); 740 } 741 742 void 743 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) { 744 fNegativeSuffixPattern.remove(); 745 fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); 746 UErrorCode status = U_ZERO_ERROR; 747 updateFormatting(kFormattingNegSuffix, status); 748 } 749 750 UnicodeString & 751 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const { 752 result = fAffixes.fPositivePrefix.getOtherVariant().toString(); 753 return result; 754 } 755 756 UnicodeString & 757 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const { 758 result = fAffixes.fPositiveSuffix.getOtherVariant().toString(); 759 return result; 760 } 761 762 UnicodeString & 763 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const { 764 result = fAffixes.fNegativePrefix.getOtherVariant().toString(); 765 return result; 766 } 767 768 UnicodeString & 769 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const { 770 result = fAffixes.fNegativeSuffix.getOtherVariant().toString(); 771 return result; 772 } 773 774 void 775 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) { 776 if (symbolsToAdopt == NULL) { 777 return; 778 } 779 delete fSymbols; 780 fSymbols = symbolsToAdopt; 781 UErrorCode status = U_ZERO_ERROR; 782 updateFormatting(kFormattingSymbols, status); 783 } 784 785 void 786 DecimalFormatImpl::applyPatternFavorCurrencyPrecision( 787 const UnicodeString &pattern, UErrorCode &status) { 788 UParseError perror; 789 applyPattern(pattern, FALSE, perror, status); 790 updateForApplyPatternFavorCurrencyPrecision(status); 791 } 792 793 void 794 DecimalFormatImpl::applyPattern( 795 const UnicodeString &pattern, UErrorCode &status) { 796 UParseError perror; 797 applyPattern(pattern, FALSE, perror, status); 798 updateForApplyPattern(status); 799 } 800 801 void 802 DecimalFormatImpl::applyPattern( 803 const UnicodeString &pattern, 804 UParseError &perror, UErrorCode &status) { 805 applyPattern(pattern, FALSE, perror, status); 806 updateForApplyPattern(status); 807 } 808 809 void 810 DecimalFormatImpl::applyLocalizedPattern( 811 const UnicodeString &pattern, UErrorCode &status) { 812 UParseError perror; 813 applyPattern(pattern, TRUE, perror, status); 814 updateForApplyPattern(status); 815 } 816 817 void 818 DecimalFormatImpl::applyLocalizedPattern( 819 const UnicodeString &pattern, 820 UParseError &perror, UErrorCode &status) { 821 applyPattern(pattern, TRUE, perror, status); 822 updateForApplyPattern(status); 823 } 824 825 void 826 DecimalFormatImpl::applyPattern( 827 const UnicodeString &pattern, 828 UBool localized, UParseError &perror, UErrorCode &status) { 829 if (U_FAILURE(status)) { 830 return; 831 } 832 DecimalFormatPatternParser patternParser; 833 if (localized) { 834 patternParser.useSymbols(*fSymbols); 835 } 836 DecimalFormatPattern out; 837 patternParser.applyPatternWithoutExpandAffix( 838 pattern, out, perror, status); 839 if (U_FAILURE(status)) { 840 return; 841 } 842 fUseScientific = out.fUseExponentialNotation; 843 fUseSigDigits = out.fUseSignificantDigits; 844 fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits); 845 fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits); 846 fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits); 847 fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits); 848 fMinSigDigits = out.fMinimumSignificantDigits; 849 fMaxSigDigits = out.fMaximumSignificantDigits; 850 fEffPrecision.fMinExponentDigits = out.fMinExponentDigits; 851 fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown; 852 fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed); 853 fGrouping.fGrouping = out.fGroupingSize; 854 fGrouping.fGrouping2 = out.fGroupingSize2; 855 fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown; 856 if (out.fRoundingIncrementUsed) { 857 fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement; 858 } else { 859 fEffPrecision.fMantissa.fRoundingIncrement.clear(); 860 } 861 fAffixes.fPadChar = out.fPad; 862 fNegativePrefixPattern = out.fNegPrefixAffix; 863 fNegativeSuffixPattern = out.fNegSuffixAffix; 864 fPositivePrefixPattern = out.fPosPrefixAffix; 865 fPositiveSuffixPattern = out.fPosSuffixAffix; 866 867 // Work around. Pattern parsing code and DecimalFormat code don't agree 868 // on the definition of field width, so we have to translate from 869 // pattern field width to decimal format field width here. 870 fAffixes.fWidth = out.fFormatWidth == 0 ? 0 : 871 out.fFormatWidth + fPositivePrefixPattern.countChar32() 872 + fPositiveSuffixPattern.countChar32(); 873 switch (out.fPadPosition) { 874 case DecimalFormatPattern::kPadBeforePrefix: 875 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix; 876 break; 877 case DecimalFormatPattern::kPadAfterPrefix: 878 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix; 879 break; 880 case DecimalFormatPattern::kPadBeforeSuffix: 881 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix; 882 break; 883 case DecimalFormatPattern::kPadAfterSuffix: 884 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix; 885 break; 886 default: 887 break; 888 } 889 } 890 891 void 892 DecimalFormatImpl::updatePrecision() { 893 if (fUseScientific) { 894 updatePrecisionForScientific(); 895 } else { 896 updatePrecisionForFixed(); 897 } 898 } 899 900 static void updatePrecisionForScientificMinMax( 901 const DigitInterval &min, 902 const DigitInterval &max, 903 DigitInterval &resultMin, 904 DigitInterval &resultMax, 905 SignificantDigitInterval &resultSignificant) { 906 resultMin.setIntDigitCount(0); 907 resultMin.setFracDigitCount(0); 908 resultSignificant.clear(); 909 resultMax.clear(); 910 911 int32_t maxIntDigitCount = max.getIntDigitCount(); 912 int32_t minIntDigitCount = min.getIntDigitCount(); 913 int32_t maxFracDigitCount = max.getFracDigitCount(); 914 int32_t minFracDigitCount = min.getFracDigitCount(); 915 916 917 // Not in spec: maxIntDigitCount > 8 assume 918 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has 919 // no provision for unsetting maxIntDigitCount which would be useful for 920 // scientific notation. The best we can do is assume that if 921 // maxIntDigitCount is the default of 2000000000 or is "big enough" then 922 // user did not intend to explicitly set it. The 8 was derived emperically 923 // by extensive testing of legacy code. 924 if (maxIntDigitCount > 8) { 925 maxIntDigitCount = minIntDigitCount; 926 } 927 928 // Per the spec, exponent grouping happens if maxIntDigitCount is more 929 // than 1 and more than minIntDigitCount. 930 UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount; 931 if (bExponentGrouping) { 932 resultMax.setIntDigitCount(maxIntDigitCount); 933 934 // For exponent grouping minIntDigits is always treated as 1 even 935 // if it wasn't set to 1! 936 resultMin.setIntDigitCount(1); 937 } else { 938 // Fixed digit count left of decimal. minIntDigitCount doesn't have 939 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while 940 // maxIntDigitCount == 1. 941 int32_t fixedIntDigitCount = maxIntDigitCount; 942 943 // If fixedIntDigitCount is 0 but 944 // min or max fraction count is 0 too then use 1. This way we can get 945 // unlimited precision for X.XXXEX 946 if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) { 947 fixedIntDigitCount = 1; 948 } 949 resultMax.setIntDigitCount(fixedIntDigitCount); 950 resultMin.setIntDigitCount(fixedIntDigitCount); 951 } 952 // Spec says this is how we compute significant digits. 0 means 953 // unlimited significant digits. 954 int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount; 955 if (maxSigDigits > 0) { 956 int32_t minSigDigits = minIntDigitCount + minFracDigitCount; 957 resultSignificant.setMin(minSigDigits); 958 resultSignificant.setMax(maxSigDigits); 959 } 960 } 961 962 void 963 DecimalFormatImpl::updatePrecisionForScientific() { 964 FixedPrecision *result = &fEffPrecision.fMantissa; 965 if (fUseSigDigits) { 966 result->fMax.setFracDigitCount(-1); 967 result->fMax.setIntDigitCount(1); 968 result->fMin.setFracDigitCount(0); 969 result->fMin.setIntDigitCount(1); 970 result->fSignificant.clear(); 971 extractSigDigits(result->fSignificant); 972 return; 973 } 974 DigitInterval max; 975 DigitInterval min; 976 extractMinMaxDigits(min, max); 977 updatePrecisionForScientificMinMax( 978 min, max, 979 result->fMin, result->fMax, result->fSignificant); 980 } 981 982 void 983 DecimalFormatImpl::updatePrecisionForFixed() { 984 FixedPrecision *result = &fEffPrecision.fMantissa; 985 if (!fUseSigDigits) { 986 extractMinMaxDigits(result->fMin, result->fMax); 987 result->fSignificant.clear(); 988 } else { 989 extractSigDigits(result->fSignificant); 990 result->fMin.setIntDigitCount(1); 991 result->fMin.setFracDigitCount(0); 992 result->fMax.clear(); 993 } 994 } 995 996 void 997 DecimalFormatImpl::extractMinMaxDigits( 998 DigitInterval &min, DigitInterval &max) const { 999 min.setIntDigitCount(fSuper->getMinimumIntegerDigits()); 1000 max.setIntDigitCount(fSuper->getMaximumIntegerDigits()); 1001 min.setFracDigitCount(fSuper->getMinimumFractionDigits()); 1002 max.setFracDigitCount(fSuper->getMaximumFractionDigits()); 1003 } 1004 1005 void 1006 DecimalFormatImpl::extractSigDigits( 1007 SignificantDigitInterval &sig) const { 1008 sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits); 1009 sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits); 1010 } 1011 1012 void 1013 DecimalFormatImpl::updateGrouping() { 1014 if (fSuper->isGroupingUsed()) { 1015 fEffGrouping = fGrouping; 1016 } else { 1017 fEffGrouping.clear(); 1018 } 1019 } 1020 1021 void 1022 DecimalFormatImpl::updateCurrency(UErrorCode &status) { 1023 updateFormatting(kFormattingCurrency, TRUE, status); 1024 } 1025 1026 void 1027 DecimalFormatImpl::updateFormatting( 1028 int32_t changedFormattingFields, 1029 UErrorCode &status) { 1030 updateFormatting(changedFormattingFields, TRUE, status); 1031 } 1032 1033 void 1034 DecimalFormatImpl::updateFormatting( 1035 int32_t changedFormattingFields, 1036 UBool updatePrecisionBasedOnCurrency, 1037 UErrorCode &status) { 1038 if (U_FAILURE(status)) { 1039 return; 1040 } 1041 // Each function updates one field. Order matters. For instance, 1042 // updatePluralRules comes before updateCurrencyAffixInfo because the 1043 // fRules field is needed to update the fCurrencyAffixInfo field. 1044 updateFormattingUsesCurrency(changedFormattingFields); 1045 updateFormattingFixedPointFormatter(changedFormattingFields); 1046 updateFormattingAffixParser(changedFormattingFields); 1047 updateFormattingPluralRules(changedFormattingFields, status); 1048 updateFormattingCurrencyAffixInfo( 1049 changedFormattingFields, 1050 updatePrecisionBasedOnCurrency, 1051 status); 1052 updateFormattingLocalizedPositivePrefix( 1053 changedFormattingFields, status); 1054 updateFormattingLocalizedPositiveSuffix( 1055 changedFormattingFields, status); 1056 updateFormattingLocalizedNegativePrefix( 1057 changedFormattingFields, status); 1058 updateFormattingLocalizedNegativeSuffix( 1059 changedFormattingFields, status); 1060 } 1061 1062 void 1063 DecimalFormatImpl::updateFormattingUsesCurrency( 1064 int32_t &changedFormattingFields) { 1065 if ((changedFormattingFields & kFormattingAffixes) == 0) { 1066 // If no affixes changed, don't need to do any work 1067 return; 1068 } 1069 UBool newUsesCurrency = 1070 fPositivePrefixPattern.usesCurrency() || 1071 fPositiveSuffixPattern.usesCurrency() || 1072 fNegativePrefixPattern.usesCurrency() || 1073 fNegativeSuffixPattern.usesCurrency(); 1074 if (fMonetary != newUsesCurrency) { 1075 fMonetary = newUsesCurrency; 1076 changedFormattingFields |= kFormattingUsesCurrency; 1077 } 1078 } 1079 1080 void 1081 DecimalFormatImpl::updateFormattingPluralRules( 1082 int32_t &changedFormattingFields, UErrorCode &status) { 1083 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) { 1084 // No work to do if both fSymbols and fMonetary 1085 // fields are unchanged 1086 return; 1087 } 1088 if (U_FAILURE(status)) { 1089 return; 1090 } 1091 PluralRules *newRules = NULL; 1092 if (fMonetary) { 1093 newRules = PluralRules::forLocale(fSymbols->getLocale(), status); 1094 if (U_FAILURE(status)) { 1095 return; 1096 } 1097 } 1098 // Its ok to say a field has changed when it really hasn't but not 1099 // the other way around. Here we assume the field changed unless it 1100 // was NULL before and is still NULL now 1101 if (fRules != newRules) { 1102 delete fRules; 1103 fRules = newRules; 1104 changedFormattingFields |= kFormattingPluralRules; 1105 } 1106 } 1107 1108 void 1109 DecimalFormatImpl::updateFormattingCurrencyAffixInfo( 1110 int32_t &changedFormattingFields, 1111 UBool updatePrecisionBasedOnCurrency, 1112 UErrorCode &status) { 1113 if ((changedFormattingFields & ( 1114 kFormattingSymbols | kFormattingCurrency | 1115 kFormattingUsesCurrency | kFormattingPluralRules)) == 0) { 1116 // If all these fields are unchanged, no work to do. 1117 return; 1118 } 1119 if (U_FAILURE(status)) { 1120 return; 1121 } 1122 if (!fMonetary) { 1123 if (fCurrencyAffixInfo.isDefault()) { 1124 // In this case don't have to do any work 1125 return; 1126 } 1127 fCurrencyAffixInfo.set(NULL, NULL, NULL, status); 1128 if (U_FAILURE(status)) { 1129 return; 1130 } 1131 changedFormattingFields |= kFormattingCurrencyAffixInfo; 1132 } else { 1133 const UChar *currency = fSuper->getCurrency(); 1134 UChar localeCurr[4]; 1135 if (currency[0] == 0) { 1136 ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status); 1137 if (U_SUCCESS(status)) { 1138 currency = localeCurr; 1139 fSuper->NumberFormat::setCurrency(currency, status); 1140 } else { 1141 currency = NULL; 1142 status = U_ZERO_ERROR; 1143 } 1144 } 1145 fCurrencyAffixInfo.set( 1146 fSymbols->getLocale().getName(), fRules, currency, status); 1147 if (U_FAILURE(status)) { 1148 return; 1149 } 1150 UBool customCurrencySymbol = FALSE; 1151 // If DecimalFormatSymbols has custom currency symbol, prefer 1152 // that over what we just read from the resource bundles 1153 if (fSymbols->isCustomCurrencySymbol()) { 1154 fCurrencyAffixInfo.setSymbol( 1155 fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol)); 1156 customCurrencySymbol = TRUE; 1157 } 1158 if (fSymbols->isCustomIntlCurrencySymbol()) { 1159 fCurrencyAffixInfo.setISO( 1160 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 1161 customCurrencySymbol = TRUE; 1162 } 1163 changedFormattingFields |= kFormattingCurrencyAffixInfo; 1164 if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) { 1165 FixedPrecision precision; 1166 CurrencyAffixInfo::adjustPrecision( 1167 currency, fCurrencyUsage, precision, status); 1168 if (U_FAILURE(status)) { 1169 return; 1170 } 1171 fSuper->NumberFormat::setMinimumFractionDigits( 1172 precision.fMin.getFracDigitCount()); 1173 fSuper->NumberFormat::setMaximumFractionDigits( 1174 precision.fMax.getFracDigitCount()); 1175 updatePrecision(); 1176 fEffPrecision.fMantissa.fRoundingIncrement = 1177 precision.fRoundingIncrement; 1178 } 1179 1180 } 1181 } 1182 1183 void 1184 DecimalFormatImpl::updateFormattingFixedPointFormatter( 1185 int32_t &changedFormattingFields) { 1186 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) { 1187 // No work to do if fSymbols is unchanged 1188 return; 1189 } 1190 if (fMonetary) { 1191 fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols); 1192 } else { 1193 fFormatter.setDecimalFormatSymbols(*fSymbols); 1194 } 1195 } 1196 1197 void 1198 DecimalFormatImpl::updateFormattingAffixParser( 1199 int32_t &changedFormattingFields) { 1200 if ((changedFormattingFields & kFormattingSymbols) == 0) { 1201 // No work to do if fSymbols is unchanged 1202 return; 1203 } 1204 fAffixParser.setDecimalFormatSymbols(*fSymbols); 1205 changedFormattingFields |= kFormattingAffixParser; 1206 } 1207 1208 void 1209 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix( 1210 int32_t &changedFormattingFields, UErrorCode &status) { 1211 if (U_FAILURE(status)) { 1212 return; 1213 } 1214 if ((changedFormattingFields & ( 1215 kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) { 1216 // No work to do 1217 return; 1218 } 1219 fAffixes.fPositivePrefix.remove(); 1220 fAffixParser.parse( 1221 fPositivePrefixPattern, 1222 fCurrencyAffixInfo, 1223 fAffixes.fPositivePrefix, 1224 status); 1225 } 1226 1227 void 1228 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix( 1229 int32_t &changedFormattingFields, UErrorCode &status) { 1230 if (U_FAILURE(status)) { 1231 return; 1232 } 1233 if ((changedFormattingFields & ( 1234 kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) { 1235 // No work to do 1236 return; 1237 } 1238 fAffixes.fPositiveSuffix.remove(); 1239 fAffixParser.parse( 1240 fPositiveSuffixPattern, 1241 fCurrencyAffixInfo, 1242 fAffixes.fPositiveSuffix, 1243 status); 1244 } 1245 1246 void 1247 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix( 1248 int32_t &changedFormattingFields, UErrorCode &status) { 1249 if (U_FAILURE(status)) { 1250 return; 1251 } 1252 if ((changedFormattingFields & ( 1253 kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) { 1254 // No work to do 1255 return; 1256 } 1257 fAffixes.fNegativePrefix.remove(); 1258 fAffixParser.parse( 1259 fNegativePrefixPattern, 1260 fCurrencyAffixInfo, 1261 fAffixes.fNegativePrefix, 1262 status); 1263 } 1264 1265 void 1266 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix( 1267 int32_t &changedFormattingFields, UErrorCode &status) { 1268 if (U_FAILURE(status)) { 1269 return; 1270 } 1271 if ((changedFormattingFields & ( 1272 kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) { 1273 // No work to do 1274 return; 1275 } 1276 fAffixes.fNegativeSuffix.remove(); 1277 fAffixParser.parse( 1278 fNegativeSuffixPattern, 1279 fCurrencyAffixInfo, 1280 fAffixes.fNegativeSuffix, 1281 status); 1282 } 1283 1284 void 1285 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision( 1286 UErrorCode &status) { 1287 updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status); 1288 } 1289 1290 void 1291 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) { 1292 updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status); 1293 } 1294 1295 void 1296 DecimalFormatImpl::updateAll(UErrorCode &status) { 1297 updateAll(kFormattingAll, TRUE, status); 1298 } 1299 1300 void 1301 DecimalFormatImpl::updateAll( 1302 int32_t formattingFlags, 1303 UBool updatePrecisionBasedOnCurrency, 1304 UErrorCode &status) { 1305 if (U_FAILURE(status)) { 1306 return; 1307 } 1308 updatePrecision(); 1309 updateGrouping(); 1310 updateFormatting( 1311 formattingFlags, updatePrecisionBasedOnCurrency, status); 1312 setMultiplierScale(getPatternScale()); 1313 } 1314 1315 1316 static int32_t 1317 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) { 1318 if (grouping.fGrouping <= 0) { 1319 return 0; 1320 } 1321 if (grouping.fGrouping2 <= 0) { 1322 return grouping.fGrouping + 1; 1323 } 1324 return grouping.fGrouping + grouping.fGrouping2 + 1; 1325 } 1326 1327 /** 1328 * Given a grouping policy, calculates how many digits are needed left of 1329 * the decimal point to achieve a desired length left of the 1330 * decimal point. 1331 * @param grouping the grouping policy 1332 * @param desiredLength number of characters needed left of decimal point 1333 * @param minLeftDigits at least this many digits is returned 1334 * @param leftDigits the number of digits needed stored here 1335 * which is >= minLeftDigits. 1336 * @return true if a perfect fit or false if having leftDigits would exceed 1337 * desiredLength 1338 */ 1339 static UBool 1340 getLeftDigitsForLeftLength( 1341 const DigitGrouping &grouping, 1342 int32_t desiredLength, 1343 int32_t minLeftDigits, 1344 int32_t &leftDigits) { 1345 leftDigits = minLeftDigits; 1346 int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits); 1347 while (lengthSoFar < desiredLength) { 1348 lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1; 1349 ++leftDigits; 1350 } 1351 return (lengthSoFar == desiredLength); 1352 } 1353 1354 int32_t 1355 DecimalFormatImpl::computeExponentPatternLength() const { 1356 if (fUseScientific) { 1357 return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits; 1358 } 1359 return 0; 1360 } 1361 1362 int32_t 1363 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength( 1364 int32_t fracDigitCount) const { 1365 if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) { 1366 return 0; 1367 } 1368 return fracDigitCount + 1; 1369 } 1370 1371 UnicodeString& 1372 DecimalFormatImpl::toNumberPattern( 1373 UBool hasPadding, int32_t minimumLength, UnicodeString& result) const { 1374 // Get a grouping policy like the one in this object that does not 1375 // have minimum grouping since toPattern doesn't support it. 1376 DigitGrouping grouping(fEffGrouping); 1377 grouping.fMinGrouping = 0; 1378 1379 // Only for fixed digits, these are the digits that get 0's. 1380 DigitInterval minInterval; 1381 1382 // Only for fixed digits, these are the digits that get #'s. 1383 DigitInterval maxInterval; 1384 1385 // Only for significant digits 1386 int32_t sigMin = 0; /* initialize to avoid compiler warning */ 1387 int32_t sigMax = 0; /* initialize to avoid compiler warning */ 1388 1389 // These are all the digits to be displayed. For significant digits, 1390 // this interval always starts at the 1's place an extends left. 1391 DigitInterval fullInterval; 1392 1393 // Digit range of rounding increment. If rounding increment is .025. 1394 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1 1395 int32_t roundingIncrementLowerExp = 0; 1396 int32_t roundingIncrementUpperExp = 0; 1397 1398 if (fUseSigDigits) { 1399 SignificantDigitInterval sigInterval; 1400 extractSigDigits(sigInterval); 1401 sigMax = sigInterval.getMax(); 1402 sigMin = sigInterval.getMin(); 1403 fullInterval.setFracDigitCount(0); 1404 fullInterval.setIntDigitCount(sigMax); 1405 } else { 1406 extractMinMaxDigits(minInterval, maxInterval); 1407 if (fUseScientific) { 1408 if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) { 1409 maxInterval.setIntDigitCount(1); 1410 minInterval.shrinkToFitWithin(maxInterval); 1411 } 1412 } else if (hasPadding) { 1413 // Make max int digits match min int digits for now, we 1414 // compute necessary padding later. 1415 maxInterval.setIntDigitCount(minInterval.getIntDigitCount()); 1416 } else { 1417 // For some reason toPattern adds at least one leading '#' 1418 maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1); 1419 } 1420 if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) { 1421 roundingIncrementLowerExp = 1422 fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent(); 1423 roundingIncrementUpperExp = 1424 fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent(); 1425 // We have to include the rounding increment in what we display 1426 maxInterval.expandToContainDigit(roundingIncrementLowerExp); 1427 maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1); 1428 } 1429 fullInterval = maxInterval; 1430 } 1431 // We have to include enough digits to show grouping strategy 1432 int32_t minLengthToDescribeGrouping = 1433 getMinimumLengthToDescribeGrouping(grouping); 1434 if (minLengthToDescribeGrouping > 0) { 1435 fullInterval.expandToContainDigit( 1436 getMinimumLengthToDescribeGrouping(grouping) - 1); 1437 } 1438 1439 // If we have a minimum length, we have to add digits to the left to 1440 // depict padding. 1441 if (hasPadding) { 1442 // For non scientific notation, 1443 // minimumLengthForMantissa = minimumLength 1444 int32_t minimumLengthForMantissa = 1445 minimumLength - computeExponentPatternLength(); 1446 int32_t mininumLengthForMantissaIntPart = 1447 minimumLengthForMantissa 1448 - countFractionDigitAndDecimalPatternLength( 1449 fullInterval.getFracDigitCount()); 1450 // Because of grouping, we may need fewer than expected digits to 1451 // achieve the length we need. 1452 int32_t digitsNeeded; 1453 if (getLeftDigitsForLeftLength( 1454 grouping, 1455 mininumLengthForMantissaIntPart, 1456 fullInterval.getIntDigitCount(), 1457 digitsNeeded)) { 1458 1459 // In this case, we achieved the exact length that we want. 1460 fullInterval.setIntDigitCount(digitsNeeded); 1461 } else if (digitsNeeded > fullInterval.getIntDigitCount()) { 1462 1463 // Having digitsNeeded digits goes over desired length which 1464 // means that to have desired length would mean starting on a 1465 // grouping sepearator e.g ,###,### so add a '#' and use one 1466 // less digit. This trick gives ####,### but that is the best 1467 // we can do. 1468 result.append(kPatternDigit); 1469 fullInterval.setIntDigitCount(digitsNeeded - 1); 1470 } 1471 } 1472 int32_t maxDigitPos = fullInterval.getMostSignificantExclusive(); 1473 int32_t minDigitPos = fullInterval.getLeastSignificantInclusive(); 1474 for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) { 1475 if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) { 1476 result.append(kPatternDecimalSeparator); 1477 } 1478 if (fUseSigDigits) { 1479 // Use digit symbol 1480 if (i >= sigMax || i < sigMax - sigMin) { 1481 result.append(kPatternDigit); 1482 } else { 1483 result.append(kPatternSignificantDigit); 1484 } 1485 } else { 1486 if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) { 1487 result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit)); 1488 } else if (minInterval.contains(i)) { 1489 result.append(kPatternZeroDigit); 1490 } else { 1491 result.append(kPatternDigit); 1492 } 1493 } 1494 if (grouping.isSeparatorAt(i + 1, i)) { 1495 result.append(kPatternGroupingSeparator); 1496 } 1497 if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) { 1498 result.append(kPatternDecimalSeparator); 1499 } 1500 } 1501 if (fUseScientific) { 1502 result.append(kPatternExponent); 1503 if (fOptions.fExponent.fAlwaysShowSign) { 1504 result.append(kPatternPlus); 1505 } 1506 for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) { 1507 result.append(kPatternZeroDigit); 1508 } 1509 } 1510 return result; 1511 } 1512 1513 UnicodeString& 1514 DecimalFormatImpl::toPattern(UnicodeString& result) const { 1515 result.remove(); 1516 UnicodeString padSpec; 1517 if (fAffixes.fWidth > 0) { 1518 padSpec.append(kPatternPadEscape); 1519 padSpec.append(fAffixes.fPadChar); 1520 } 1521 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { 1522 result.append(padSpec); 1523 } 1524 fPositivePrefixPattern.toUserString(result); 1525 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { 1526 result.append(padSpec); 1527 } 1528 toNumberPattern( 1529 fAffixes.fWidth > 0, 1530 fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(), 1531 result); 1532 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { 1533 result.append(padSpec); 1534 } 1535 fPositiveSuffixPattern.toUserString(result); 1536 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { 1537 result.append(padSpec); 1538 } 1539 AffixPattern withNegative; 1540 withNegative.add(AffixPattern::kNegative); 1541 withNegative.append(fPositivePrefixPattern); 1542 if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) || 1543 !withNegative.equals(fNegativePrefixPattern)) { 1544 result.append(kPatternSeparator); 1545 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { 1546 result.append(padSpec); 1547 } 1548 fNegativePrefixPattern.toUserString(result); 1549 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { 1550 result.append(padSpec); 1551 } 1552 toNumberPattern( 1553 fAffixes.fWidth > 0, 1554 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(), 1555 result); 1556 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { 1557 result.append(padSpec); 1558 } 1559 fNegativeSuffixPattern.toUserString(result); 1560 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { 1561 result.append(padSpec); 1562 } 1563 } 1564 return result; 1565 } 1566 1567 int32_t 1568 DecimalFormatImpl::getOldFormatWidth() const { 1569 if (fAffixes.fWidth == 0) { 1570 return 0; 1571 } 1572 return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32(); 1573 } 1574 1575 const UnicodeString & 1576 DecimalFormatImpl::getConstSymbol( 1577 DecimalFormatSymbols::ENumberFormatSymbol symbol) const { 1578 return fSymbols->getConstSymbol(symbol); 1579 } 1580 1581 UBool 1582 DecimalFormatImpl::isParseFastpath() const { 1583 AffixPattern negative; 1584 negative.add(AffixPattern::kNegative); 1585 1586 return fAffixes.fWidth == 0 && 1587 fPositivePrefixPattern.countChar32() == 0 && 1588 fNegativePrefixPattern.equals(negative) && 1589 fPositiveSuffixPattern.countChar32() == 0 && 1590 fNegativeSuffixPattern.countChar32() == 0; 1591 } 1592 1593 1594 U_NAMESPACE_END 1595 1596 #endif /* #if !UCONFIG_NO_FORMATTING */ 1597 1598