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