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 
62 U_NAMESPACE_BEGIN
63 
64 // -------------------------------------
65 // default constructor
66 
DigitList()67 DigitList::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 
~DigitList()82 DigitList::~DigitList()
83 {
84 }
85 
86 // -------------------------------------
87 // copy constructor
88 
DigitList(const DigitList & other)89 DigitList::DigitList(const DigitList &other)
90 {
91     fDecNumber = fStorage.getAlias();
92     *this = other;
93 }
94 
95 
96 // -------------------------------------
97 // assignment operator
98 
99 DigitList&
operator =(const DigitList & other)100 DigitList::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 
134 UBool
operator ==(const DigitList & that) const135 DigitList::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
compare(const DigitList & other)157 int32_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.
177 void
reduce()178 DigitList::reduce() {
179     uprv_decNumberReduce(fDecNumber, fDecNumber, &fContext);
180 }
181 
182 
183 // -------------------------------------
184 //  trim - remove trailing fraction zero digits.
185 void
trim()186 DigitList::trim() {
187     uprv_decNumberTrim(fDecNumber);
188 }
189 
190 // -------------------------------------
191 // Resets the digit list; sets all the digits to zero.
192 
193 void
clear()194 DigitList::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  */
209 static int32_t
formatBase10(int64_t number,char * outputStr)210 formatBase10(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 
253 void
setRoundingMode(DecimalFormat::ERoundingMode m)254 DigitList::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 
278 void
setPositive(UBool s)279 DigitList::setPositive(UBool s) {
280     if (s) {
281         fDecNumber->bits &= ~DECNEG;
282     } else {
283         fDecNumber->bits |= DECNEG;
284     }
285     internalClear();
286 }
287 // -------------------------------------
288 
289 void
setDecimalAt(int32_t d)290 DigitList::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 
303 int32_t
getDecimalAt()304 DigitList::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 
312 void
setCount(int32_t c)313 DigitList::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 
325 int32_t
getCount() const326 DigitList::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 
336 void
setDigit(int32_t i,char v)337 DigitList::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 
346 char
getDigit(int32_t i)347 DigitList::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()
354 uint8_t
getDigitValue(int32_t i)355 DigitList::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 //
369 void
append(char digit)370 DigitList::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 
getStrtodDecimalSeparator()400 char 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  */
430 double
getDouble() const431 DigitList::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  */
getLong()514 int32_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  */
getInt64()539 int64_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  */
getDecimal(CharString & str,UErrorCode & status)596 void 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  */
619 UBool
fitsIntoLong(UBool ignoreNegativeZero)620 DigitList::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  */
666 UBool
fitsIntoInt64(UBool ignoreNegativeZero)667 DigitList::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 
710 void
set(int32_t source)711 DigitList::set(int32_t source)
712 {
713     set((int64_t)source);
714     internalSetDouble(source);
715 }
716 
717 // -------------------------------------
718 /**
719  * Set an int64, via decnumber
720  */
721 void
set(int64_t source)722 DigitList::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  */
735 void
setInteger(int64_t source)736 DigitList::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  */
752 void
set(const StringPiece & source,UErrorCode & status,uint32_t)753 DigitList::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  */
812 void
set(double source)813 DigitList::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  */
855 void
mult(const DigitList & other,UErrorCode & status)856 DigitList::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  */
879 void
div(const DigitList & other,UErrorCode & status)880 DigitList::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  */
894 void
ensureCapacity(int32_t requestedCapacity,UErrorCode & status)895 DigitList::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  */
927 void
round(int32_t maximumDigits)928 DigitList::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 
944 void
roundFixedPoint(int32_t maximumFractionDigits)945 DigitList::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 
962 void
toIntegralValue()963 DigitList::toIntegralValue() {
964     uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext);
965 }
966 
967 
968 // -------------------------------------
969 UBool
isZero() const970 DigitList::isZero() const
971 {
972     return decNumberIsZero(fDecNumber);
973 }
974 
975 // -------------------------------------
976 int32_t
getUpperExponent() const977 DigitList::getUpperExponent() const {
978     return fDecNumber->digits + fDecNumber->exponent;
979 }
980 
981 DigitInterval &
getSmallestInterval(DigitInterval & result) const982 DigitList::getSmallestInterval(DigitInterval &result) const {
983     result.setLeastSignificantInclusive(fDecNumber->exponent);
984     result.setMostSignificantExclusive(getUpperExponent());
985     return result;
986 }
987 
988 uint8_t
getDigitByExponent(int32_t exponent) const989 DigitList::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 
997 void
appendDigitsTo(CharString & str,UErrorCode & status) const998 DigitList::appendDigitsTo(CharString &str, UErrorCode &status) const {
999     str.append((const char *) fDecNumber->lsu, fDecNumber->digits, status);
1000 }
1001 
1002 void
roundAtExponent(int32_t exponent,int32_t maxSigDigits)1003 DigitList::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 
1022 void
quantize(const DigitList & quantity,UErrorCode & status)1023 DigitList::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 
1033 int32_t
getScientificExponent(int32_t minIntDigitCount,int32_t exponentMultiplier) const1034 DigitList::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 
1052 int32_t
toScientific(int32_t minIntDigitCount,int32_t exponentMultiplier)1053 DigitList::toScientific(
1054         int32_t minIntDigitCount, int32_t exponentMultiplier) {
1055     int32_t exponent = getScientificExponent(
1056             minIntDigitCount, exponentMultiplier);
1057     shiftDecimalRight(-exponent);
1058     return exponent;
1059 }
1060 
1061 void
shiftDecimalRight(int32_t n)1062 DigitList::shiftDecimalRight(int32_t n) {
1063     fDecNumber->exponent += n;
1064     internalClear();
1065 }
1066 
1067 U_NAMESPACE_END
1068 #endif // #if !UCONFIG_NO_FORMATTING
1069 
1070 //eof
1071