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