Home | History | Annotate | Download | only in i18n
      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