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