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