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