1 // Copyright (C) 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.isNanOrInfinity = digits.isNaNOrInfinity(); 525 digits.getFixedDecimal( 526 result.source, result.intValue, result.decimalDigits, 527 result.decimalDigitsWithoutTrailingZeros, 528 result.visibleDecimalDigitCount, result.hasIntegerValue); 529 return result; 530 } 531 532 FixedDecimal & 533 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const { 534 if (U_FAILURE(status)) { 535 return result; 536 } 537 VisibleDigits digits; 538 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); 539 return initFixedDecimal(digits, result); 540 } 541 542 FixedDecimal & 543 DecimalFormatImpl::getFixedDecimal( 544 DigitList &number, FixedDecimal &result, UErrorCode &status) const { 545 if (U_FAILURE(status)) { 546 return result; 547 } 548 VisibleDigits digits; 549 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); 550 return initFixedDecimal(digits, result); 551 } 552 553 VisibleDigitsWithExponent & 554 DecimalFormatImpl::initVisibleDigitsWithExponent( 555 int64_t number, 556 VisibleDigitsWithExponent &digits, 557 UErrorCode &status) const { 558 if (maybeInitVisibleDigitsFromDigitList( 559 number, digits, status)) { 560 return digits; 561 } 562 if (fUseScientific) { 563 fEffPrecision.initVisibleDigitsWithExponent( 564 number, digits, status); 565 } else { 566 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 567 number, digits, status); 568 } 569 return digits; 570 } 571 572 VisibleDigitsWithExponent & 573 DecimalFormatImpl::initVisibleDigitsWithExponent( 574 double number, 575 VisibleDigitsWithExponent &digits, 576 UErrorCode &status) const { 577 if (maybeInitVisibleDigitsFromDigitList( 578 number, digits, status)) { 579 return digits; 580 } 581 if (fUseScientific) { 582 fEffPrecision.initVisibleDigitsWithExponent( 583 number, digits, status); 584 } else { 585 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 586 number, digits, status); 587 } 588 return digits; 589 } 590 591 VisibleDigitsWithExponent & 592 DecimalFormatImpl::initVisibleDigitsWithExponent( 593 DigitList &number, 594 VisibleDigitsWithExponent &digits, 595 UErrorCode &status) const { 596 adjustDigitList(number, status); 597 return initVisibleDigitsFromAdjusted(number, digits, status); 598 } 599 600 VisibleDigitsWithExponent & 601 DecimalFormatImpl::initVisibleDigitsFromAdjusted( 602 DigitList &number, 603 VisibleDigitsWithExponent &digits, 604 UErrorCode &status) const { 605 if (fUseScientific) { 606 fEffPrecision.initVisibleDigitsWithExponent( 607 number, digits, status); 608 } else { 609 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( 610 number, digits, status); 611 } 612 return digits; 613 } 614 615 DigitList & 616 DecimalFormatImpl::round( 617 DigitList &number, UErrorCode &status) const { 618 if (number.isNaN() || number.isInfinite()) { 619 return number; 620 } 621 adjustDigitList(number, status); 622 ValueFormatter vf; 623 prepareValueFormatter(vf); 624 return vf.round(number, status); 625 } 626 627 void 628 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) { 629 fMinSigDigits = newValue; 630 fUseSigDigits = TRUE; // ticket 9936 631 updatePrecision(); 632 } 633 634 void 635 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) { 636 fMaxSigDigits = newValue; 637 fUseSigDigits = TRUE; // ticket 9936 638 updatePrecision(); 639 } 640 641 void 642 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) { 643 fMinSigDigits = min; 644 fMaxSigDigits = max; 645 fUseSigDigits = TRUE; // ticket 9936 646 updatePrecision(); 647 } 648 649 void 650 DecimalFormatImpl::setScientificNotation(UBool newValue) { 651 fUseScientific = newValue; 652 updatePrecision(); 653 } 654 655 void 656 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) { 657 fUseSigDigits = newValue; 658 updatePrecision(); 659 } 660 661 void 662 DecimalFormatImpl::setGroupingSize(int32_t newValue) { 663 fGrouping.fGrouping = newValue; 664 updateGrouping(); 665 } 666 667 void 668 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) { 669 fGrouping.fGrouping2 = newValue; 670 updateGrouping(); 671 } 672 673 void 674 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) { 675 fGrouping.fMinGrouping = newValue; 676 updateGrouping(); 677 } 678 679 void 680 DecimalFormatImpl::setCurrencyUsage( 681 UCurrencyUsage currencyUsage, UErrorCode &status) { 682 fCurrencyUsage = currencyUsage; 683 updateFormatting(kFormattingCurrency, status); 684 } 685 686 void 687 DecimalFormatImpl::setRoundingIncrement(double d) { 688 if (d > 0.0) { 689 fEffPrecision.fMantissa.fRoundingIncrement.set(d); 690 } else { 691 fEffPrecision.fMantissa.fRoundingIncrement.set(0.0); 692 } 693 } 694 695 double 696 DecimalFormatImpl::getRoundingIncrement() const { 697 return fEffPrecision.fMantissa.fRoundingIncrement.getDouble(); 698 } 699 700 int32_t 701 DecimalFormatImpl::getMultiplier() const { 702 if (fMultiplier.isZero()) { 703 return 1; 704 } 705 return (int32_t) fMultiplier.getDouble(); 706 } 707 708 void 709 DecimalFormatImpl::setMultiplier(int32_t m) { 710 if (m == 0 || m == 1) { 711 fMultiplier.set((int32_t)0); 712 } else { 713 fMultiplier.set(m); 714 } 715 } 716 717 void 718 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) { 719 fPositivePrefixPattern.remove(); 720 fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); 721 UErrorCode status = U_ZERO_ERROR; 722 updateFormatting(kFormattingPosPrefix, status); 723 } 724 725 void 726 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) { 727 fPositiveSuffixPattern.remove(); 728 fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); 729 UErrorCode status = U_ZERO_ERROR; 730 updateFormatting(kFormattingPosSuffix, status); 731 } 732 733 void 734 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) { 735 fNegativePrefixPattern.remove(); 736 fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); 737 UErrorCode status = U_ZERO_ERROR; 738 updateFormatting(kFormattingNegPrefix, status); 739 } 740 741 void 742 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) { 743 fNegativeSuffixPattern.remove(); 744 fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); 745 UErrorCode status = U_ZERO_ERROR; 746 updateFormatting(kFormattingNegSuffix, status); 747 } 748 749 UnicodeString & 750 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const { 751 result = fAffixes.fPositivePrefix.getOtherVariant().toString(); 752 return result; 753 } 754 755 UnicodeString & 756 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const { 757 result = fAffixes.fPositiveSuffix.getOtherVariant().toString(); 758 return result; 759 } 760 761 UnicodeString & 762 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const { 763 result = fAffixes.fNegativePrefix.getOtherVariant().toString(); 764 return result; 765 } 766 767 UnicodeString & 768 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const { 769 result = fAffixes.fNegativeSuffix.getOtherVariant().toString(); 770 return result; 771 } 772 773 void 774 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) { 775 if (symbolsToAdopt == NULL) { 776 return; 777 } 778 delete fSymbols; 779 fSymbols = symbolsToAdopt; 780 UErrorCode status = U_ZERO_ERROR; 781 updateFormatting(kFormattingSymbols, status); 782 } 783 784 void 785 DecimalFormatImpl::applyPatternFavorCurrencyPrecision( 786 const UnicodeString &pattern, UErrorCode &status) { 787 UParseError perror; 788 applyPattern(pattern, FALSE, perror, status); 789 updateForApplyPatternFavorCurrencyPrecision(status); 790 } 791 792 void 793 DecimalFormatImpl::applyPattern( 794 const UnicodeString &pattern, UErrorCode &status) { 795 UParseError perror; 796 applyPattern(pattern, FALSE, perror, status); 797 updateForApplyPattern(status); 798 } 799 800 void 801 DecimalFormatImpl::applyPattern( 802 const UnicodeString &pattern, 803 UParseError &perror, UErrorCode &status) { 804 applyPattern(pattern, FALSE, perror, status); 805 updateForApplyPattern(status); 806 } 807 808 void 809 DecimalFormatImpl::applyLocalizedPattern( 810 const UnicodeString &pattern, UErrorCode &status) { 811 UParseError perror; 812 applyPattern(pattern, TRUE, perror, status); 813 updateForApplyPattern(status); 814 } 815 816 void 817 DecimalFormatImpl::applyLocalizedPattern( 818 const UnicodeString &pattern, 819 UParseError &perror, UErrorCode &status) { 820 applyPattern(pattern, TRUE, perror, status); 821 updateForApplyPattern(status); 822 } 823 824 void 825 DecimalFormatImpl::applyPattern( 826 const UnicodeString &pattern, 827 UBool localized, UParseError &perror, UErrorCode &status) { 828 if (U_FAILURE(status)) { 829 return; 830 } 831 DecimalFormatPatternParser patternParser; 832 if (localized) { 833 patternParser.useSymbols(*fSymbols); 834 } 835 DecimalFormatPattern out; 836 patternParser.applyPatternWithoutExpandAffix( 837 pattern, out, perror, status); 838 if (U_FAILURE(status)) { 839 return; 840 } 841 fUseScientific = out.fUseExponentialNotation; 842 fUseSigDigits = out.fUseSignificantDigits; 843 fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits); 844 fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits); 845 fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits); 846 fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits); 847 fMinSigDigits = out.fMinimumSignificantDigits; 848 fMaxSigDigits = out.fMaximumSignificantDigits; 849 fEffPrecision.fMinExponentDigits = out.fMinExponentDigits; 850 fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown; 851 fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed); 852 fGrouping.fGrouping = out.fGroupingSize; 853 fGrouping.fGrouping2 = out.fGroupingSize2; 854 fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown; 855 if (out.fRoundingIncrementUsed) { 856 fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement; 857 } else { 858 fEffPrecision.fMantissa.fRoundingIncrement.clear(); 859 } 860 fAffixes.fPadChar = out.fPad; 861 fNegativePrefixPattern = out.fNegPrefixAffix; 862 fNegativeSuffixPattern = out.fNegSuffixAffix; 863 fPositivePrefixPattern = out.fPosPrefixAffix; 864 fPositiveSuffixPattern = out.fPosSuffixAffix; 865 866 // Work around. Pattern parsing code and DecimalFormat code don't agree 867 // on the definition of field width, so we have to translate from 868 // pattern field width to decimal format field width here. 869 fAffixes.fWidth = out.fFormatWidth == 0 ? 0 : 870 out.fFormatWidth + fPositivePrefixPattern.countChar32() 871 + fPositiveSuffixPattern.countChar32(); 872 switch (out.fPadPosition) { 873 case DecimalFormatPattern::kPadBeforePrefix: 874 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix; 875 break; 876 case DecimalFormatPattern::kPadAfterPrefix: 877 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix; 878 break; 879 case DecimalFormatPattern::kPadBeforeSuffix: 880 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix; 881 break; 882 case DecimalFormatPattern::kPadAfterSuffix: 883 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix; 884 break; 885 default: 886 break; 887 } 888 } 889 890 void 891 DecimalFormatImpl::updatePrecision() { 892 if (fUseScientific) { 893 updatePrecisionForScientific(); 894 } else { 895 updatePrecisionForFixed(); 896 } 897 } 898 899 static void updatePrecisionForScientificMinMax( 900 const DigitInterval &min, 901 const DigitInterval &max, 902 DigitInterval &resultMin, 903 DigitInterval &resultMax, 904 SignificantDigitInterval &resultSignificant) { 905 resultMin.setIntDigitCount(0); 906 resultMin.setFracDigitCount(0); 907 resultSignificant.clear(); 908 resultMax.clear(); 909 910 int32_t maxIntDigitCount = max.getIntDigitCount(); 911 int32_t minIntDigitCount = min.getIntDigitCount(); 912 int32_t maxFracDigitCount = max.getFracDigitCount(); 913 int32_t minFracDigitCount = min.getFracDigitCount(); 914 915 916 // Not in spec: maxIntDigitCount > 8 assume 917 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has 918 // no provision for unsetting maxIntDigitCount which would be useful for 919 // scientific notation. The best we can do is assume that if 920 // maxIntDigitCount is the default of 2000000000 or is "big enough" then 921 // user did not intend to explicitly set it. The 8 was derived emperically 922 // by extensive testing of legacy code. 923 if (maxIntDigitCount > 8) { 924 maxIntDigitCount = minIntDigitCount; 925 } 926 927 // Per the spec, exponent grouping happens if maxIntDigitCount is more 928 // than 1 and more than minIntDigitCount. 929 UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount; 930 if (bExponentGrouping) { 931 resultMax.setIntDigitCount(maxIntDigitCount); 932 933 // For exponent grouping minIntDigits is always treated as 1 even 934 // if it wasn't set to 1! 935 resultMin.setIntDigitCount(1); 936 } else { 937 // Fixed digit count left of decimal. minIntDigitCount doesn't have 938 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while 939 // maxIntDigitCount == 1. 940 int32_t fixedIntDigitCount = maxIntDigitCount; 941 942 // If fixedIntDigitCount is 0 but 943 // min or max fraction count is 0 too then use 1. This way we can get 944 // unlimited precision for X.XXXEX 945 if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) { 946 fixedIntDigitCount = 1; 947 } 948 resultMax.setIntDigitCount(fixedIntDigitCount); 949 resultMin.setIntDigitCount(fixedIntDigitCount); 950 } 951 // Spec says this is how we compute significant digits. 0 means 952 // unlimited significant digits. 953 int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount; 954 if (maxSigDigits > 0) { 955 int32_t minSigDigits = minIntDigitCount + minFracDigitCount; 956 resultSignificant.setMin(minSigDigits); 957 resultSignificant.setMax(maxSigDigits); 958 } 959 } 960 961 void 962 DecimalFormatImpl::updatePrecisionForScientific() { 963 FixedPrecision *result = &fEffPrecision.fMantissa; 964 if (fUseSigDigits) { 965 result->fMax.setFracDigitCount(-1); 966 result->fMax.setIntDigitCount(1); 967 result->fMin.setFracDigitCount(0); 968 result->fMin.setIntDigitCount(1); 969 result->fSignificant.clear(); 970 extractSigDigits(result->fSignificant); 971 return; 972 } 973 DigitInterval max; 974 DigitInterval min; 975 extractMinMaxDigits(min, max); 976 updatePrecisionForScientificMinMax( 977 min, max, 978 result->fMin, result->fMax, result->fSignificant); 979 } 980 981 void 982 DecimalFormatImpl::updatePrecisionForFixed() { 983 FixedPrecision *result = &fEffPrecision.fMantissa; 984 if (!fUseSigDigits) { 985 extractMinMaxDigits(result->fMin, result->fMax); 986 result->fSignificant.clear(); 987 } else { 988 extractSigDigits(result->fSignificant); 989 result->fMin.setIntDigitCount(1); 990 result->fMin.setFracDigitCount(0); 991 result->fMax.clear(); 992 } 993 } 994 995 void 996 DecimalFormatImpl::extractMinMaxDigits( 997 DigitInterval &min, DigitInterval &max) const { 998 min.setIntDigitCount(fSuper->getMinimumIntegerDigits()); 999 max.setIntDigitCount(fSuper->getMaximumIntegerDigits()); 1000 min.setFracDigitCount(fSuper->getMinimumFractionDigits()); 1001 max.setFracDigitCount(fSuper->getMaximumFractionDigits()); 1002 } 1003 1004 void 1005 DecimalFormatImpl::extractSigDigits( 1006 SignificantDigitInterval &sig) const { 1007 sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits); 1008 sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits); 1009 } 1010 1011 void 1012 DecimalFormatImpl::updateGrouping() { 1013 if (fSuper->isGroupingUsed()) { 1014 fEffGrouping = fGrouping; 1015 } else { 1016 fEffGrouping.clear(); 1017 } 1018 } 1019 1020 void 1021 DecimalFormatImpl::updateCurrency(UErrorCode &status) { 1022 updateFormatting(kFormattingCurrency, TRUE, status); 1023 } 1024 1025 void 1026 DecimalFormatImpl::updateFormatting( 1027 int32_t changedFormattingFields, 1028 UErrorCode &status) { 1029 updateFormatting(changedFormattingFields, TRUE, status); 1030 } 1031 1032 void 1033 DecimalFormatImpl::updateFormatting( 1034 int32_t changedFormattingFields, 1035 UBool updatePrecisionBasedOnCurrency, 1036 UErrorCode &status) { 1037 if (U_FAILURE(status)) { 1038 return; 1039 } 1040 // Each function updates one field. Order matters. For instance, 1041 // updatePluralRules comes before updateCurrencyAffixInfo because the 1042 // fRules field is needed to update the fCurrencyAffixInfo field. 1043 updateFormattingUsesCurrency(changedFormattingFields); 1044 updateFormattingFixedPointFormatter(changedFormattingFields); 1045 updateFormattingAffixParser(changedFormattingFields); 1046 updateFormattingPluralRules(changedFormattingFields, status); 1047 updateFormattingCurrencyAffixInfo( 1048 changedFormattingFields, 1049 updatePrecisionBasedOnCurrency, 1050 status); 1051 updateFormattingLocalizedPositivePrefix( 1052 changedFormattingFields, status); 1053 updateFormattingLocalizedPositiveSuffix( 1054 changedFormattingFields, status); 1055 updateFormattingLocalizedNegativePrefix( 1056 changedFormattingFields, status); 1057 updateFormattingLocalizedNegativeSuffix( 1058 changedFormattingFields, status); 1059 } 1060 1061 void 1062 DecimalFormatImpl::updateFormattingUsesCurrency( 1063 int32_t &changedFormattingFields) { 1064 if ((changedFormattingFields & kFormattingAffixes) == 0) { 1065 // If no affixes changed, don't need to do any work 1066 return; 1067 } 1068 UBool newUsesCurrency = 1069 fPositivePrefixPattern.usesCurrency() || 1070 fPositiveSuffixPattern.usesCurrency() || 1071 fNegativePrefixPattern.usesCurrency() || 1072 fNegativeSuffixPattern.usesCurrency(); 1073 if (fMonetary != newUsesCurrency) { 1074 fMonetary = newUsesCurrency; 1075 changedFormattingFields |= kFormattingUsesCurrency; 1076 } 1077 } 1078 1079 void 1080 DecimalFormatImpl::updateFormattingPluralRules( 1081 int32_t &changedFormattingFields, UErrorCode &status) { 1082 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) { 1083 // No work to do if both fSymbols and fMonetary 1084 // fields are unchanged 1085 return; 1086 } 1087 if (U_FAILURE(status)) { 1088 return; 1089 } 1090 PluralRules *newRules = NULL; 1091 if (fMonetary) { 1092 newRules = PluralRules::forLocale(fSymbols->getLocale(), status); 1093 if (U_FAILURE(status)) { 1094 return; 1095 } 1096 } 1097 // Its ok to say a field has changed when it really hasn't but not 1098 // the other way around. Here we assume the field changed unless it 1099 // was NULL before and is still NULL now 1100 if (fRules != newRules) { 1101 delete fRules; 1102 fRules = newRules; 1103 changedFormattingFields |= kFormattingPluralRules; 1104 } 1105 } 1106 1107 void 1108 DecimalFormatImpl::updateFormattingCurrencyAffixInfo( 1109 int32_t &changedFormattingFields, 1110 UBool updatePrecisionBasedOnCurrency, 1111 UErrorCode &status) { 1112 if ((changedFormattingFields & ( 1113 kFormattingSymbols | kFormattingCurrency | 1114 kFormattingUsesCurrency | kFormattingPluralRules)) == 0) { 1115 // If all these fields are unchanged, no work to do. 1116 return; 1117 } 1118 if (U_FAILURE(status)) { 1119 return; 1120 } 1121 if (!fMonetary) { 1122 if (fCurrencyAffixInfo.isDefault()) { 1123 // In this case don't have to do any work 1124 return; 1125 } 1126 fCurrencyAffixInfo.set(NULL, NULL, NULL, status); 1127 if (U_FAILURE(status)) { 1128 return; 1129 } 1130 changedFormattingFields |= kFormattingCurrencyAffixInfo; 1131 } else { 1132 const UChar *currency = fSuper->getCurrency(); 1133 UChar localeCurr[4]; 1134 if (currency[0] == 0) { 1135 ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status); 1136 if (U_SUCCESS(status)) { 1137 currency = localeCurr; 1138 fSuper->NumberFormat::setCurrency(currency, status); 1139 } else { 1140 currency = NULL; 1141 status = U_ZERO_ERROR; 1142 } 1143 } 1144 fCurrencyAffixInfo.set( 1145 fSymbols->getLocale().getName(), fRules, currency, status); 1146 if (U_FAILURE(status)) { 1147 return; 1148 } 1149 UBool customCurrencySymbol = FALSE; 1150 // If DecimalFormatSymbols has custom currency symbol, prefer 1151 // that over what we just read from the resource bundles 1152 if (fSymbols->isCustomCurrencySymbol()) { 1153 fCurrencyAffixInfo.setSymbol( 1154 fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol)); 1155 customCurrencySymbol = TRUE; 1156 } 1157 if (fSymbols->isCustomIntlCurrencySymbol()) { 1158 fCurrencyAffixInfo.setISO( 1159 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 1160 customCurrencySymbol = TRUE; 1161 } 1162 changedFormattingFields |= kFormattingCurrencyAffixInfo; 1163 if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) { 1164 FixedPrecision precision; 1165 CurrencyAffixInfo::adjustPrecision( 1166 currency, fCurrencyUsage, precision, status); 1167 if (U_FAILURE(status)) { 1168 return; 1169 } 1170 fSuper->NumberFormat::setMinimumFractionDigits( 1171 precision.fMin.getFracDigitCount()); 1172 fSuper->NumberFormat::setMaximumFractionDigits( 1173 precision.fMax.getFracDigitCount()); 1174 updatePrecision(); 1175 fEffPrecision.fMantissa.fRoundingIncrement = 1176 precision.fRoundingIncrement; 1177 } 1178 1179 } 1180 } 1181 1182 void 1183 DecimalFormatImpl::updateFormattingFixedPointFormatter( 1184 int32_t &changedFormattingFields) { 1185 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) { 1186 // No work to do if fSymbols is unchanged 1187 return; 1188 } 1189 if (fMonetary) { 1190 fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols); 1191 } else { 1192 fFormatter.setDecimalFormatSymbols(*fSymbols); 1193 } 1194 } 1195 1196 void 1197 DecimalFormatImpl::updateFormattingAffixParser( 1198 int32_t &changedFormattingFields) { 1199 if ((changedFormattingFields & kFormattingSymbols) == 0) { 1200 // No work to do if fSymbols is unchanged 1201 return; 1202 } 1203 fAffixParser.setDecimalFormatSymbols(*fSymbols); 1204 changedFormattingFields |= kFormattingAffixParser; 1205 } 1206 1207 void 1208 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix( 1209 int32_t &changedFormattingFields, UErrorCode &status) { 1210 if (U_FAILURE(status)) { 1211 return; 1212 } 1213 if ((changedFormattingFields & ( 1214 kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) { 1215 // No work to do 1216 return; 1217 } 1218 fAffixes.fPositivePrefix.remove(); 1219 fAffixParser.parse( 1220 fPositivePrefixPattern, 1221 fCurrencyAffixInfo, 1222 fAffixes.fPositivePrefix, 1223 status); 1224 } 1225 1226 void 1227 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix( 1228 int32_t &changedFormattingFields, UErrorCode &status) { 1229 if (U_FAILURE(status)) { 1230 return; 1231 } 1232 if ((changedFormattingFields & ( 1233 kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) { 1234 // No work to do 1235 return; 1236 } 1237 fAffixes.fPositiveSuffix.remove(); 1238 fAffixParser.parse( 1239 fPositiveSuffixPattern, 1240 fCurrencyAffixInfo, 1241 fAffixes.fPositiveSuffix, 1242 status); 1243 } 1244 1245 void 1246 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix( 1247 int32_t &changedFormattingFields, UErrorCode &status) { 1248 if (U_FAILURE(status)) { 1249 return; 1250 } 1251 if ((changedFormattingFields & ( 1252 kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) { 1253 // No work to do 1254 return; 1255 } 1256 fAffixes.fNegativePrefix.remove(); 1257 fAffixParser.parse( 1258 fNegativePrefixPattern, 1259 fCurrencyAffixInfo, 1260 fAffixes.fNegativePrefix, 1261 status); 1262 } 1263 1264 void 1265 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix( 1266 int32_t &changedFormattingFields, UErrorCode &status) { 1267 if (U_FAILURE(status)) { 1268 return; 1269 } 1270 if ((changedFormattingFields & ( 1271 kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) { 1272 // No work to do 1273 return; 1274 } 1275 fAffixes.fNegativeSuffix.remove(); 1276 fAffixParser.parse( 1277 fNegativeSuffixPattern, 1278 fCurrencyAffixInfo, 1279 fAffixes.fNegativeSuffix, 1280 status); 1281 } 1282 1283 void 1284 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision( 1285 UErrorCode &status) { 1286 updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status); 1287 } 1288 1289 void 1290 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) { 1291 updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status); 1292 } 1293 1294 void 1295 DecimalFormatImpl::updateAll(UErrorCode &status) { 1296 updateAll(kFormattingAll, TRUE, status); 1297 } 1298 1299 void 1300 DecimalFormatImpl::updateAll( 1301 int32_t formattingFlags, 1302 UBool updatePrecisionBasedOnCurrency, 1303 UErrorCode &status) { 1304 if (U_FAILURE(status)) { 1305 return; 1306 } 1307 updatePrecision(); 1308 updateGrouping(); 1309 updateFormatting( 1310 formattingFlags, updatePrecisionBasedOnCurrency, status); 1311 setMultiplierScale(getPatternScale()); 1312 } 1313 1314 1315 static int32_t 1316 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) { 1317 if (grouping.fGrouping <= 0) { 1318 return 0; 1319 } 1320 if (grouping.fGrouping2 <= 0) { 1321 return grouping.fGrouping + 1; 1322 } 1323 return grouping.fGrouping + grouping.fGrouping2 + 1; 1324 } 1325 1326 /** 1327 * Given a grouping policy, calculates how many digits are needed left of 1328 * the decimal point to achieve a desired length left of the 1329 * decimal point. 1330 * @param grouping the grouping policy 1331 * @param desiredLength number of characters needed left of decimal point 1332 * @param minLeftDigits at least this many digits is returned 1333 * @param leftDigits the number of digits needed stored here 1334 * which is >= minLeftDigits. 1335 * @return true if a perfect fit or false if having leftDigits would exceed 1336 * desiredLength 1337 */ 1338 static UBool 1339 getLeftDigitsForLeftLength( 1340 const DigitGrouping &grouping, 1341 int32_t desiredLength, 1342 int32_t minLeftDigits, 1343 int32_t &leftDigits) { 1344 leftDigits = minLeftDigits; 1345 int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits); 1346 while (lengthSoFar < desiredLength) { 1347 lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1; 1348 ++leftDigits; 1349 } 1350 return (lengthSoFar == desiredLength); 1351 } 1352 1353 int32_t 1354 DecimalFormatImpl::computeExponentPatternLength() const { 1355 if (fUseScientific) { 1356 return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits; 1357 } 1358 return 0; 1359 } 1360 1361 int32_t 1362 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength( 1363 int32_t fracDigitCount) const { 1364 if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) { 1365 return 0; 1366 } 1367 return fracDigitCount + 1; 1368 } 1369 1370 UnicodeString& 1371 DecimalFormatImpl::toNumberPattern( 1372 UBool hasPadding, int32_t minimumLength, UnicodeString& result) const { 1373 // Get a grouping policy like the one in this object that does not 1374 // have minimum grouping since toPattern doesn't support it. 1375 DigitGrouping grouping(fEffGrouping); 1376 grouping.fMinGrouping = 0; 1377 1378 // Only for fixed digits, these are the digits that get 0's. 1379 DigitInterval minInterval; 1380 1381 // Only for fixed digits, these are the digits that get #'s. 1382 DigitInterval maxInterval; 1383 1384 // Only for significant digits 1385 int32_t sigMin; 1386 int32_t sigMax; 1387 1388 // These are all the digits to be displayed. For significant digits, 1389 // this interval always starts at the 1's place an extends left. 1390 DigitInterval fullInterval; 1391 1392 // Digit range of rounding increment. If rounding increment is .025. 1393 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1 1394 int32_t roundingIncrementLowerExp = 0; 1395 int32_t roundingIncrementUpperExp = 0; 1396 1397 if (fUseSigDigits) { 1398 SignificantDigitInterval sigInterval; 1399 extractSigDigits(sigInterval); 1400 sigMax = sigInterval.getMax(); 1401 sigMin = sigInterval.getMin(); 1402 fullInterval.setFracDigitCount(0); 1403 fullInterval.setIntDigitCount(sigMax); 1404 } else { 1405 extractMinMaxDigits(minInterval, maxInterval); 1406 if (fUseScientific) { 1407 if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) { 1408 maxInterval.setIntDigitCount(1); 1409 minInterval.shrinkToFitWithin(maxInterval); 1410 } 1411 } else if (hasPadding) { 1412 // Make max int digits match min int digits for now, we 1413 // compute necessary padding later. 1414 maxInterval.setIntDigitCount(minInterval.getIntDigitCount()); 1415 } else { 1416 // For some reason toPattern adds at least one leading '#' 1417 maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1); 1418 } 1419 if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) { 1420 roundingIncrementLowerExp = 1421 fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent(); 1422 roundingIncrementUpperExp = 1423 fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent(); 1424 // We have to include the rounding increment in what we display 1425 maxInterval.expandToContainDigit(roundingIncrementLowerExp); 1426 maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1); 1427 } 1428 fullInterval = maxInterval; 1429 } 1430 // We have to include enough digits to show grouping strategy 1431 int32_t minLengthToDescribeGrouping = 1432 getMinimumLengthToDescribeGrouping(grouping); 1433 if (minLengthToDescribeGrouping > 0) { 1434 fullInterval.expandToContainDigit( 1435 getMinimumLengthToDescribeGrouping(grouping) - 1); 1436 } 1437 1438 // If we have a minimum length, we have to add digits to the left to 1439 // depict padding. 1440 if (hasPadding) { 1441 // For non scientific notation, 1442 // minimumLengthForMantissa = minimumLength 1443 int32_t minimumLengthForMantissa = 1444 minimumLength - computeExponentPatternLength(); 1445 int32_t mininumLengthForMantissaIntPart = 1446 minimumLengthForMantissa 1447 - countFractionDigitAndDecimalPatternLength( 1448 fullInterval.getFracDigitCount()); 1449 // Because of grouping, we may need fewer than expected digits to 1450 // achieve the length we need. 1451 int32_t digitsNeeded; 1452 if (getLeftDigitsForLeftLength( 1453 grouping, 1454 mininumLengthForMantissaIntPart, 1455 fullInterval.getIntDigitCount(), 1456 digitsNeeded)) { 1457 1458 // In this case, we achieved the exact length that we want. 1459 fullInterval.setIntDigitCount(digitsNeeded); 1460 } else if (digitsNeeded > fullInterval.getIntDigitCount()) { 1461 1462 // Having digitsNeeded digits goes over desired length which 1463 // means that to have desired length would mean starting on a 1464 // grouping sepearator e.g ,###,### so add a '#' and use one 1465 // less digit. This trick gives ####,### but that is the best 1466 // we can do. 1467 result.append(kPatternDigit); 1468 fullInterval.setIntDigitCount(digitsNeeded - 1); 1469 } 1470 } 1471 int32_t maxDigitPos = fullInterval.getMostSignificantExclusive(); 1472 int32_t minDigitPos = fullInterval.getLeastSignificantInclusive(); 1473 for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) { 1474 if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) { 1475 result.append(kPatternDecimalSeparator); 1476 } 1477 if (fUseSigDigits) { 1478 // Use digit symbol 1479 if (i >= sigMax || i < sigMax - sigMin) { 1480 result.append(kPatternDigit); 1481 } else { 1482 result.append(kPatternSignificantDigit); 1483 } 1484 } else { 1485 if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) { 1486 result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit)); 1487 } else if (minInterval.contains(i)) { 1488 result.append(kPatternZeroDigit); 1489 } else { 1490 result.append(kPatternDigit); 1491 } 1492 } 1493 if (grouping.isSeparatorAt(i + 1, i)) { 1494 result.append(kPatternGroupingSeparator); 1495 } 1496 if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) { 1497 result.append(kPatternDecimalSeparator); 1498 } 1499 } 1500 if (fUseScientific) { 1501 result.append(kPatternExponent); 1502 if (fOptions.fExponent.fAlwaysShowSign) { 1503 result.append(kPatternPlus); 1504 } 1505 for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) { 1506 result.append(kPatternZeroDigit); 1507 } 1508 } 1509 return result; 1510 } 1511 1512 UnicodeString& 1513 DecimalFormatImpl::toPattern(UnicodeString& result) const { 1514 result.remove(); 1515 UnicodeString padSpec; 1516 if (fAffixes.fWidth > 0) { 1517 padSpec.append(kPatternPadEscape); 1518 padSpec.append(fAffixes.fPadChar); 1519 } 1520 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { 1521 result.append(padSpec); 1522 } 1523 fPositivePrefixPattern.toUserString(result); 1524 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { 1525 result.append(padSpec); 1526 } 1527 toNumberPattern( 1528 fAffixes.fWidth > 0, 1529 fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(), 1530 result); 1531 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { 1532 result.append(padSpec); 1533 } 1534 fPositiveSuffixPattern.toUserString(result); 1535 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { 1536 result.append(padSpec); 1537 } 1538 AffixPattern withNegative; 1539 withNegative.add(AffixPattern::kNegative); 1540 withNegative.append(fPositivePrefixPattern); 1541 if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) || 1542 !withNegative.equals(fNegativePrefixPattern)) { 1543 result.append(kPatternSeparator); 1544 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { 1545 result.append(padSpec); 1546 } 1547 fNegativePrefixPattern.toUserString(result); 1548 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { 1549 result.append(padSpec); 1550 } 1551 toNumberPattern( 1552 fAffixes.fWidth > 0, 1553 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(), 1554 result); 1555 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { 1556 result.append(padSpec); 1557 } 1558 fNegativeSuffixPattern.toUserString(result); 1559 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { 1560 result.append(padSpec); 1561 } 1562 } 1563 return result; 1564 } 1565 1566 int32_t 1567 DecimalFormatImpl::getOldFormatWidth() const { 1568 if (fAffixes.fWidth == 0) { 1569 return 0; 1570 } 1571 return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32(); 1572 } 1573 1574 const UnicodeString & 1575 DecimalFormatImpl::getConstSymbol( 1576 DecimalFormatSymbols::ENumberFormatSymbol symbol) const { 1577 return fSymbols->getConstSymbol(symbol); 1578 } 1579 1580 UBool 1581 DecimalFormatImpl::isParseFastpath() const { 1582 AffixPattern negative; 1583 negative.add(AffixPattern::kNegative); 1584 1585 return fAffixes.fWidth == 0 && 1586 fPositivePrefixPattern.countChar32() == 0 && 1587 fNegativePrefixPattern.equals(negative) && 1588 fPositiveSuffixPattern.countChar32() == 0 && 1589 fNegativeSuffixPattern.countChar32() == 0; 1590 } 1591 1592 1593 U_NAMESPACE_END 1594 1595 #endif /* #if !UCONFIG_NO_FORMATTING */ 1596 1597