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