1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ********************************************************************** 5 * Copyright (C) 1997-2015, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ********************************************************************** 8 * 9 * File DIGITLST.CPP 10 * 11 * Modification History: 12 * 13 * Date Name Description 14 * 03/21/97 clhuang Converted from java. 15 * 03/21/97 clhuang Implemented with new APIs. 16 * 03/27/97 helena Updated to pass the simple test after code review. 17 * 03/31/97 aliu Moved isLONG_MIN to here, and fixed it. 18 * 04/15/97 aliu Changed MAX_COUNT to DBL_DIG. Changed Digit to char. 19 * Reworked representation by replacing fDecimalAt 20 * with fExponent. 21 * 04/16/97 aliu Rewrote set() and getDouble() to use sprintf/atof 22 * to do digit conversion. 23 * 09/09/97 aliu Modified for exponential notation support. 24 * 08/02/98 stephen Added nearest/even rounding 25 * Fixed bug in fitsIntoLong 26 ****************************************************************************** 27 */ 28 29 #if defined(__CYGWIN__) && !defined(_GNU_SOURCE) 30 #define _GNU_SOURCE 31 #endif 32 33 #include "digitlst.h" 34 35 #if !UCONFIG_NO_FORMATTING 36 37 #include "unicode/putil.h" 38 #include "charstr.h" 39 #include "cmemory.h" 40 #include "cstring.h" 41 #include "mutex.h" 42 #include "putilimp.h" 43 #include "uassert.h" 44 #include "digitinterval.h" 45 #include "ucln_in.h" 46 #include "umutex.h" 47 #include <stdlib.h> 48 #include <limits.h> 49 #include <string.h> 50 #include <stdio.h> 51 #include <limits> 52 53 #if !defined(U_USE_STRTOD_L) 54 # if U_PLATFORM_USES_ONLY_WIN32_API 55 # define U_USE_STRTOD_L 1 56 # define U_HAVE_XLOCALE_H 0 57 # elif defined(U_HAVE_STRTOD_L) 58 # define U_USE_STRTOD_L U_HAVE_STRTOD_L 59 # else 60 # define U_USE_STRTOD_L 0 61 # endif 62 #endif 63 64 #if U_USE_STRTOD_L 65 # if U_HAVE_XLOCALE_H 66 # include <xlocale.h> 67 # else 68 # include <locale.h> 69 # endif 70 #endif 71 72 // *************************************************************************** 73 // class DigitList 74 // A wrapper onto decNumber. 75 // Used to be standalone. 76 // *************************************************************************** 77 78 /** 79 * This is the zero digit. The base for the digits returned by getDigit() 80 * Note that it is the platform invariant digit, and is not Unicode. 81 */ 82 #define kZero '0' 83 84 85 /* Only for 32 bit numbers. Ignore the negative sign. */ 86 //static const char LONG_MIN_REP[] = "2147483648"; 87 //static const char I64_MIN_REP[] = "9223372036854775808"; 88 89 90 U_NAMESPACE_BEGIN 91 92 // ------------------------------------- 93 // default constructor 94 95 DigitList::DigitList() 96 { 97 uprv_decContextDefault(&fContext, DEC_INIT_BASE); 98 fContext.traps = 0; 99 uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); 100 fContext.digits = fStorage.getCapacity(); 101 102 fDecNumber = fStorage.getAlias(); 103 uprv_decNumberZero(fDecNumber); 104 105 internalSetDouble(0.0); 106 } 107 108 // ------------------------------------- 109 110 DigitList::~DigitList() 111 { 112 } 113 114 // ------------------------------------- 115 // copy constructor 116 117 DigitList::DigitList(const DigitList &other) 118 { 119 fDecNumber = fStorage.getAlias(); 120 *this = other; 121 } 122 123 124 // ------------------------------------- 125 // assignment operator 126 127 DigitList& 128 DigitList::operator=(const DigitList& other) 129 { 130 if (this != &other) 131 { 132 uprv_memcpy(&fContext, &other.fContext, sizeof(decContext)); 133 134 if (other.fStorage.getCapacity() > fStorage.getCapacity()) { 135 fDecNumber = fStorage.resize(other.fStorage.getCapacity()); 136 } 137 // Always reset the fContext.digits, even if fDecNumber was not reallocated, 138 // because above we copied fContext from other.fContext. 139 fContext.digits = fStorage.getCapacity(); 140 uprv_decNumberCopy(fDecNumber, other.fDecNumber); 141 142 { 143 // fDouble is lazily created and cached. 144 // Avoid potential races with that happening with other.fDouble 145 // while we are doing the assignment. 146 Mutex mutex; 147 148 if(other.fHave==kDouble) { 149 fUnion.fDouble = other.fUnion.fDouble; 150 } 151 fHave = other.fHave; 152 } 153 } 154 return *this; 155 } 156 157 // ------------------------------------- 158 // operator == (does not exactly match the old DigitList function) 159 160 UBool 161 DigitList::operator==(const DigitList& that) const 162 { 163 if (this == &that) { 164 return TRUE; 165 } 166 decNumber n; // Has space for only a none digit value. 167 decContext c; 168 uprv_decContextDefault(&c, DEC_INIT_BASE); 169 c.digits = 1; 170 c.traps = 0; 171 172 uprv_decNumberCompare(&n, this->fDecNumber, that.fDecNumber, &c); 173 UBool result = decNumberIsZero(&n); 174 return result; 175 } 176 177 // ------------------------------------- 178 // comparison function. Returns 179 // Not Comparable : -2 180 // < : -1 181 // == : 0 182 // > : +1 183 int32_t DigitList::compare(const DigitList &other) { 184 decNumber result; 185 int32_t savedDigits = fContext.digits; 186 fContext.digits = 1; 187 uprv_decNumberCompare(&result, this->fDecNumber, other.fDecNumber, &fContext); 188 fContext.digits = savedDigits; 189 if (decNumberIsZero(&result)) { 190 return 0; 191 } else if (decNumberIsSpecial(&result)) { 192 return -2; 193 } else if (result.bits & DECNEG) { 194 return -1; 195 } else { 196 return 1; 197 } 198 } 199 200 201 // ------------------------------------- 202 // Reduce - remove trailing zero digits. 203 void 204 DigitList::reduce() { 205 uprv_decNumberReduce(fDecNumber, fDecNumber, &fContext); 206 } 207 208 209 // ------------------------------------- 210 // trim - remove trailing fraction zero digits. 211 void 212 DigitList::trim() { 213 uprv_decNumberTrim(fDecNumber); 214 } 215 216 // ------------------------------------- 217 // Resets the digit list; sets all the digits to zero. 218 219 void 220 DigitList::clear() 221 { 222 uprv_decNumberZero(fDecNumber); 223 uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); 224 internalSetDouble(0.0); 225 } 226 227 228 /** 229 * Formats a int64_t number into a base 10 string representation, and NULL terminates it. 230 * @param number The number to format 231 * @param outputStr The string to output to. Must be at least MAX_DIGITS+2 in length (21), 232 * to hold the longest int64_t value. 233 * @return the number of digits written, not including the sign. 234 */ 235 static int32_t 236 formatBase10(int64_t number, char *outputStr) { 237 // The number is output backwards, starting with the LSD. 238 // Fill the buffer from the far end. After the number is complete, 239 // slide the string contents to the front. 240 241 const int32_t MAX_IDX = MAX_DIGITS+2; 242 int32_t destIdx = MAX_IDX; 243 outputStr[--destIdx] = 0; 244 245 int64_t n = number; 246 if (number < 0) { // Negative numbers are slightly larger than a postive 247 outputStr[--destIdx] = (char)(-(n % 10) + kZero); 248 n /= -10; 249 } 250 do { 251 outputStr[--destIdx] = (char)(n % 10 + kZero); 252 n /= 10; 253 } while (n > 0); 254 255 if (number < 0) { 256 outputStr[--destIdx] = '-'; 257 } 258 259 // Slide the number to the start of the output str 260 U_ASSERT(destIdx >= 0); 261 int32_t length = MAX_IDX - destIdx; 262 uprv_memmove(outputStr, outputStr+MAX_IDX-length, length); 263 264 return length; 265 } 266 267 268 // ------------------------------------- 269 // 270 // setRoundingMode() 271 // For most modes, the meaning and names are the same between the decNumber library 272 // (which DigitList follows) and the ICU Formatting Rounding Mode values. 273 // The flag constants are different, however. 274 // 275 // Note that ICU's kRoundingUnnecessary is not implemented directly by DigitList. 276 // This mode, inherited from Java, means that numbers that would not format exactly 277 // will return an error when formatting is attempted. 278 279 void 280 DigitList::setRoundingMode(DecimalFormat::ERoundingMode m) { 281 enum rounding r; 282 283 switch (m) { 284 case DecimalFormat::kRoundCeiling: r = DEC_ROUND_CEILING; break; 285 case DecimalFormat::kRoundFloor: r = DEC_ROUND_FLOOR; break; 286 case DecimalFormat::kRoundDown: r = DEC_ROUND_DOWN; break; 287 case DecimalFormat::kRoundUp: r = DEC_ROUND_UP; break; 288 case DecimalFormat::kRoundHalfEven: r = DEC_ROUND_HALF_EVEN; break; 289 case DecimalFormat::kRoundHalfDown: r = DEC_ROUND_HALF_DOWN; break; 290 case DecimalFormat::kRoundHalfUp: r = DEC_ROUND_HALF_UP; break; 291 case DecimalFormat::kRoundUnnecessary: r = DEC_ROUND_HALF_EVEN; break; 292 default: 293 // TODO: how to report the problem? 294 // Leave existing mode unchanged. 295 r = uprv_decContextGetRounding(&fContext); 296 } 297 uprv_decContextSetRounding(&fContext, r); 298 299 } 300 301 302 // ------------------------------------- 303 304 void 305 DigitList::setPositive(UBool s) { 306 if (s) { 307 fDecNumber->bits &= ~DECNEG; 308 } else { 309 fDecNumber->bits |= DECNEG; 310 } 311 internalClear(); 312 } 313 // ------------------------------------- 314 315 void 316 DigitList::setDecimalAt(int32_t d) { 317 U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0); // Not Infinity or NaN 318 U_ASSERT(d-1>-999999999); 319 U_ASSERT(d-1< 999999999); 320 int32_t adjustedDigits = fDecNumber->digits; 321 if (decNumberIsZero(fDecNumber)) { 322 // Account for difference in how zero is represented between DigitList & decNumber. 323 adjustedDigits = 0; 324 } 325 fDecNumber->exponent = d - adjustedDigits; 326 internalClear(); 327 } 328 329 int32_t 330 DigitList::getDecimalAt() { 331 U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0); // Not Infinity or NaN 332 if (decNumberIsZero(fDecNumber) || ((fDecNumber->bits & DECSPECIAL) != 0)) { 333 return fDecNumber->exponent; // Exponent should be zero for these cases. 334 } 335 return fDecNumber->exponent + fDecNumber->digits; 336 } 337 338 void 339 DigitList::setCount(int32_t c) { 340 U_ASSERT(c <= fContext.digits); 341 if (c == 0) { 342 // For a value of zero, DigitList sets all fields to zero, while 343 // decNumber keeps one digit (with that digit being a zero) 344 c = 1; 345 fDecNumber->lsu[0] = 0; 346 } 347 fDecNumber->digits = c; 348 internalClear(); 349 } 350 351 int32_t 352 DigitList::getCount() const { 353 if (decNumberIsZero(fDecNumber) && fDecNumber->exponent==0) { 354 // The extra test for exponent==0 is needed because parsing sometimes appends 355 // zero digits. It's bogus, decimalFormatter parsing needs to be cleaned up. 356 return 0; 357 } else { 358 return fDecNumber->digits; 359 } 360 } 361 362 void 363 DigitList::setDigit(int32_t i, char v) { 364 int32_t count = fDecNumber->digits; 365 U_ASSERT(i<count); 366 U_ASSERT(v>='0' && v<='9'); 367 v &= 0x0f; 368 fDecNumber->lsu[count-i-1] = v; 369 internalClear(); 370 } 371 372 char 373 DigitList::getDigit(int32_t i) { 374 int32_t count = fDecNumber->digits; 375 U_ASSERT(i<count); 376 return fDecNumber->lsu[count-i-1] + '0'; 377 } 378 379 // copied from DigitList::getDigit() 380 uint8_t 381 DigitList::getDigitValue(int32_t i) { 382 int32_t count = fDecNumber->digits; 383 U_ASSERT(i<count); 384 return fDecNumber->lsu[count-i-1]; 385 } 386 387 // ------------------------------------- 388 // Appends the digit to the digit list if it's not out of scope. 389 // Ignores the digit, otherwise. 390 // 391 // This function is horribly inefficient to implement with decNumber because 392 // the digits are stored least significant first, which requires moving all 393 // existing digits down one to make space for the new one to be appended. 394 // 395 void 396 DigitList::append(char digit) 397 { 398 U_ASSERT(digit>='0' && digit<='9'); 399 // Ignore digits which exceed the precision we can represent 400 // And don't fix for larger precision. Fix callers instead. 401 if (decNumberIsZero(fDecNumber)) { 402 // Zero needs to be special cased because of the difference in the way 403 // that the old DigitList and decNumber represent it. 404 // digit cout was zero for digitList, is one for decNumber 405 fDecNumber->lsu[0] = digit & 0x0f; 406 fDecNumber->digits = 1; 407 fDecNumber->exponent--; // To match the old digit list implementation. 408 } else { 409 int32_t nDigits = fDecNumber->digits; 410 if (nDigits < fContext.digits) { 411 int i; 412 for (i=nDigits; i>0; i--) { 413 fDecNumber->lsu[i] = fDecNumber->lsu[i-1]; 414 } 415 fDecNumber->lsu[0] = digit & 0x0f; 416 fDecNumber->digits++; 417 // DigitList emulation - appending doesn't change the magnitude of existing 418 // digits. With decNumber's decimal being after the 419 // least signficant digit, we need to adjust the exponent. 420 fDecNumber->exponent--; 421 } 422 } 423 internalClear(); 424 } 425 426 // ------------------------------------- 427 428 /** 429 * Currently, getDouble() depends on strtod() to do its conversion. 430 * 431 * WARNING!! 432 * This is an extremely costly function. ~1/2 of the conversion time 433 * can be linked to this function. 434 */ 435 double 436 DigitList::getDouble() const 437 { 438 { 439 Mutex mutex; 440 if (fHave == kDouble) { 441 return fUnion.fDouble; 442 } 443 } 444 445 double tDouble = 0.0; 446 if (isZero()) { 447 tDouble = 0.0; 448 if (decNumberIsNegative(fDecNumber)) { 449 tDouble /= -1; 450 } 451 } else if (isInfinite()) { 452 if (std::numeric_limits<double>::has_infinity) { 453 tDouble = std::numeric_limits<double>::infinity(); 454 } else { 455 tDouble = std::numeric_limits<double>::max(); 456 } 457 if (!isPositive()) { 458 tDouble = -tDouble; //this was incorrectly "-fDouble" originally. 459 } 460 } else { 461 MaybeStackArray<char, MAX_DBL_DIGITS+18> s; 462 // Note: 14 is a magic constant from the decNumber library documentation, 463 // the max number of extra characters beyond the number of digits 464 // needed to represent the number in string form. Add a few more 465 // for the additional digits we retain. 466 467 // Round down to appx. double precision, if the number is longer than that. 468 // Copy the number first, so that we don't modify the original. 469 if (getCount() > MAX_DBL_DIGITS + 3) { 470 DigitList numToConvert(*this); 471 numToConvert.reduce(); // Removes any trailing zeros, so that digit count is good. 472 numToConvert.round(MAX_DBL_DIGITS+3); 473 uprv_decNumberToString(numToConvert.fDecNumber, s.getAlias()); 474 // TODO: how many extra digits should be included for an accurate conversion? 475 } else { 476 uprv_decNumberToString(this->fDecNumber, s.getAlias()); 477 } 478 U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); 479 480 char *end = NULL; 481 tDouble = decimalStrToDouble(s.getAlias(), &end); 482 } 483 { 484 Mutex mutex; 485 DigitList *nonConstThis = const_cast<DigitList *>(this); 486 nonConstThis->internalSetDouble(tDouble); 487 } 488 return tDouble; 489 } 490 491 #if U_USE_STRTOD_L && U_PLATFORM_USES_ONLY_WIN32_API 492 # define locale_t _locale_t 493 # define freelocale _free_locale 494 # define strtod_l _strtod_l 495 #endif 496 497 #if U_USE_STRTOD_L 498 static locale_t gCLocale = (locale_t)0; 499 #endif 500 static icu::UInitOnce gCLocaleInitOnce = U_INITONCE_INITIALIZER; 501 502 U_CDECL_BEGIN 503 // Cleanup callback func 504 static UBool U_CALLCONV digitList_cleanup(void) 505 { 506 #if U_USE_STRTOD_L 507 if (gCLocale != (locale_t)0) { 508 freelocale(gCLocale); 509 } 510 #endif 511 return TRUE; 512 } 513 // C Locale initialization func 514 static void U_CALLCONV initCLocale(void) { 515 ucln_i18n_registerCleanup(UCLN_I18N_DIGITLIST, digitList_cleanup); 516 #if U_USE_STRTOD_L 517 # if U_PLATFORM_USES_ONLY_WIN32_API 518 gCLocale = _create_locale(LC_ALL, "C"); 519 # else 520 gCLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0); 521 # endif 522 #endif 523 } 524 U_CDECL_END 525 526 double 527 DigitList::decimalStrToDouble(char *decstr, char **end) { 528 umtx_initOnce(gCLocaleInitOnce, &initCLocale); 529 #if U_USE_STRTOD_L 530 return strtod_l(decstr, end, gCLocale); 531 #else 532 char *decimalPt = strchr(decstr, '.'); 533 if (decimalPt) { 534 // We need to know the decimal separator character that will be used with strtod(). 535 // Depends on the C runtime global locale. 536 // Most commonly is '.' 537 char rep[MAX_DIGITS]; 538 sprintf(rep, "%+1.1f", 1.0); 539 *decimalPt = rep[2]; 540 } 541 return uprv_strtod(decstr, end); 542 #endif 543 } 544 545 // ------------------------------------- 546 547 /** 548 * convert this number to an int32_t. Round if there is a fractional part. 549 * Return zero if the number cannot be represented. 550 */ 551 int32_t DigitList::getLong() /*const*/ 552 { 553 int32_t result = 0; 554 if (getUpperExponent() > 10) { 555 // Overflow, absolute value too big. 556 return result; 557 } 558 if (fDecNumber->exponent != 0) { 559 // Force to an integer, with zero exponent, rounding if necessary. 560 // (decNumberToInt32 will only work if the exponent is exactly zero.) 561 DigitList copy(*this); 562 DigitList zero; 563 uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext); 564 result = uprv_decNumberToInt32(copy.fDecNumber, &fContext); 565 } else { 566 result = uprv_decNumberToInt32(fDecNumber, &fContext); 567 } 568 return result; 569 } 570 571 572 /** 573 * convert this number to an int64_t. Truncate if there is a fractional part. 574 * Return zero if the number cannot be represented. 575 */ 576 int64_t DigitList::getInt64() /*const*/ { 577 // TODO: fast conversion if fHave == fDouble 578 579 // Truncate if non-integer. 580 // Return 0 if out of range. 581 // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digits) 582 // 583 if (getUpperExponent() > 19) { 584 // Overflow, absolute value too big. 585 return 0; 586 } 587 588 // The number of integer digits may differ from the number of digits stored 589 // in the decimal number. 590 // for 12.345 numIntDigits = 2, number->digits = 5 591 // for 12E4 numIntDigits = 6, number->digits = 2 592 // The conversion ignores the fraction digits in the first case, 593 // and fakes up extra zero digits in the second. 594 // TODO: It would be faster to store a table of powers of ten to multiply by 595 // instead of looping over zero digits, multiplying each time. 596 597 int32_t numIntDigits = getUpperExponent(); 598 uint64_t value = 0; 599 for (int32_t i = 0; i < numIntDigits; i++) { 600 // Loop is iterating over digits starting with the most significant. 601 // Numbers are stored with the least significant digit at index zero. 602 int32_t digitIndex = fDecNumber->digits - i - 1; 603 int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0; 604 value = value * (uint64_t)10 + (uint64_t)v; 605 } 606 607 if (decNumberIsNegative(fDecNumber)) { 608 value = ~value; 609 value += 1; 610 } 611 int64_t svalue = (int64_t)value; 612 613 // Check overflow. It's convenient that the MSD is 9 only on overflow, the amount of 614 // overflow can't wrap too far. The test will also fail -0, but 615 // that does no harm; the right answer is 0. 616 if (numIntDigits == 19) { 617 if (( decNumberIsNegative(fDecNumber) && svalue>0) || 618 (!decNumberIsNegative(fDecNumber) && svalue<0)) { 619 svalue = 0; 620 } 621 } 622 623 return svalue; 624 } 625 626 627 /** 628 * Return a string form of this number. 629 * Format is as defined by the decNumber library, for interchange of 630 * decimal numbers. 631 */ 632 void DigitList::getDecimal(CharString &str, UErrorCode &status) { 633 if (U_FAILURE(status)) { 634 return; 635 } 636 637 // A decimal number in string form can, worst case, be 14 characters longer 638 // than the number of digits. So says the decNumber library doc. 639 int32_t maxLength = fDecNumber->digits + 14; 640 int32_t capacity = 0; 641 char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status); 642 if (U_FAILURE(status)) { 643 return; // Memory allocation error on growing the string. 644 } 645 U_ASSERT(capacity >= maxLength); 646 uprv_decNumberToString(this->fDecNumber, buffer); 647 U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength); 648 str.append(buffer, -1, status); 649 } 650 651 /** 652 * Return true if this is an integer value that can be held 653 * by an int32_t type. 654 */ 655 UBool 656 DigitList::fitsIntoLong(UBool ignoreNegativeZero) /*const*/ 657 { 658 if (decNumberIsSpecial(this->fDecNumber)) { 659 // NaN or Infinity. Does not fit in int32. 660 return FALSE; 661 } 662 uprv_decNumberTrim(this->fDecNumber); 663 if (fDecNumber->exponent < 0) { 664 // Number contains fraction digits. 665 return FALSE; 666 } 667 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && 668 (fDecNumber->bits & DECNEG) != 0) { 669 // Negative Zero, not ingored. Cannot represent as a long. 670 return FALSE; 671 } 672 if (getUpperExponent() < 10) { 673 // The number is 9 or fewer digits. 674 // The max and min int32 are 10 digts, so this number fits. 675 // This is the common case. 676 return TRUE; 677 } 678 679 // TODO: Should cache these constants; construction is relatively costly. 680 // But not of huge consequence; they're only needed for 10 digit ints. 681 UErrorCode status = U_ZERO_ERROR; 682 DigitList min32; min32.set("-2147483648", status); 683 if (this->compare(min32) < 0) { 684 return FALSE; 685 } 686 DigitList max32; max32.set("2147483647", status); 687 if (this->compare(max32) > 0) { 688 return FALSE; 689 } 690 if (U_FAILURE(status)) { 691 return FALSE; 692 } 693 return true; 694 } 695 696 697 698 /** 699 * Return true if the number represented by this object can fit into 700 * a long. 701 */ 702 UBool 703 DigitList::fitsIntoInt64(UBool ignoreNegativeZero) /*const*/ 704 { 705 if (decNumberIsSpecial(this->fDecNumber)) { 706 // NaN or Infinity. Does not fit in int32. 707 return FALSE; 708 } 709 uprv_decNumberTrim(this->fDecNumber); 710 if (fDecNumber->exponent < 0) { 711 // Number contains fraction digits. 712 return FALSE; 713 } 714 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && 715 (fDecNumber->bits & DECNEG) != 0) { 716 // Negative Zero, not ingored. Cannot represent as a long. 717 return FALSE; 718 } 719 if (getUpperExponent() < 19) { 720 // The number is 18 or fewer digits. 721 // The max and min int64 are 19 digts, so this number fits. 722 // This is the common case. 723 return TRUE; 724 } 725 726 // TODO: Should cache these constants; construction is relatively costly. 727 // But not of huge consequence; they're only needed for 19 digit ints. 728 UErrorCode status = U_ZERO_ERROR; 729 DigitList min64; min64.set("-9223372036854775808", status); 730 if (this->compare(min64) < 0) { 731 return FALSE; 732 } 733 DigitList max64; max64.set("9223372036854775807", status); 734 if (this->compare(max64) > 0) { 735 return FALSE; 736 } 737 if (U_FAILURE(status)) { 738 return FALSE; 739 } 740 return true; 741 } 742 743 744 // ------------------------------------- 745 746 void 747 DigitList::set(int32_t source) 748 { 749 set((int64_t)source); 750 internalSetDouble(source); 751 } 752 753 // ------------------------------------- 754 /** 755 * Set an int64, via decnumber 756 */ 757 void 758 DigitList::set(int64_t source) 759 { 760 char str[MAX_DIGITS+2]; // Leave room for sign and trailing nul. 761 formatBase10(source, str); 762 U_ASSERT(uprv_strlen(str) < sizeof(str)); 763 764 uprv_decNumberFromString(fDecNumber, str, &fContext); 765 internalSetDouble(static_cast<double>(source)); 766 } 767 768 // ------------------------------------- 769 /** 770 * Set the DigitList from a decimal number string. 771 * 772 * The incoming string _must_ be nul terminated, even though it is arriving 773 * as a StringPiece because that is what the decNumber library wants. 774 * We can get away with this for an internal function; it would not 775 * be acceptable for a public API. 776 */ 777 void 778 DigitList::set(StringPiece source, UErrorCode &status, uint32_t /*fastpathBits*/) { 779 if (U_FAILURE(status)) { 780 return; 781 } 782 783 #if 0 784 if(fastpathBits==(kFastpathOk|kNoDecimal)) { 785 int32_t size = source.size(); 786 const char *data = source.data(); 787 int64_t r = 0; 788 int64_t m = 1; 789 // fast parse 790 while(size>0) { 791 char ch = data[--size]; 792 if(ch=='+') { 793 break; 794 } else if(ch=='-') { 795 r = -r; 796 break; 797 } else { 798 int64_t d = ch-'0'; 799 //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m); 800 r+=(d)*m; 801 m *= 10; 802 } 803 } 804 //printf("R=%d\n", r); 805 set(r); 806 } else 807 #endif 808 { 809 // Figure out a max number of digits to use during the conversion, and 810 // resize the number up if necessary. 811 int32_t numDigits = source.length(); 812 if (numDigits > fContext.digits) { 813 // fContext.digits == fStorage.getCapacity() 814 decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity()); 815 if (t == NULL) { 816 status = U_MEMORY_ALLOCATION_ERROR; 817 return; 818 } 819 fDecNumber = t; 820 fContext.digits = numDigits; 821 } 822 823 fContext.status = 0; 824 uprv_decNumberFromString(fDecNumber, source.data(), &fContext); 825 if ((fContext.status & DEC_Conversion_syntax) != 0) { 826 status = U_DECIMAL_NUMBER_SYNTAX_ERROR; 827 } 828 } 829 internalClear(); 830 } 831 832 /** 833 * Set the digit list to a representation of the given double value. 834 * This method supports both fixed-point and exponential notation. 835 * @param source Value to be converted. 836 */ 837 void 838 DigitList::set(double source) 839 { 840 // for now, simple implementation; later, do proper IEEE stuff 841 char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough) 842 843 // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/ 844 // Can also generate /[+-]nan/ or /[+-]inf/ 845 // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific. 846 // That is why infinity is special cased here. 847 if (uprv_isInfinite(source)) { 848 if (uprv_isNegativeInfinity(source)) { 849 uprv_strcpy(rep,"-inf"); // Handle negative infinity 850 } else { 851 uprv_strcpy(rep,"inf"); 852 } 853 } else { 854 sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); 855 } 856 U_ASSERT(uprv_strlen(rep) < sizeof(rep)); 857 858 // uprv_decNumberFromString() will parse the string expecting '.' as a 859 // decimal separator, however sprintf() can use ',' in certain locales. 860 // Overwrite a ',' with '.' here before proceeding. 861 char *decimalSeparator = strchr(rep, ','); 862 if (decimalSeparator != NULL) { 863 *decimalSeparator = '.'; 864 } 865 866 // Create a decNumber from the string. 867 uprv_decNumberFromString(fDecNumber, rep, &fContext); 868 uprv_decNumberTrim(fDecNumber); 869 internalSetDouble(source); 870 } 871 872 // ------------------------------------- 873 874 /* 875 * Multiply 876 * The number will be expanded if need be to retain full precision. 877 * In practice, for formatting, multiply is by 10, 100 or 1000, so more digits 878 * will not be required for this use. 879 */ 880 void 881 DigitList::mult(const DigitList &other, UErrorCode &status) { 882 if (U_FAILURE(status)) { 883 return; 884 } 885 fContext.status = 0; 886 int32_t requiredDigits = this->digits() + other.digits(); 887 if (requiredDigits > fContext.digits) { 888 reduce(); // Remove any trailing zeros 889 int32_t requiredDigits = this->digits() + other.digits(); 890 ensureCapacity(requiredDigits, status); 891 } 892 uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext); 893 internalClear(); 894 } 895 896 // ------------------------------------- 897 898 /* 899 * Divide 900 * The number will _not_ be expanded for inexact results. 901 * TODO: probably should expand some, for rounding increments that 902 * could add a few digits, e.g. .25, but not expand arbitrarily. 903 */ 904 void 905 DigitList::div(const DigitList &other, UErrorCode &status) { 906 if (U_FAILURE(status)) { 907 return; 908 } 909 uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext); 910 internalClear(); 911 } 912 913 // ------------------------------------- 914 915 /* 916 * ensureCapacity. Grow the digit storage for the number if it's less than the requested 917 * amount. Never reduce it. Available size is kept in fContext.digits. 918 */ 919 void 920 DigitList::ensureCapacity(int32_t requestedCapacity, UErrorCode &status) { 921 if (U_FAILURE(status)) { 922 return; 923 } 924 if (requestedCapacity <= 0) { 925 status = U_ILLEGAL_ARGUMENT_ERROR; 926 return; 927 } 928 if (requestedCapacity > DEC_MAX_DIGITS) { 929 // Don't report an error for requesting too much. 930 // Arithemetic Results will be rounded to what can be supported. 931 // At 999,999,999 max digits, exceeding the limit is not too likely! 932 requestedCapacity = DEC_MAX_DIGITS; 933 } 934 if (requestedCapacity > fContext.digits) { 935 decNumber *newBuffer = fStorage.resize(requestedCapacity, fStorage.getCapacity()); 936 if (newBuffer == NULL) { 937 status = U_MEMORY_ALLOCATION_ERROR; 938 return; 939 } 940 fContext.digits = requestedCapacity; 941 fDecNumber = newBuffer; 942 } 943 } 944 945 // ------------------------------------- 946 947 /** 948 * Round the representation to the given number of digits. 949 * @param maximumDigits The maximum number of digits to be shown. 950 * Upon return, count will be less than or equal to maximumDigits. 951 */ 952 void 953 DigitList::round(int32_t maximumDigits) 954 { 955 reduce(); 956 if (maximumDigits >= fDecNumber->digits) { 957 return; 958 } 959 int32_t savedDigits = fContext.digits; 960 fContext.digits = maximumDigits; 961 uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext); 962 fContext.digits = savedDigits; 963 uprv_decNumberTrim(fDecNumber); 964 reduce(); 965 internalClear(); 966 } 967 968 969 void 970 DigitList::roundFixedPoint(int32_t maximumFractionDigits) { 971 reduce(); // Remove trailing zeros. 972 if (fDecNumber->exponent >= -maximumFractionDigits) { 973 return; 974 } 975 decNumber scale; // Dummy decimal number, but with the desired number of 976 uprv_decNumberZero(&scale); // fraction digits. 977 scale.exponent = -maximumFractionDigits; 978 scale.lsu[0] = 1; 979 980 uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); 981 reduce(); 982 internalClear(); 983 } 984 985 // ------------------------------------- 986 987 void 988 DigitList::toIntegralValue() { 989 uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext); 990 } 991 992 993 // ------------------------------------- 994 UBool 995 DigitList::isZero() const 996 { 997 return decNumberIsZero(fDecNumber); 998 } 999 1000 // ------------------------------------- 1001 int32_t 1002 DigitList::getUpperExponent() const { 1003 return fDecNumber->digits + fDecNumber->exponent; 1004 } 1005 1006 DigitInterval & 1007 DigitList::getSmallestInterval(DigitInterval &result) const { 1008 result.setLeastSignificantInclusive(fDecNumber->exponent); 1009 result.setMostSignificantExclusive(getUpperExponent()); 1010 return result; 1011 } 1012 1013 uint8_t 1014 DigitList::getDigitByExponent(int32_t exponent) const { 1015 int32_t idx = exponent - fDecNumber->exponent; 1016 if (idx < 0 || idx >= fDecNumber->digits) { 1017 return 0; 1018 } 1019 return fDecNumber->lsu[idx]; 1020 } 1021 1022 void 1023 DigitList::appendDigitsTo(CharString &str, UErrorCode &status) const { 1024 str.append((const char *) fDecNumber->lsu, fDecNumber->digits, status); 1025 } 1026 1027 void 1028 DigitList::roundAtExponent(int32_t exponent, int32_t maxSigDigits) { 1029 reduce(); 1030 if (maxSigDigits < fDecNumber->digits) { 1031 int32_t minExponent = getUpperExponent() - maxSigDigits; 1032 if (exponent < minExponent) { 1033 exponent = minExponent; 1034 } 1035 } 1036 if (exponent <= fDecNumber->exponent) { 1037 return; 1038 } 1039 int32_t digits = getUpperExponent() - exponent; 1040 if (digits > 0) { 1041 round(digits); 1042 } else { 1043 roundFixedPoint(-exponent); 1044 } 1045 } 1046 1047 void 1048 DigitList::quantize(const DigitList &quantity, UErrorCode &status) { 1049 if (U_FAILURE(status)) { 1050 return; 1051 } 1052 div(quantity, status); 1053 roundAtExponent(0); 1054 mult(quantity, status); 1055 reduce(); 1056 } 1057 1058 int32_t 1059 DigitList::getScientificExponent( 1060 int32_t minIntDigitCount, int32_t exponentMultiplier) const { 1061 // The exponent for zero is always zero. 1062 if (isZero()) { 1063 return 0; 1064 } 1065 int32_t intDigitCount = getUpperExponent(); 1066 int32_t exponent; 1067 if (intDigitCount >= minIntDigitCount) { 1068 int32_t maxAdjustment = intDigitCount - minIntDigitCount; 1069 exponent = (maxAdjustment / exponentMultiplier) * exponentMultiplier; 1070 } else { 1071 int32_t minAdjustment = minIntDigitCount - intDigitCount; 1072 exponent = ((minAdjustment + exponentMultiplier - 1) / exponentMultiplier) * -exponentMultiplier; 1073 } 1074 return exponent; 1075 } 1076 1077 int32_t 1078 DigitList::toScientific( 1079 int32_t minIntDigitCount, int32_t exponentMultiplier) { 1080 int32_t exponent = getScientificExponent( 1081 minIntDigitCount, exponentMultiplier); 1082 shiftDecimalRight(-exponent); 1083 return exponent; 1084 } 1085 1086 void 1087 DigitList::shiftDecimalRight(int32_t n) { 1088 fDecNumber->exponent += n; 1089 internalClear(); 1090 } 1091 1092 U_NAMESPACE_END 1093 #endif // #if !UCONFIG_NO_FORMATTING 1094 1095 //eof 1096