/*
**********************************************************************
*   Copyright (C) 1997-2010, 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 "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'

static char gDecimal = 0;

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


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);

    fDouble = 0.0;
    fHaveDouble = TRUE;
}

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

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 = other.fDouble;
        fHaveDouble = other.fHaveDouble;
    }
    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);
    fDouble = 0.0;
    fHaveDouble = TRUE;
}


/**
 * 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;
}


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

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;
      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;
    }
    fHaveDouble = FALSE;
}
// -------------------------------------

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;
    fHaveDouble = FALSE;
}

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;
    fHaveDouble = FALSE;
}

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;
    fHaveDouble = FALSE;
}

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--;
        }
    }
    fHaveDouble = FALSE;
}

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

/**
 * Currently, getDouble() depends on atof() 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
{
    // TODO:  fix thread safety.  Can probably be finessed some by analyzing
    //        what public const functions can see which DigitLists.
    //        Like precompute fDouble for DigitLists coming in from a parse
    //        or from a Formattable::set(), but not for any others.
    if (fHaveDouble) {
        return fDouble;
    }
    DigitList *nonConstThis = const_cast<DigitList *>(this);

    if (gDecimal == 0) {
        char rep[MAX_DIGITS];
        // For machines that decide to change the decimal on you,
        // and try to be too smart with localization.
        // This normally should be just a '.'.
        sprintf(rep, "%+1.1f", 1.0);
        gDecimal = rep[2];
    }

    if (isZero()) {
        nonConstThis->fDouble = 0.0;
        if (decNumberIsNegative(fDecNumber)) {
            nonConstThis->fDouble /= -1;
        }
    } else if (isInfinite()) {
        if (std::numeric_limits<double>::has_infinity) {
            nonConstThis->fDouble = std::numeric_limits<double>::infinity();
        } else {
            nonConstThis->fDouble = std::numeric_limits<double>::max();
        }
        if (!isPositive()) {
            nonConstThis->fDouble = -fDouble;
        } 
    } 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);
            // TODO:  how many extra digits should be included for an accurate conversion?
        } else {
            uprv_decNumberToString(this->fDecNumber, s);
        }
        U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18);
        
        if (gDecimal != '.') {
            char *decimalPt = strchr(s, '.');
            if (decimalPt != NULL) {
                *decimalPt = gDecimal;
            }
        }
        char *end = NULL;
        nonConstThis->fDouble = uprv_strtod(s, &end);
    }
    nonConstThis->fHaveDouble = TRUE;
    return fDouble;
}

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

/**
 *  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.   Round if there is a fractional part.
 *  Return zero if the number cannot be represented.
 */
int64_t DigitList::getInt64() /*const*/ {
    // Round if non-integer.   (Truncate or round?)
    // 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;
    }
    decNumber *workingNum = fDecNumber;

    if (fDecNumber->exponent != 0) {
        // Force to an integer, with zero exponent, rounding if necessary.
        DigitList copy(*this);
        DigitList zero;
        uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext);
        workingNum = copy.fDecNumber;
    }

    uint64_t value = 0;
    int32_t numDigits = workingNum->digits;
    for (int i = numDigits-1; i>=0 ; --i) {
        int v = workingNum->lsu[i];
        value = value * (uint64_t)10 + (uint64_t)v;
    }
    if (decNumberIsNegative(workingNum)) {
        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 (numDigits == 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);
    fDouble = source;
    fHaveDouble = TRUE;
}

// -------------------------------------
/**
 * @param maximumDigits The maximum digits to be generated.  If zero,
 * there is no maximum -- generate all digits.
 */
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);
    fDouble = (double)source;
    fHaveDouble = TRUE;
}


// -------------------------------------
/**
 * 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) {
    if (U_FAILURE(status)) {
        return;
    }

    // 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;
    }
    fHaveDouble = FALSE;
}   

/**
 * 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]+e[+-][0-9]+/
    sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source);
    U_ASSERT(uprv_strlen(rep) < sizeof(rep));

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

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

/*
 * 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);
    fHaveDouble = FALSE;
}

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

/*
 * 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);
    fHaveDouble = FALSE;
}

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

/*
 * 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);
    fHaveDouble = FALSE;
}


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();
    fHaveDouble = FALSE;
}

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

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


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


U_NAMESPACE_END
#endif // #if !UCONFIG_NO_FORMATTING

//eof
