1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
31b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert*   Copyright (C) 1997-2015, International Business Machines
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File DIGITLST.CPP
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/21/97    clhuang     Converted from java.
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/21/97    clhuang     Implemented with new APIs.
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/27/97    helena      Updated to pass the simple test after code review.
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/31/97    aliu        Moved isLONG_MIN to here, and fixed it.
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   04/15/97    aliu        Changed MAX_COUNT to DBL_DIG.  Changed Digit to char.
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                           Reworked representation by replacing fDecimalAt
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                           with fExponent.
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   04/16/97    aliu        Rewrote set() and getDouble() to use sprintf/atof
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                           to do digit conversion.
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   09/09/97    aliu        Modified for exponential notation support.
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   08/02/98    stephen     Added nearest/even rounding
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                            Fixed bug in fitsIntoLong
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "digitlst.h"
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h"
3127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "charstr.h"
3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "mutex.h"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h"
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <limits.h>
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <limits>
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class DigitList
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    A wrapper onto decNumber.
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Used to be standalone.
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This is the zero digit.  The base for the digits returned by getDigit()
5127f654740f2a26ad62a5c155af9199af9e69b889claireho * Note that it is the platform invariant digit, and is not Unicode.
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kZero '0'
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Only for 32 bit numbers. Ignore the negative sign. */
5754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const char LONG_MIN_REP[] = "2147483648";
5854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const char I64_MIN_REP[] = "9223372036854775808";
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// default constructor
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::DigitList()
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decContextDefault(&fContext, DEC_INIT_BASE);
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.traps  = 0;
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
7127f654740f2a26ad62a5c155af9199af9e69b889claireho    fContext.digits = fStorage.getCapacity();
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
7327f654740f2a26ad62a5c155af9199af9e69b889claireho    fDecNumber = fStorage.getAlias();
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberZero(fDecNumber);
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
76103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalSetDouble(0.0);
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
79bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru// -------------------------------------
80bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDigitList::~DigitList()
82bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru{
83bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru}
84bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// copy constructor
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::DigitList(const DigitList &other)
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
9027f654740f2a26ad62a5c155af9199af9e69b889claireho    fDecNumber = fStorage.getAlias();
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *this = other;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// assignment operator
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList&
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::operator=(const DigitList& other)
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (this != &other)
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_memcpy(&fContext, &other.fContext, sizeof(decContext));
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10527f654740f2a26ad62a5c155af9199af9e69b889claireho        if (other.fStorage.getCapacity() > fStorage.getCapacity()) {
10627f654740f2a26ad62a5c155af9199af9e69b889claireho            fDecNumber = fStorage.resize(other.fStorage.getCapacity());
10727f654740f2a26ad62a5c155af9199af9e69b889claireho        }
10827f654740f2a26ad62a5c155af9199af9e69b889claireho        // Always reset the fContext.digits, even if fDecNumber was not reallocated,
10927f654740f2a26ad62a5c155af9199af9e69b889claireho        // because above we copied fContext from other.fContext.
11027f654740f2a26ad62a5c155af9199af9e69b889claireho        fContext.digits = fStorage.getCapacity();
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_decNumberCopy(fDecNumber, other.fDecNumber);
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
114103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // fDouble is lazily created and cached.
115103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // Avoid potential races with that happening with other.fDouble
116103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // while we are doing the assignment.
117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Mutex mutex;
118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if(other.fHave==kDouble) {
120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius              fUnion.fDouble = other.fUnion.fDouble;
121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if(other.fHave==kInt64) {
122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius              fUnion.fInt64 = other.fUnion.fInt64;
123103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            fHave = other.fHave;
125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return *this;
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    operator ==  (does not exactly match the old DigitList function)
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::operator==(const DigitList& that) const
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (this == &that) {
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return TRUE;
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    decNumber n;  // Has space for only a none digit value.
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    decContext c;
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decContextDefault(&c, DEC_INIT_BASE);
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    c.digits = 1;
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    c.traps = 0;
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberCompare(&n, this->fDecNumber, that.fDecNumber, &c);
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UBool result = decNumberIsZero(&n);
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      comparison function.   Returns
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//         Not Comparable :  -2
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//                      < :  -1
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//                     == :   0
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//                      > :  +1
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t DigitList::compare(const DigitList &other) {
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    decNumber   result;
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t     savedDigits = fContext.digits;
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.digits = 1;
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberCompare(&result, this->fDecNumber, other.fDecNumber, &fContext);
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.digits = savedDigits;
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(&result)) {
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (decNumberIsSpecial(&result)) {
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return -2;
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (result.bits & DECNEG) {
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return -1;
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 1;
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  Reduce - remove trailing zero digits.
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::reduce() {
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberReduce(fDecNumber, fDecNumber, &fContext);
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  trim - remove trailing fraction zero digits.
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::trim() {
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberTrim(fDecNumber);
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Resets the digit list; sets all the digits to zero.
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::clear()
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberZero(fDecNumber);
19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalSetDouble(0.0);
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Formats a int64_t number into a base 10 string representation, and NULL terminates it.
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param number The number to format
20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param outputStr The string to output to.  Must be at least MAX_DIGITS+2 in length (21),
20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *                  to hold the longest int64_t value.
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the number of digits written, not including the sign.
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoformatBase10(int64_t number, char *outputStr) {
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // The number is output backwards, starting with the LSD.
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Fill the buffer from the far end.  After the number is complete,
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // slide the string contents to the front.
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const int32_t MAX_IDX = MAX_DIGITS+2;
21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t destIdx = MAX_IDX;
21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    outputStr[--destIdx] = 0;
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int64_t  n = number;
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (number < 0) {   // Negative numbers are slightly larger than a postive
22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        outputStr[--destIdx] = (char)(-(n % 10) + kZero);
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        n /= -10;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    do {
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        outputStr[--destIdx] = (char)(n % 10 + kZero);
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        n /= 10;
22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } while (n > 0);
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (number < 0) {
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        outputStr[--destIdx] = '-';
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Slide the number to the start of the output str
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(destIdx >= 0);
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length = MAX_IDX - destIdx;
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_memmove(outputStr, outputStr+MAX_IDX-length, length);
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return length;
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//  setRoundingMode()
244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//    For most modes, the meaning and names are the same between the decNumber library
245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//      (which DigitList follows) and the ICU Formatting Rounding Mode values.
246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//      The flag constants are different, however.
247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//     Note that ICU's kRoundingUnnecessary is not implemented directly by DigitList.
249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//     This mode, inherited from Java, means that numbers that would not format exactly
250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//     will return an error when formatting is attempted.
25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setRoundingMode(DecimalFormat::ERoundingMode m) {
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    enum rounding r;
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    switch (m) {
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundCeiling:  r = DEC_ROUND_CEILING;   break;
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundFloor:    r = DEC_ROUND_FLOOR;     break;
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundDown:     r = DEC_ROUND_DOWN;      break;
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundUp:       r = DEC_ROUND_UP;        break;
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundHalfEven: r = DEC_ROUND_HALF_EVEN; break;
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundHalfDown: r = DEC_ROUND_HALF_DOWN; break;
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case  DecimalFormat::kRoundHalfUp:   r = DEC_ROUND_HALF_UP;   break;
264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      case  DecimalFormat::kRoundUnnecessary: r = DEC_ROUND_HALF_EVEN; break;
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      default:
26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         // TODO: how to report the problem?
26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         // Leave existing mode unchanged.
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         r = uprv_decContextGetRounding(&fContext);
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decContextSetRounding(&fContext, r);
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setPositive(UBool s) {
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (s) {
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->bits &= ~DECNEG;
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->bits |= DECNEG;
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
28850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
28950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setDecimalAt(int32_t d) {
29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0);  // Not Infinity or NaN
29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(d-1>-999999999);
29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(d-1< 999999999);
29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t adjustedDigits = fDecNumber->digits;
29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(fDecNumber)) {
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Account for difference in how zero is represented between DigitList & decNumber.
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedDigits = 0;
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fDecNumber->exponent = d - adjustedDigits;
299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDecimalAt() {
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0);  // Not Infinity or NaN
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(fDecNumber) || ((fDecNumber->bits & DECSPECIAL) != 0)) {
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return fDecNumber->exponent;  // Exponent should be zero for these cases.
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return fDecNumber->exponent + fDecNumber->digits;
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setCount(int32_t c)  {
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(c <= fContext.digits);
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (c == 0) {
31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // For a value of zero, DigitList sets all fields to zero, while
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // decNumber keeps one digit (with that digit being a zero)
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        c = 1;
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->lsu[0] = 0;
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fDecNumber->digits = c;
321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getCount() const {
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(fDecNumber) && fDecNumber->exponent==0) {
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       // The extra test for exponent==0 is needed because parsing sometimes appends
32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       // zero digits.  It's bogus, decimalFormatter parsing needs to be cleaned up.
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       return 0;
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       return fDecNumber->digits;
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setDigit(int32_t i, char v) {
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t count = fDecNumber->digits;
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(i<count);
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(v>='0' && v<='9');
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    v &= 0x0f;
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fDecNumber->lsu[count-i-1] = v;
342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehochar
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDigit(int32_t i) {
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t count = fDecNumber->digits;
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(i<count);
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return fDecNumber->lsu[count-i-1] + '0';
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
35227f654740f2a26ad62a5c155af9199af9e69b889claireho// copied from DigitList::getDigit()
35327f654740f2a26ad62a5c155af9199af9e69b889clairehouint8_t
35427f654740f2a26ad62a5c155af9199af9e69b889clairehoDigitList::getDigitValue(int32_t i) {
35527f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t count = fDecNumber->digits;
35627f654740f2a26ad62a5c155af9199af9e69b889claireho    U_ASSERT(i<count);
35727f654740f2a26ad62a5c155af9199af9e69b889claireho    return fDecNumber->lsu[count-i-1];
35827f654740f2a26ad62a5c155af9199af9e69b889claireho}
35927f654740f2a26ad62a5c155af9199af9e69b889claireho
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Appends the digit to the digit list if it's not out of scope.
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Ignores the digit, otherwise.
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// This function is horribly inefficient to implement with decNumber because
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// the digits are stored least significant first, which requires moving all
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// existing digits down one to make space for the new one to be appended.
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::append(char digit)
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(digit>='0' && digit<='9');
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Ignore digits which exceed the precision we can represent
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    And don't fix for larger precision.  Fix callers instead.
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(fDecNumber)) {
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Zero needs to be special cased because of the difference in the way
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // that the old DigitList and decNumber represent it.
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // digit cout was zero for digitList, is one for decNumber
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->lsu[0] = digit & 0x0f;
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->digits = 1;
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fDecNumber->exponent--;     // To match the old digit list implementation.
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t nDigits = fDecNumber->digits;
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (nDigits < fContext.digits) {
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            int i;
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            for (i=nDigits; i>0; i--) {
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                fDecNumber->lsu[i] = fDecNumber->lsu[i-1];
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fDecNumber->lsu[0] = digit & 0x0f;
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fDecNumber->digits++;
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // DigitList emulation - appending doesn't change the magnitude of existing
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            //                       digits.  With decNumber's decimal being after the
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            //                       least signficant digit, we need to adjust the exponent.
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fDecNumber->exponent--;
39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
396103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Currently, getDouble() depends on strtod() to do its conversion.
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * WARNING!!
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is an extremely costly function. ~1/2 of the conversion time
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * can be linked to this function.
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudouble
40950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDouble() const
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
411103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    static char gDecimal = 0;
412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    char decimalSeparator;
413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    {
414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        Mutex mutex;
415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fHave == kDouble) {
416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return fUnion.fDouble;
417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if(fHave == kInt64) {
418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return (double)fUnion.fInt64;
419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        decimalSeparator = gDecimal;
42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (decimalSeparator == 0) {
424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // We need to know the decimal separator character that will be used with strtod().
425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Depends on the C runtime global locale.
426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Most commonly is '.'
427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // TODO: caching could fail if the global locale is changed on the fly.
42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char rep[MAX_DIGITS];
42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        sprintf(rep, "%+1.1f", 1.0);
430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        decimalSeparator = rep[2];
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    double tDouble = 0.0;
43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (isZero()) {
435103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        tDouble = 0.0;
43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (decNumberIsNegative(fDecNumber)) {
437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            tDouble /= -1;
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (isInfinite()) {
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (std::numeric_limits<double>::has_infinity) {
441103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            tDouble = std::numeric_limits<double>::infinity();
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else {
443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            tDouble = std::numeric_limits<double>::max();
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (!isPositive()) {
446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            tDouble = -tDouble; //this was incorrectly "-fDouble" originally.
447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        MaybeStackArray<char, MAX_DBL_DIGITS+18> s;
45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           // Note:  14 is a  magic constant from the decNumber library documentation,
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           //        the max number of extra characters beyond the number of digits
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           //        needed to represent the number in string form.  Add a few more
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           //        for the additional digits we retain.
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Round down to appx. double precision, if the number is longer than that.
45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Copy the number first, so that we don't modify the original.
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (getCount() > MAX_DBL_DIGITS + 3) {
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            DigitList numToConvert(*this);
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            numToConvert.reduce();    // Removes any trailing zeros, so that digit count is good.
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            numToConvert.round(MAX_DBL_DIGITS+3);
46154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            uprv_decNumberToString(numToConvert.fDecNumber, s.getAlias());
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // TODO:  how many extra digits should be included for an accurate conversion?
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else {
46454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            uprv_decNumberToString(this->fDecNumber, s.getAlias());
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18);
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
468103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (decimalSeparator != '.') {
46954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            char *decimalPt = strchr(s.getAlias(), '.');
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (decimalPt != NULL) {
471103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                *decimalPt = decimalSeparator;
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char *end = NULL;
47554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        tDouble = uprv_strtod(s.getAlias(), &end);
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
477103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    {
478103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        Mutex mutex;
479103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        DigitList *nonConstThis = const_cast<DigitList *>(this);
480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        nonConstThis->internalSetDouble(tDouble);
481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        gDecimal = decimalSeparator;
482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return tDouble;
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *  convert this number to an int32_t.   Round if there is a fractional part.
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *  Return zero if the number cannot be represented.
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t DigitList::getLong() /*const*/
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t result = 0;
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->digits + fDecNumber->exponent > 10) {
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Overflow, absolute value too big.
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->exponent != 0) {
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Force to an integer, with zero exponent, rounding if necessary.
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //   (decNumberToInt32 will only work if the exponent is exactly zero.)
50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        DigitList copy(*this);
50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        DigitList zero;
50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext);
50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result = uprv_decNumberToInt32(copy.fDecNumber, &fContext);
50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result = uprv_decNumberToInt32(fDecNumber, &fContext);
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
5143ef011cb2ded20c46f764e284c6a10f49a9923f8claireho *  convert this number to an int64_t.   Truncate if there is a fractional part.
51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *  Return zero if the number cannot be represented.
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
51750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint64_t DigitList::getInt64() /*const*/ {
518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(fHave==kInt64) {
519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      return fUnion.fInt64;
520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
5213ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    // Truncate if non-integer.
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Return 0 if out of range.
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Range of in64_t is -9223372036854775808 to 9223372036854775807  (19 digits)
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->digits + fDecNumber->exponent > 19) {
52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Overflow, absolute value too big.
52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5303ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    // The number of integer digits may differ from the number of digits stored
5313ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    //   in the decimal number.
5323ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    //     for 12.345  numIntDigits = 2, number->digits = 5
5333ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    //     for 12E4    numIntDigits = 6, number->digits = 2
5343ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    // The conversion ignores the fraction digits in the first case,
5353ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    // and fakes up extra zero digits in the second.
5363ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    // TODO:  It would be faster to store a table of powers of ten to multiply by
5373ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    //        instead of looping over zero digits, multiplying each time.
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
5393ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    int32_t numIntDigits = fDecNumber->digits + fDecNumber->exponent;
54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uint64_t value = 0;
5413ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    for (int32_t i = 0; i < numIntDigits; i++) {
5423ef011cb2ded20c46f764e284c6a10f49a9923f8claireho        // Loop is iterating over digits starting with the most significant.
5433ef011cb2ded20c46f764e284c6a10f49a9923f8claireho        // Numbers are stored with the least significant digit at index zero.
5443ef011cb2ded20c46f764e284c6a10f49a9923f8claireho        int32_t digitIndex = fDecNumber->digits - i - 1;
5453ef011cb2ded20c46f764e284c6a10f49a9923f8claireho        int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0;
54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        value = value * (uint64_t)10 + (uint64_t)v;
54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
5483ef011cb2ded20c46f764e284c6a10f49a9923f8claireho
5493ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    if (decNumberIsNegative(fDecNumber)) {
55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        value = ~value;
55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        value += 1;
55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int64_t svalue = (int64_t)value;
55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Check overflow.  It's convenient that the MSD is 9 only on overflow, the amount of
55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //                  overflow can't wrap too far.  The test will also fail -0, but
55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //                  that does no harm; the right answer is 0.
5583ef011cb2ded20c46f764e284c6a10f49a9923f8claireho    if (numIntDigits == 19) {
55950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (( decNumberIsNegative(fDecNumber) && svalue>0) ||
56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            (!decNumberIsNegative(fDecNumber) && svalue<0)) {
56150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            svalue = 0;
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return svalue;
56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
568103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
56950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *  Return a string form of this number.
57150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *     Format is as defined by the decNumber library, for interchange of
57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *     decimal numbers.
57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
57427f654740f2a26ad62a5c155af9199af9e69b889clairehovoid DigitList::getDecimal(CharString &str, UErrorCode &status) {
57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
57650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
57827f654740f2a26ad62a5c155af9199af9e69b889claireho
57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // A decimal number in string form can, worst case, be 14 characters longer
58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  than the number of digits.  So says the decNumber library doc.
58127f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t maxLength = fDecNumber->digits + 14;
58227f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t capacity = 0;
58327f654740f2a26ad62a5c155af9199af9e69b889claireho    char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status);
58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;    // Memory allocation error on growing the string.
58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
58727f654740f2a26ad62a5c155af9199af9e69b889claireho    U_ASSERT(capacity >= maxLength);
58827f654740f2a26ad62a5c155af9199af9e69b889claireho    uprv_decNumberToString(this->fDecNumber, buffer);
58927f654740f2a26ad62a5c155af9199af9e69b889claireho    U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength);
59027f654740f2a26ad62a5c155af9199af9e69b889claireho    str.append(buffer, -1, status);
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Return true if this is an integer value that can be held
59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * by an int32_t type.
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::fitsIntoLong(UBool ignoreNegativeZero) /*const*/
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsSpecial(this->fDecNumber)) {
60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // NaN or Infinity.  Does not fit in int32.
60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberTrim(this->fDecNumber);
60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->exponent < 0) {
60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Number contains fraction digits.
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero &&
61050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (fDecNumber->bits & DECNEG) != 0) {
61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Negative Zero, not ingored.  Cannot represent as a long.
61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
61350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
61450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->digits + fDecNumber->exponent < 10) {
61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // The number is 9 or fewer digits.
61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // The max and min int32 are 10 digts, so this number fits.
61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // This is the common case.
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // TODO:  Should cache these constants; construction is relatively costly.
62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //        But not of huge consequence; they're only needed for 10 digit ints.
62350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode status = U_ZERO_ERROR;
62450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList min32; min32.set("-2147483648", status);
62550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (this->compare(min32) < 0) {
62650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
62750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
62850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList max32; max32.set("2147483647", status);
62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (this->compare(max32) > 0) {
63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return true;
63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return true if the number represented by this object can fit into
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a long.
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::fitsIntoInt64(UBool ignoreNegativeZero) /*const*/
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsSpecial(this->fDecNumber)) {
64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // NaN or Infinity.  Does not fit in int32.
64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberTrim(this->fDecNumber);
65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->exponent < 0) {
65350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Number contains fraction digits.
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
65650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero &&
65750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (fDecNumber->bits & DECNEG) != 0) {
65850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Negative Zero, not ingored.  Cannot represent as a long.
65950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
66150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->digits + fDecNumber->exponent < 19) {
66250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // The number is 18 or fewer digits.
66350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // The max and min int64 are 19 digts, so this number fits.
66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // This is the common case.
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
66650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // TODO:  Should cache these constants; construction is relatively costly.
66950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //        But not of huge consequence; they're only needed for 19 digit ints.
67050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode status = U_ZERO_ERROR;
67150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList min64; min64.set("-9223372036854775808", status);
67250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (this->compare(min64) < 0) {
67350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
67450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
67550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList max64; max64.set("9223372036854775807", status);
67650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (this->compare(max64) > 0) {
67750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
68050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
68150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
68250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return true;
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
68950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(int32_t source)
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    set((int64_t)source);
692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalSetDouble(source);
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
697103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Set an int64, via decnumber
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
70050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(int64_t source)
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char str[MAX_DIGITS+2];   // Leave room for sign and trailing nul.
70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    formatBase10(source, str);
70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(uprv_strlen(str) < sizeof(str));
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberFromString(fDecNumber, str, &fContext);
7071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    internalSetDouble(static_cast<double>(source));
708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
710103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/**
711103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Set an int64, with no decnumber
712103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */
713103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid
714103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusDigitList::setInteger(int64_t source)
715103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
716103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  fDecNumber=NULL;
717103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  internalSetInt64(source);
71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
72150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
72250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Set the DigitList from a decimal number string.
72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
72527f654740f2a26ad62a5c155af9199af9e69b889claireho * The incoming string _must_ be nul terminated, even though it is arriving
72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * as a StringPiece because that is what the decNumber library wants.
72750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We can get away with this for an internal function; it would not
72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * be acceptable for a public API.
72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
73050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
73154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) {
73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
73654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if 0
73754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if(fastpathBits==(kFastpathOk|kNoDecimal)) {
73854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      int32_t size = source.size();
73954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      const char *data = source.data();
74054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      int64_t r = 0;
74154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      int64_t m = 1;
74254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      // fast parse
74354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      while(size>0) {
74454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        char ch = data[--size];
74554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(ch=='+') {
74654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          break;
74754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if(ch=='-') {
74854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          r = -r;
74954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          break;
75054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else {
75154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          int64_t d = ch-'0';
75254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m);
75354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          r+=(d)*m;
75454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          m *= 10;
75554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
75654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      }
75754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      //printf("R=%d\n", r);
75854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      set(r);
75954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else
76054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
76154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {
76254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      // Figure out a max number of digits to use during the conversion, and
76354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      // resize the number up if necessary.
76454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      int32_t numDigits = source.length();
76554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      if (numDigits > fContext.digits) {
76627f654740f2a26ad62a5c155af9199af9e69b889claireho        // fContext.digits == fStorage.getCapacity()
76727f654740f2a26ad62a5c155af9199af9e69b889claireho        decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity());
76850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (t == NULL) {
76954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          status = U_MEMORY_ALLOCATION_ERROR;
77054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          return;
77150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
77227f654740f2a26ad62a5c155af9199af9e69b889claireho        fDecNumber = t;
77327f654740f2a26ad62a5c155af9199af9e69b889claireho        fContext.digits = numDigits;
77454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      }
77527f654740f2a26ad62a5c155af9199af9e69b889claireho
77654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      fContext.status = 0;
77754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      uprv_decNumberFromString(fDecNumber, source.data(), &fContext);
77854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      if ((fContext.status & DEC_Conversion_syntax) != 0) {
77950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_DECIMAL_NUMBER_SYNTAX_ERROR;
78054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      }
78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Set the digit list to a representation of the given double value.
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This method supports both fixed-point and exponential notation.
78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param source Value to be converted.
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
79150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(double source)
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for now, simple implementation; later, do proper IEEE stuff
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough)
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/
797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // Can also generate /[+-]nan/ or /[+-]inf/
798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific.
799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    //       That is why infinity is special cased here.
800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (uprv_isInfinite(source)) {
801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (uprv_isNegativeInfinity(source)) {
802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            uprv_strcpy(rep,"-inf"); // Handle negative infinity
803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            uprv_strcpy(rep,"inf");
805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    } else {
807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source);
808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
80950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    U_ASSERT(uprv_strlen(rep) < sizeof(rep));
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // uprv_decNumberFromString() will parse the string expecting '.' as a
812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // decimal separator, however sprintf() can use ',' in certain locales.
813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // Overwrite a ',' with '.' here before proceeding.
814103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    char *decimalSeparator = strchr(rep, ',');
815103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (decimalSeparator != NULL) {
816103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        *decimalSeparator = '.';
817103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
818103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Create a decNumber from the string.
82050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberFromString(fDecNumber, rep, &fContext);
82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberTrim(fDecNumber);
822103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalSetDouble(source);
82350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Multiply
82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *      The number will be expanded if need be to retain full precision.
83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *      In practice, for formatting, multiply is by 10, 100 or 1000, so more digits
83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *      will not be required for this use.
83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
83350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
83450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::mult(const DigitList &other, UErrorCode &status) {
83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.status = 0;
83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t requiredDigits = this->digits() + other.digits();
83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (requiredDigits > fContext.digits) {
83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        reduce();    // Remove any trailing zeros
83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t requiredDigits = this->digits() + other.digits();
84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ensureCapacity(requiredDigits, status);
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
84250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
84450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
84850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Divide
85050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *      The number will _not_ be expanded for inexact results.
85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *      TODO:  probably should expand some, for rounding increments that
85250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *             could add a few digits, e.g. .25, but not expand arbitrarily.
85350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
85450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
85550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::div(const DigitList &other, UErrorCode &status) {
85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
860103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
86150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
86350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
86550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * ensureCapacity.   Grow the digit storage for the number if it's less than the requested
86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *         amount.  Never reduce it.  Available size is kept in fContext.digits.
86850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
86950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
87050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::ensureCapacity(int32_t requestedCapacity, UErrorCode &status) {
87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
87450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (requestedCapacity <= 0) {
87550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_ILLEGAL_ARGUMENT_ERROR;
87650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
87750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (requestedCapacity > DEC_MAX_DIGITS) {
87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Don't report an error for requesting too much.
88050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Arithemetic Results will be rounded to what can be supported.
88150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //   At 999,999,999 max digits, exceeding the limit is not too likely!
88250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        requestedCapacity = DEC_MAX_DIGITS;
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
88450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (requestedCapacity > fContext.digits) {
88527f654740f2a26ad62a5c155af9199af9e69b889claireho        decNumber *newBuffer = fStorage.resize(requestedCapacity, fStorage.getCapacity());
88650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (newBuffer == NULL) {
88750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            status = U_MEMORY_ALLOCATION_ERROR;
88850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return;
88950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
89050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fContext.digits = requestedCapacity;
89127f654740f2a26ad62a5c155af9199af9e69b889claireho        fDecNumber = newBuffer;
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Round the representation to the given number of digits.
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param maximumDigits The maximum number of digits to be shown.
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Upon return, count will be less than or equal to maximumDigits.
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::round(int32_t maximumDigits)
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t savedDigits  = fContext.digits;
90650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.digits = maximumDigits;
90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fContext.digits = savedDigits;
90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberTrim(fDecNumber);
910103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
91450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
91550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::roundFixedPoint(int32_t maximumFractionDigits) {
91650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trim();        // Remove trailing zeros.
91750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fDecNumber->exponent >= -maximumFractionDigits) {
91850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    decNumber scale;   // Dummy decimal number, but with the desired number of
92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberZero(&scale);    //    fraction digits.
92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    scale.exponent = -maximumFractionDigits;
92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    scale.lsu[0] = 1;
92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext);
92650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trim();
927103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    internalClear();
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------------------------------------
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
93350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::toIntegralValue() {
93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext);
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
93750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
93850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::isZero() const
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
94250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return decNumberIsZero(fDecNumber);
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif // #if !UCONFIG_NO_FORMATTING
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof
949