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