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