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