/*
**********************************************************************
*   Copyright (C) 1997-2012, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*
* File DIGITLST.CPP
*
* Modification History:
*
*   Date        Name        Description
*   03/21/97    clhuang     Converted from java.
*   03/21/97    clhuang     Implemented with new APIs.
*   03/27/97    helena      Updated to pass the simple test after code review.
*   03/31/97    aliu        Moved isLONG_MIN to here, and fixed it.
*   04/15/97    aliu        Changed MAX_COUNT to DBL_DIG.  Changed Digit to char.
*                           Reworked representation by replacing fDecimalAt
*                           with fExponent.
*   04/16/97    aliu        Rewrote set() and getDouble() to use sprintf/atof
*                           to do digit conversion.
*   09/09/97    aliu        Modified for exponential notation support.
*   08/02/98    stephen     Added nearest/even rounding
*                            Fixed bug in fitsIntoLong
******************************************************************************
*/

#include "digitlst.h"

#if !UCONFIG_NO_FORMATTING
#include "unicode/putil.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "mutex.h"
#include "putilimp.h"
#include "uassert.h"
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <limits>

// ***************************************************************************
// class DigitList
//    A wrapper onto decNumber.
//    Used to be standalone.
// ***************************************************************************

/**
 * This is the zero digit.  The base for the digits returned by getDigit()
 * Note that it is the platform invariant digit, and is not Unicode.
 */
#define kZero '0'


/* Only for 32 bit numbers. Ignore the negative sign. */
//static const char LONG_MIN_REP[] = "2147483648";
//static const char I64_MIN_REP[] = "9223372036854775808";


static const uint8_t DIGIT_HAVE_NONE=0;
static const uint8_t DIGIT_HAVE_DOUBLE=1;
static const uint8_t DIGIT_HAVE_INT64=2;

U_NAMESPACE_BEGIN

// -------------------------------------
// default constructor

DigitList::DigitList()
{
    uprv_decContextDefault(&fContext, DEC_INIT_BASE);
    fContext.traps  = 0;
    uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
    fContext.digits = fStorage.getCapacity();

    fDecNumber = fStorage.getAlias();
    uprv_decNumberZero(fDecNumber);

    internalSetDouble(0.0);
}

// -------------------------------------

DigitList::~DigitList()
{
}

// -------------------------------------
// copy constructor

DigitList::DigitList(const DigitList &other)
{
    fDecNumber = fStorage.getAlias();
    *this = other;
}


// -------------------------------------
// assignment operator

DigitList&
DigitList::operator=(const DigitList& other)
{
    if (this != &other)
    {
        uprv_memcpy(&fContext, &other.fContext, sizeof(decContext));

        if (other.fStorage.getCapacity() > fStorage.getCapacity()) {
            fDecNumber = fStorage.resize(other.fStorage.getCapacity());
        }
        // Always reset the fContext.digits, even if fDecNumber was not reallocated,
        // because above we copied fContext from other.fContext.
        fContext.digits = fStorage.getCapacity();
        uprv_decNumberCopy(fDecNumber, other.fDecNumber);

        {
            // fDouble is lazily created and cached.
            // Avoid potential races with that happening with other.fDouble
            // while we are doing the assignment.
            Mutex mutex;

            if(other.fHave==kDouble) {
              fUnion.fDouble = other.fUnion.fDouble;
            } else if(other.fHave==kInt64) {
              fUnion.fInt64 = other.fUnion.fInt64;
            }
            fHave = other.fHave;
        }
    }
    return *this;
}

// -------------------------------------
//    operator ==  (does not exactly match the old DigitList function)

UBool
DigitList::operator==(const DigitList& that) const
{
    if (this == &that) {
        return TRUE;
    }
    decNumber n;  // Has space for only a none digit value.
    decContext c;
    uprv_decContextDefault(&c, DEC_INIT_BASE);
    c.digits = 1;
    c.traps = 0;

    uprv_decNumberCompare(&n, this->fDecNumber, that.fDecNumber, &c);
    UBool result = decNumberIsZero(&n);
    return result;
}

// -------------------------------------
//      comparison function.   Returns 
//         Not Comparable :  -2
//                      < :  -1
//                     == :   0
//                      > :  +1
int32_t DigitList::compare(const DigitList &other) {
    decNumber   result;
    int32_t     savedDigits = fContext.digits;
    fContext.digits = 1;
    uprv_decNumberCompare(&result, this->fDecNumber, other.fDecNumber, &fContext);
    fContext.digits = savedDigits;
    if (decNumberIsZero(&result)) {
        return 0;
    } else if (decNumberIsSpecial(&result)) {
        return -2;
    } else if (result.bits & DECNEG) {
        return -1;
    } else {
        return 1;
    }
}


// -------------------------------------
//  Reduce - remove trailing zero digits.
void
DigitList::reduce() {
    uprv_decNumberReduce(fDecNumber, fDecNumber, &fContext);
}


// -------------------------------------
//  trim - remove trailing fraction zero digits.
void
DigitList::trim() {
    uprv_decNumberTrim(fDecNumber);
}

// -------------------------------------
// Resets the digit list; sets all the digits to zero.

void
DigitList::clear()
{
    uprv_decNumberZero(fDecNumber);
    uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
    internalSetDouble(0.0);
}


/**
 * Formats a int64_t number into a base 10 string representation, and NULL terminates it.
 * @param number The number to format
 * @param outputStr The string to output to.  Must be at least MAX_DIGITS+2 in length (21),
 *                  to hold the longest int64_t value.
 * @return the number of digits written, not including the sign.
 */
static int32_t
formatBase10(int64_t number, char *outputStr) {
    // The number is output backwards, starting with the LSD.
    // Fill the buffer from the far end.  After the number is complete,
    // slide the string contents to the front.

    const int32_t MAX_IDX = MAX_DIGITS+2;
    int32_t destIdx = MAX_IDX;
    outputStr[--destIdx] = 0; 

    int64_t  n = number;
    if (number < 0) {   // Negative numbers are slightly larger than a postive
        outputStr[--destIdx] = (char)(-(n % 10) + kZero);
        n /= -10;
    }
    do { 
        outputStr[--destIdx] = (char)(n % 10 + kZero);
        n /= 10;
    } while (n > 0);
    
    if (number < 0) {
        outputStr[--destIdx] = '-';
    }

    // Slide the number to the start of the output str
    U_ASSERT(destIdx >= 0);
    int32_t length = MAX_IDX - destIdx;
    uprv_memmove(outputStr, outputStr+MAX_IDX-length, length);

    return length;
}


// -------------------------------------
//
//  setRoundingMode()
//    For most modes, the meaning and names are the same between the decNumber library
//      (which DigitList follows) and the ICU Formatting Rounding Mode values.
//      The flag constants are different, however.
//
//     Note that ICU's kRoundingUnnecessary is not implemented directly by DigitList.
//     This mode, inherited from Java, means that numbers that would not format exactly
//     will return an error when formatting is attempted.

void 
DigitList::setRoundingMode(DecimalFormat::ERoundingMode m) {
    enum rounding r;

    switch (m) {
      case  DecimalFormat::kRoundCeiling:  r = DEC_ROUND_CEILING;   break;
      case  DecimalFormat::kRoundFloor:    r = DEC_ROUND_FLOOR;     break;
      case  DecimalFormat::kRoundDown:     r = DEC_ROUND_DOWN;      break;
      case  DecimalFormat::kRoundUp:       r = DEC_ROUND_UP;        break;
      case  DecimalFormat::kRoundHalfEven: r = DEC_ROUND_HALF_EVEN; break;
      case  DecimalFormat::kRoundHalfDown: r = DEC_ROUND_HALF_DOWN; break;
      case  DecimalFormat::kRoundHalfUp:   r = DEC_ROUND_HALF_UP;   break;
      case  DecimalFormat::kRoundUnnecessary: r = DEC_ROUND_HALF_EVEN; break;
      default:
         // TODO: how to report the problem?
         // Leave existing mode unchanged.
         r = uprv_decContextGetRounding(&fContext);
    }
    uprv_decContextSetRounding(&fContext, r);
  
}


// -------------------------------------

void  
DigitList::setPositive(UBool s) {
    if (s) {
        fDecNumber->bits &= ~DECNEG; 
    } else {
        fDecNumber->bits |= DECNEG;
    }
    internalClear();
}
// -------------------------------------

void     
DigitList::setDecimalAt(int32_t d) {
    U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0);  // Not Infinity or NaN
    U_ASSERT(d-1>-999999999);
    U_ASSERT(d-1< 999999999);
    int32_t adjustedDigits = fDecNumber->digits;
    if (decNumberIsZero(fDecNumber)) {
        // Account for difference in how zero is represented between DigitList & decNumber.
        adjustedDigits = 0;
    }
    fDecNumber->exponent = d - adjustedDigits;
    internalClear();
}

int32_t  
DigitList::getDecimalAt() {
    U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0);  // Not Infinity or NaN
    if (decNumberIsZero(fDecNumber) || ((fDecNumber->bits & DECSPECIAL) != 0)) {
        return fDecNumber->exponent;  // Exponent should be zero for these cases.
    }
    return fDecNumber->exponent + fDecNumber->digits;
}

void     
DigitList::setCount(int32_t c)  {
    U_ASSERT(c <= fContext.digits);
    if (c == 0) {
        // For a value of zero, DigitList sets all fields to zero, while
        // decNumber keeps one digit (with that digit being a zero)
        c = 1;
        fDecNumber->lsu[0] = 0;
    }
    fDecNumber->digits = c;
    internalClear();
}

int32_t  
DigitList::getCount() const {
    if (decNumberIsZero(fDecNumber) && fDecNumber->exponent==0) {
       // The extra test for exponent==0 is needed because parsing sometimes appends
       // zero digits.  It's bogus, decimalFormatter parsing needs to be cleaned up.
       return 0;
    } else {
       return fDecNumber->digits;
    }
}
    
void     
DigitList::setDigit(int32_t i, char v) {
    int32_t count = fDecNumber->digits;
    U_ASSERT(i<count);
    U_ASSERT(v>='0' && v<='9');
    v &= 0x0f;
    fDecNumber->lsu[count-i-1] = v;
    internalClear();
}

char     
DigitList::getDigit(int32_t i) {
    int32_t count = fDecNumber->digits;
    U_ASSERT(i<count);
    return fDecNumber->lsu[count-i-1] + '0';
}

// copied from DigitList::getDigit()
uint8_t
DigitList::getDigitValue(int32_t i) {
    int32_t count = fDecNumber->digits;
    U_ASSERT(i<count);
    return fDecNumber->lsu[count-i-1];
}

// -------------------------------------
// Appends the digit to the digit list if it's not out of scope.
// Ignores the digit, otherwise.
// 
// This function is horribly inefficient to implement with decNumber because
// the digits are stored least significant first, which requires moving all
// existing digits down one to make space for the new one to be appended.
//
void
DigitList::append(char digit)
{
    U_ASSERT(digit>='0' && digit<='9');
    // Ignore digits which exceed the precision we can represent
    //    And don't fix for larger precision.  Fix callers instead.
    if (decNumberIsZero(fDecNumber)) {
        // Zero needs to be special cased because of the difference in the way
        // that the old DigitList and decNumber represent it.
        // digit cout was zero for digitList, is one for decNumber
        fDecNumber->lsu[0] = digit & 0x0f;
        fDecNumber->digits = 1;
        fDecNumber->exponent--;     // To match the old digit list implementation.
    } else {
        int32_t nDigits = fDecNumber->digits;
        if (nDigits < fContext.digits) {
            int i;
            for (i=nDigits; i>0; i--) {
                fDecNumber->lsu[i] = fDecNumber->lsu[i-1];
            }
            fDecNumber->lsu[0] = digit & 0x0f;
            fDecNumber->digits++;
            // DigitList emulation - appending doesn't change the magnitude of existing
            //                       digits.  With decNumber's decimal being after the
            //                       least signficant digit, we need to adjust the exponent.
            fDecNumber->exponent--;
        }
    }
    internalClear();
}

// -------------------------------------

/**
 * Currently, getDouble() depends on strtod() to do its conversion.
 *
 * WARNING!!
 * This is an extremely costly function. ~1/2 of the conversion time
 * can be linked to this function.
 */
double
DigitList::getDouble() const
{
    static char gDecimal = 0;
    char decimalSeparator;
    {
        Mutex mutex;
        if (fHave == kDouble) {
            return fUnion.fDouble;
        } else if(fHave == kInt64) {
            return (double)fUnion.fInt64;
        }
        decimalSeparator = gDecimal;
    }

    if (decimalSeparator == 0) {
        // We need to know the decimal separator character that will be used with strtod().
        // Depends on the C runtime global locale.
        // Most commonly is '.'
        // TODO: caching could fail if the global locale is changed on the fly.
        char rep[MAX_DIGITS];
        sprintf(rep, "%+1.1f", 1.0);
        decimalSeparator = rep[2];
    }

    double tDouble = 0.0;
    if (isZero()) {
        tDouble = 0.0;
        if (decNumberIsNegative(fDecNumber)) {
            tDouble /= -1;
        }
    } else if (isInfinite()) {
        if (std::numeric_limits<double>::has_infinity) {
            tDouble = std::numeric_limits<double>::infinity();
        } else {
            tDouble = std::numeric_limits<double>::max();
        }
        if (!isPositive()) {
            tDouble = -tDouble; //this was incorrectly "-fDouble" originally.
        } 
    } else {
        MaybeStackArray<char, MAX_DBL_DIGITS+18> s;
           // Note:  14 is a  magic constant from the decNumber library documentation,
           //        the max number of extra characters beyond the number of digits 
           //        needed to represent the number in string form.  Add a few more
           //        for the additional digits we retain.

        // Round down to appx. double precision, if the number is longer than that.
        // Copy the number first, so that we don't modify the original.
        if (getCount() > MAX_DBL_DIGITS + 3) {
            DigitList numToConvert(*this);
            numToConvert.reduce();    // Removes any trailing zeros, so that digit count is good.
            numToConvert.round(MAX_DBL_DIGITS+3);
            uprv_decNumberToString(numToConvert.fDecNumber, s.getAlias());
            // TODO:  how many extra digits should be included for an accurate conversion?
        } else {
            uprv_decNumberToString(this->fDecNumber, s.getAlias());
        }
        U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18);
        
        if (decimalSeparator != '.') {
            char *decimalPt = strchr(s.getAlias(), '.');
            if (decimalPt != NULL) {
                *decimalPt = decimalSeparator;
            }
        }
        char *end = NULL;
        tDouble = uprv_strtod(s.getAlias(), &end);
    }
    {
        Mutex mutex;
        DigitList *nonConstThis = const_cast<DigitList *>(this);
        nonConstThis->internalSetDouble(tDouble);
        gDecimal = decimalSeparator;
    }
    return tDouble;
}

// -------------------------------------

/**
 *  convert this number to an int32_t.   Round if there is a fractional part.
 *  Return zero if the number cannot be represented.
 */
int32_t DigitList::getLong() /*const*/
{
    int32_t result = 0;
    if (fDecNumber->digits + fDecNumber->exponent > 10) {
        // Overflow, absolute value too big.
        return result;
    }
    if (fDecNumber->exponent != 0) {
        // Force to an integer, with zero exponent, rounding if necessary.
        //   (decNumberToInt32 will only work if the exponent is exactly zero.)
        DigitList copy(*this);
        DigitList zero;
        uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext);
        result = uprv_decNumberToInt32(copy.fDecNumber, &fContext);
    } else {
        result = uprv_decNumberToInt32(fDecNumber, &fContext);
    }
    return result;
}


/**
 *  convert this number to an int64_t.   Truncate if there is a fractional part.
 *  Return zero if the number cannot be represented.
 */
int64_t DigitList::getInt64() /*const*/ {
    if(fHave==kInt64) {
      return fUnion.fInt64;
    } 
    // Truncate if non-integer.
    // Return 0 if out of range.
    // Range of in64_t is -9223372036854775808 to 9223372036854775807  (19 digits)
    //
    if (fDecNumber->digits + fDecNumber->exponent > 19) {
        // Overflow, absolute value too big.
        return 0;
    }

    // The number of integer digits may differ from the number of digits stored
    //   in the decimal number.
    //     for 12.345  numIntDigits = 2, number->digits = 5
    //     for 12E4    numIntDigits = 6, number->digits = 2
    // The conversion ignores the fraction digits in the first case,
    // and fakes up extra zero digits in the second.
    // TODO:  It would be faster to store a table of powers of ten to multiply by
    //        instead of looping over zero digits, multiplying each time.

    int32_t numIntDigits = fDecNumber->digits + fDecNumber->exponent;
    uint64_t value = 0;
    for (int32_t i = 0; i < numIntDigits; i++) {
        // Loop is iterating over digits starting with the most significant.
        // Numbers are stored with the least significant digit at index zero.
        int32_t digitIndex = fDecNumber->digits - i - 1;
        int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0;
        value = value * (uint64_t)10 + (uint64_t)v;
    }

    if (decNumberIsNegative(fDecNumber)) {
        value = ~value;
        value += 1;
    }
    int64_t svalue = (int64_t)value;

    // Check overflow.  It's convenient that the MSD is 9 only on overflow, the amount of
    //                  overflow can't wrap too far.  The test will also fail -0, but
    //                  that does no harm; the right answer is 0.
    if (numIntDigits == 19) {
        if (( decNumberIsNegative(fDecNumber) && svalue>0) ||
            (!decNumberIsNegative(fDecNumber) && svalue<0)) {
            svalue = 0;
        }
    }
        
    return svalue;
}


/**
 *  Return a string form of this number.
 *     Format is as defined by the decNumber library, for interchange of
 *     decimal numbers.
 */
void DigitList::getDecimal(CharString &str, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }

    // A decimal number in string form can, worst case, be 14 characters longer
    //  than the number of digits.  So says the decNumber library doc.
    int32_t maxLength = fDecNumber->digits + 14;
    int32_t capacity = 0;
    char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status);
    if (U_FAILURE(status)) {
        return;    // Memory allocation error on growing the string.
    }
    U_ASSERT(capacity >= maxLength);
    uprv_decNumberToString(this->fDecNumber, buffer);
    U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength);
    str.append(buffer, -1, status);
}

/**
 * Return true if this is an integer value that can be held
 * by an int32_t type.
 */
UBool
DigitList::fitsIntoLong(UBool ignoreNegativeZero) /*const*/
{
    if (decNumberIsSpecial(this->fDecNumber)) {
        // NaN or Infinity.  Does not fit in int32.
        return FALSE;
    }
    uprv_decNumberTrim(this->fDecNumber);
    if (fDecNumber->exponent < 0) {
        // Number contains fraction digits.
        return FALSE;
    }
    if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero &&
        (fDecNumber->bits & DECNEG) != 0) {
        // Negative Zero, not ingored.  Cannot represent as a long.
        return FALSE;
    }
    if (fDecNumber->digits + fDecNumber->exponent < 10) {
        // The number is 9 or fewer digits.
        // The max and min int32 are 10 digts, so this number fits.
        // This is the common case.
        return TRUE;
    }

    // TODO:  Should cache these constants; construction is relatively costly.
    //        But not of huge consequence; they're only needed for 10 digit ints.
    UErrorCode status = U_ZERO_ERROR;
    DigitList min32; min32.set("-2147483648", status);
    if (this->compare(min32) < 0) {
        return FALSE;
    }
    DigitList max32; max32.set("2147483647", status);
    if (this->compare(max32) > 0) {
        return FALSE;
    }
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return true;
}



/**
 * Return true if the number represented by this object can fit into
 * a long.
 */
UBool
DigitList::fitsIntoInt64(UBool ignoreNegativeZero) /*const*/
{
    if (decNumberIsSpecial(this->fDecNumber)) {
        // NaN or Infinity.  Does not fit in int32.
        return FALSE;
    }
    uprv_decNumberTrim(this->fDecNumber);
    if (fDecNumber->exponent < 0) {
        // Number contains fraction digits.
        return FALSE;
    }
    if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero &&
        (fDecNumber->bits & DECNEG) != 0) {
        // Negative Zero, not ingored.  Cannot represent as a long.
        return FALSE;
    }
    if (fDecNumber->digits + fDecNumber->exponent < 19) {
        // The number is 18 or fewer digits.
        // The max and min int64 are 19 digts, so this number fits.
        // This is the common case.
        return TRUE;
    }

    // TODO:  Should cache these constants; construction is relatively costly.
    //        But not of huge consequence; they're only needed for 19 digit ints.
    UErrorCode status = U_ZERO_ERROR;
    DigitList min64; min64.set("-9223372036854775808", status);
    if (this->compare(min64) < 0) {
        return FALSE;
    }
    DigitList max64; max64.set("9223372036854775807", status);
    if (this->compare(max64) > 0) {
        return FALSE;
    }
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return true;
}


// -------------------------------------

void
DigitList::set(int32_t source)
{
    set((int64_t)source);
    internalSetDouble(source);
}

// -------------------------------------
/**
 * Set an int64, via decnumber
 */
void
DigitList::set(int64_t source)
{
    char str[MAX_DIGITS+2];   // Leave room for sign and trailing nul.
    formatBase10(source, str);
    U_ASSERT(uprv_strlen(str) < sizeof(str));

    uprv_decNumberFromString(fDecNumber, str, &fContext);
    internalSetDouble(source);
}

/**
 * Set an int64, with no decnumber
 */
void
DigitList::setInteger(int64_t source)
{
  fDecNumber=NULL;
  internalSetInt64(source);
}


// -------------------------------------
/**
 * Set the DigitList from a decimal number string.
 *
 * The incoming string _must_ be nul terminated, even though it is arriving
 * as a StringPiece because that is what the decNumber library wants.
 * We can get away with this for an internal function; it would not
 * be acceptable for a public API.
 */
void
DigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) {
    if (U_FAILURE(status)) {
        return;
    }

#if 0    
    if(fastpathBits==(kFastpathOk|kNoDecimal)) {
      int32_t size = source.size();
      const char *data = source.data();
      int64_t r = 0;
      int64_t m = 1;
      // fast parse
      while(size>0) {
        char ch = data[--size];
        if(ch=='+') {
          break;
        } else if(ch=='-') {
          r = -r;
          break;
        } else {
          int64_t d = ch-'0';
          //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m);
          r+=(d)*m;
          m *= 10;
        }
      }
      //printf("R=%d\n", r);
      set(r);
    } else
#endif
        {
      // Figure out a max number of digits to use during the conversion, and
      // resize the number up if necessary.
      int32_t numDigits = source.length();
      if (numDigits > fContext.digits) {
        // fContext.digits == fStorage.getCapacity()
        decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity());
        if (t == NULL) {
          status = U_MEMORY_ALLOCATION_ERROR;
          return;
        }
        fDecNumber = t;
        fContext.digits = numDigits;
      }

      fContext.status = 0;
      uprv_decNumberFromString(fDecNumber, source.data(), &fContext);
      if ((fContext.status & DEC_Conversion_syntax) != 0) {
        status = U_DECIMAL_NUMBER_SYNTAX_ERROR;
      }
    }
    internalClear();
}   

/**
 * Set the digit list to a representation of the given double value.
 * This method supports both fixed-point and exponential notation.
 * @param source Value to be converted.
 */
void
DigitList::set(double source)
{
    // for now, simple implementation; later, do proper IEEE stuff
    char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough)

    // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/
    // Can also generate /[+-]nan/ or /[+-]inf/
    // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific.
    //       That is why infinity is special cased here.
    if (uprv_isInfinite(source)) {
        if (uprv_isNegativeInfinity(source)) {
            uprv_strcpy(rep,"-inf"); // Handle negative infinity
        } else {
            uprv_strcpy(rep,"inf");
        }
    } else {
        sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source);
    }
    U_ASSERT(uprv_strlen(rep) < sizeof(rep));

    // uprv_decNumberFromString() will parse the string expecting '.' as a
    // decimal separator, however sprintf() can use ',' in certain locales.
    // Overwrite a ',' with '.' here before proceeding.
    char *decimalSeparator = strchr(rep, ',');
    if (decimalSeparator != NULL) {
        *decimalSeparator = '.';
    }

    // Create a decNumber from the string.
    uprv_decNumberFromString(fDecNumber, rep, &fContext);
    uprv_decNumberTrim(fDecNumber);
    internalSetDouble(source);
}

// -------------------------------------

/*
 * Multiply
 *      The number will be expanded if need be to retain full precision.
 *      In practice, for formatting, multiply is by 10, 100 or 1000, so more digits
 *      will not be required for this use.
 */
void
DigitList::mult(const DigitList &other, UErrorCode &status) {
    fContext.status = 0;
    int32_t requiredDigits = this->digits() + other.digits();
    if (requiredDigits > fContext.digits) {
        reduce();    // Remove any trailing zeros
        int32_t requiredDigits = this->digits() + other.digits();
        ensureCapacity(requiredDigits, status);
    }
    uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
    internalClear();
}

// -------------------------------------

/*
 * Divide
 *      The number will _not_ be expanded for inexact results.
 *      TODO:  probably should expand some, for rounding increments that
 *             could add a few digits, e.g. .25, but not expand arbitrarily.
 */
void
DigitList::div(const DigitList &other, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
    internalClear();
}

// -------------------------------------

/*
 * ensureCapacity.   Grow the digit storage for the number if it's less than the requested
 *         amount.  Never reduce it.  Available size is kept in fContext.digits.
 */
void
DigitList::ensureCapacity(int32_t requestedCapacity, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    if (requestedCapacity <= 0) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if (requestedCapacity > DEC_MAX_DIGITS) {
        // Don't report an error for requesting too much.
        // Arithemetic Results will be rounded to what can be supported.
        //   At 999,999,999 max digits, exceeding the limit is not too likely!
        requestedCapacity = DEC_MAX_DIGITS;
    }
    if (requestedCapacity > fContext.digits) {
        decNumber *newBuffer = fStorage.resize(requestedCapacity, fStorage.getCapacity());
        if (newBuffer == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        fContext.digits = requestedCapacity;
        fDecNumber = newBuffer;
    }
}

// -------------------------------------

/**
 * Round the representation to the given number of digits.
 * @param maximumDigits The maximum number of digits to be shown.
 * Upon return, count will be less than or equal to maximumDigits.
 */
void
DigitList::round(int32_t maximumDigits)
{
    int32_t savedDigits  = fContext.digits;
    fContext.digits = maximumDigits;
    uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
    fContext.digits = savedDigits;
    uprv_decNumberTrim(fDecNumber);
    internalClear();
}


void
DigitList::roundFixedPoint(int32_t maximumFractionDigits) {
    trim();        // Remove trailing zeros.
    if (fDecNumber->exponent >= -maximumFractionDigits) {
        return;
    }
    decNumber scale;   // Dummy decimal number, but with the desired number of
    uprv_decNumberZero(&scale);    //    fraction digits.
    scale.exponent = -maximumFractionDigits;
    scale.lsu[0] = 1;
    
    uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext);
    trim();
    internalClear();
}

// -------------------------------------

void
DigitList::toIntegralValue() {
    uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext);
}


// -------------------------------------
UBool
DigitList::isZero() const
{
    return decNumberIsZero(fDecNumber);
}

U_NAMESPACE_END
#endif // #if !UCONFIG_NO_FORMATTING

//eof
