1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 **********************************************************************
5 * Copyright (C) 1997-2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 **********************************************************************
11 * Modification History:
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
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 ******************************************************************************
29 #if defined(__CYGWIN__) && !defined(_GNU_SOURCE)
35 #if !UCONFIG_NO_FORMATTING
37 #include "unicode/putil.h"
44 #include "digitinterval.h"
47 #include "double-conversion.h"
54 using icu::double_conversion::DoubleToStringConverter
;
56 #if !defined(U_USE_STRTOD_L)
57 # if U_PLATFORM_USES_ONLY_WIN32_API
58 # define U_USE_STRTOD_L 1
59 # define U_HAVE_XLOCALE_H 0
60 # elif defined(U_HAVE_STRTOD_L)
61 # define U_USE_STRTOD_L U_HAVE_STRTOD_L
63 # define U_USE_STRTOD_L 0
75 // ***************************************************************************
77 // A wrapper onto decNumber.
78 // Used to be standalone.
79 // ***************************************************************************
82 * This is the zero digit. The base for the digits returned by getDigit()
83 * Note that it is the platform invariant digit, and is not Unicode.
88 /* Only for 32 bit numbers. Ignore the negative sign. */
89 //static const char LONG_MIN_REP[] = "2147483648";
90 //static const char I64_MIN_REP[] = "9223372036854775808";
95 // -------------------------------------
96 // default constructor
98 DigitList::DigitList()
100 uprv_decContextDefault(&fContext
, DEC_INIT_BASE
);
102 uprv_decContextSetRounding(&fContext
, DEC_ROUND_HALF_EVEN
);
103 fContext
.digits
= fStorage
.getCapacity();
105 fDecNumber
= fStorage
.getAlias();
106 uprv_decNumberZero(fDecNumber
);
108 internalSetDouble(0.0);
109 fFormatFullPrecision
= TRUE
; // Apple
112 // -------------------------------------
114 DigitList::~DigitList()
118 // -------------------------------------
121 DigitList::DigitList(const DigitList
&other
)
123 fDecNumber
= fStorage
.getAlias();
128 // -------------------------------------
129 // assignment operator
132 DigitList::operator=(const DigitList
& other
)
136 uprv_memcpy(&fContext
, &other
.fContext
, sizeof(decContext
));
138 if (other
.fStorage
.getCapacity() > fStorage
.getCapacity()) {
139 fDecNumber
= fStorage
.resize(other
.fStorage
.getCapacity());
141 // Always reset the fContext.digits, even if fDecNumber was not reallocated,
142 // because above we copied fContext from other.fContext.
143 fContext
.digits
= fStorage
.getCapacity();
144 uprv_decNumberCopy(fDecNumber
, other
.fDecNumber
);
147 // fDouble is lazily created and cached.
148 // Avoid potential races with that happening with other.fDouble
149 // while we are doing the assignment.
152 if(other
.fHave
==kDouble
) {
153 fUnion
.fDouble
= other
.fUnion
.fDouble
;
157 fFormatFullPrecision
= other
.fFormatFullPrecision
; // Apple
162 // -------------------------------------
163 // operator == (does not exactly match the old DigitList function)
166 DigitList::operator==(const DigitList
& that
) const
171 decNumber n
; // Has space for only a none digit value.
173 uprv_decContextDefault(&c
, DEC_INIT_BASE
);
177 uprv_decNumberCompare(&n
, this->fDecNumber
, that
.fDecNumber
, &c
);
178 UBool result
= decNumberIsZero(&n
);
182 // -------------------------------------
183 // comparison function. Returns
184 // Not Comparable : -2
188 int32_t DigitList::compare(const DigitList
&other
) {
190 int32_t savedDigits
= fContext
.digits
;
192 uprv_decNumberCompare(&result
, this->fDecNumber
, other
.fDecNumber
, &fContext
);
193 fContext
.digits
= savedDigits
;
194 if (decNumberIsZero(&result
)) {
196 } else if (decNumberIsSpecial(&result
)) {
198 } else if (result
.bits
& DECNEG
) {
206 // -------------------------------------
207 // Reduce - remove trailing zero digits.
209 DigitList::reduce() {
210 uprv_decNumberReduce(fDecNumber
, fDecNumber
, &fContext
);
214 // -------------------------------------
215 // trim - remove trailing fraction zero digits.
218 uprv_decNumberTrim(fDecNumber
);
221 // -------------------------------------
222 // Resets the digit list; sets all the digits to zero.
227 uprv_decNumberZero(fDecNumber
);
228 uprv_decContextSetRounding(&fContext
, DEC_ROUND_HALF_EVEN
);
229 internalSetDouble(0.0);
234 * Formats a int64_t number into a base 10 string representation, and NULL terminates it.
235 * @param number The number to format
236 * @param outputStr The string to output to. Must be at least MAX_DIGITS+2 in length (21),
237 * to hold the longest int64_t value.
238 * @return the number of digits written, not including the sign.
241 formatBase10(int64_t number
, char *outputStr
) {
242 // The number is output backwards, starting with the LSD.
243 // Fill the buffer from the far end. After the number is complete,
244 // slide the string contents to the front.
246 const int32_t MAX_IDX
= MAX_DIGITS
+2;
247 int32_t destIdx
= MAX_IDX
;
248 outputStr
[--destIdx
] = 0;
251 if (number
< 0) { // Negative numbers are slightly larger than a postive
252 outputStr
[--destIdx
] = (char)(-(n
% 10) + kZero
);
256 outputStr
[--destIdx
] = (char)(n
% 10 + kZero
);
261 outputStr
[--destIdx
] = '-';
264 // Slide the number to the start of the output str
265 U_ASSERT(destIdx
>= 0);
266 int32_t length
= MAX_IDX
- destIdx
;
267 uprv_memmove(outputStr
, outputStr
+MAX_IDX
-length
, length
);
273 // -------------------------------------
276 // For most modes, the meaning and names are the same between the decNumber library
277 // (which DigitList follows) and the ICU Formatting Rounding Mode values.
278 // The flag constants are different, however.
280 // Note that ICU's kRoundingUnnecessary is not implemented directly by DigitList.
281 // This mode, inherited from Java, means that numbers that would not format exactly
282 // will return an error when formatting is attempted.
285 DigitList::setRoundingMode(DecimalFormat::ERoundingMode m
) {
289 case DecimalFormat::kRoundCeiling
: r
= DEC_ROUND_CEILING
; break;
290 case DecimalFormat::kRoundFloor
: r
= DEC_ROUND_FLOOR
; break;
291 case DecimalFormat::kRoundDown
: r
= DEC_ROUND_DOWN
; break;
292 case DecimalFormat::kRoundUp
: r
= DEC_ROUND_UP
; break;
293 case DecimalFormat::kRoundHalfEven
: r
= DEC_ROUND_HALF_EVEN
; break;
294 case DecimalFormat::kRoundHalfDown
: r
= DEC_ROUND_HALF_DOWN
; break;
295 case DecimalFormat::kRoundHalfUp
: r
= DEC_ROUND_HALF_UP
; break;
296 case DecimalFormat::kRoundUnnecessary
: r
= DEC_ROUND_HALF_EVEN
; break;
298 // TODO: how to report the problem?
299 // Leave existing mode unchanged.
300 r
= uprv_decContextGetRounding(&fContext
);
302 uprv_decContextSetRounding(&fContext
, r
);
307 // -------------------------------------
310 DigitList::setPositive(UBool s
) {
312 fDecNumber
->bits
&= ~DECNEG
;
314 fDecNumber
->bits
|= DECNEG
;
318 // -------------------------------------
321 DigitList::setDecimalAt(int32_t d
) {
322 U_ASSERT((fDecNumber
->bits
& DECSPECIAL
) == 0); // Not Infinity or NaN
323 U_ASSERT(d
-1>-999999999);
324 U_ASSERT(d
-1< 999999999);
325 int32_t adjustedDigits
= fDecNumber
->digits
;
326 if (decNumberIsZero(fDecNumber
)) {
327 // Account for difference in how zero is represented between DigitList & decNumber.
330 fDecNumber
->exponent
= d
- adjustedDigits
;
335 DigitList::getDecimalAt() {
336 U_ASSERT((fDecNumber
->bits
& DECSPECIAL
) == 0); // Not Infinity or NaN
337 if (decNumberIsZero(fDecNumber
) || ((fDecNumber
->bits
& DECSPECIAL
) != 0)) {
338 return fDecNumber
->exponent
; // Exponent should be zero for these cases.
340 return fDecNumber
->exponent
+ fDecNumber
->digits
;
344 DigitList::setCount(int32_t c
) {
345 U_ASSERT(c
<= fContext
.digits
);
347 // For a value of zero, DigitList sets all fields to zero, while
348 // decNumber keeps one digit (with that digit being a zero)
350 fDecNumber
->lsu
[0] = 0;
352 fDecNumber
->digits
= c
;
357 DigitList::getCount() const {
358 if (decNumberIsZero(fDecNumber
) && fDecNumber
->exponent
==0) {
359 // The extra test for exponent==0 is needed because parsing sometimes appends
360 // zero digits. It's bogus, decimalFormatter parsing needs to be cleaned up.
363 return fDecNumber
->digits
;
368 DigitList::setDigit(int32_t i
, char v
) {
369 int32_t count
= fDecNumber
->digits
;
371 U_ASSERT(v
>='0' && v
<='9');
373 fDecNumber
->lsu
[count
-i
-1] = v
;
378 DigitList::getDigit(int32_t i
) {
379 int32_t count
= fDecNumber
->digits
;
381 return fDecNumber
->lsu
[count
-i
-1] + '0';
384 // copied from DigitList::getDigit()
386 DigitList::getDigitValue(int32_t i
) {
387 int32_t count
= fDecNumber
->digits
;
389 return fDecNumber
->lsu
[count
-i
-1];
392 // -------------------------------------
393 // Appends the digit to the digit list if it's not out of scope.
394 // Ignores the digit, otherwise.
396 // This function is horribly inefficient to implement with decNumber because
397 // the digits are stored least significant first, which requires moving all
398 // existing digits down one to make space for the new one to be appended.
401 DigitList::append(char digit
)
403 U_ASSERT(digit
>='0' && digit
<='9');
404 // Ignore digits which exceed the precision we can represent
405 // And don't fix for larger precision. Fix callers instead.
406 if (decNumberIsZero(fDecNumber
)) {
407 // Zero needs to be special cased because of the difference in the way
408 // that the old DigitList and decNumber represent it.
409 // digit cout was zero for digitList, is one for decNumber
410 fDecNumber
->lsu
[0] = digit
& 0x0f;
411 fDecNumber
->digits
= 1;
412 fDecNumber
->exponent
--; // To match the old digit list implementation.
414 int32_t nDigits
= fDecNumber
->digits
;
415 if (nDigits
< fContext
.digits
) {
417 for (i
=nDigits
; i
>0; i
--) {
418 fDecNumber
->lsu
[i
] = fDecNumber
->lsu
[i
-1];
420 fDecNumber
->lsu
[0] = digit
& 0x0f;
421 fDecNumber
->digits
++;
422 // DigitList emulation - appending doesn't change the magnitude of existing
423 // digits. With decNumber's decimal being after the
424 // least signficant digit, we need to adjust the exponent.
425 fDecNumber
->exponent
--;
431 // -------------------------------------
434 * Currently, getDouble() depends on strtod() to do its conversion.
437 * This is an extremely costly function. ~1/2 of the conversion time
438 * can be linked to this function.
441 DigitList::getDouble() const
445 if (fHave
== kDouble
) {
446 return fUnion
.fDouble
;
450 double tDouble
= 0.0;
453 if (decNumberIsNegative(fDecNumber
)) {
456 } else if (isInfinite()) {
457 if (std::numeric_limits
<double>::has_infinity
) {
458 tDouble
= std::numeric_limits
<double>::infinity();
460 tDouble
= std::numeric_limits
<double>::max();
463 tDouble
= -tDouble
; //this was incorrectly "-fDouble" originally.
466 MaybeStackArray
<char, MAX_DBL_DIGITS
+18> s
;
467 // Note: 14 is a magic constant from the decNumber library documentation,
468 // the max number of extra characters beyond the number of digits
469 // needed to represent the number in string form. Add a few more
470 // for the additional digits we retain.
472 // Round down to appx. double precision, if the number is longer than that.
473 // Copy the number first, so that we don't modify the original.
474 if (getCount() > MAX_DBL_DIGITS
+ 3) {
475 DigitList
numToConvert(*this);
476 numToConvert
.reduce(); // Removes any trailing zeros, so that digit count is good.
477 numToConvert
.round(MAX_DBL_DIGITS
+3);
478 uprv_decNumberToString(numToConvert
.fDecNumber
, s
.getAlias());
479 // TODO: how many extra digits should be included for an accurate conversion?
481 uprv_decNumberToString(this->fDecNumber
, s
.getAlias());
483 U_ASSERT(uprv_strlen(&s
[0]) < MAX_DBL_DIGITS
+18);
486 tDouble
= decimalStrToDouble(s
.getAlias(), &end
);
490 DigitList
*nonConstThis
= const_cast<DigitList
*>(this);
491 nonConstThis
->internalSetDouble(tDouble
);
496 #if U_USE_STRTOD_L && U_PLATFORM_USES_ONLY_WIN32_API
497 # define locale_t _locale_t
498 # define freelocale _free_locale
499 # define strtod_l _strtod_l
503 static locale_t gCLocale
= (locale_t
)0;
505 static icu::UInitOnce gCLocaleInitOnce
= U_INITONCE_INITIALIZER
;
508 // Cleanup callback func
509 static UBool U_CALLCONV
digitList_cleanup(void)
512 if (gCLocale
!= (locale_t
)0) {
513 freelocale(gCLocale
);
518 // C Locale initialization func
519 static void U_CALLCONV
initCLocale(void) {
520 ucln_i18n_registerCleanup(UCLN_I18N_DIGITLIST
, digitList_cleanup
);
522 # if U_PLATFORM_USES_ONLY_WIN32_API
523 gCLocale
= _create_locale(LC_ALL
, "C");
525 gCLocale
= newlocale(LC_ALL_MASK
, "C", (locale_t
)0);
532 DigitList::decimalStrToDouble(char *decstr
, char **end
) {
533 umtx_initOnce(gCLocaleInitOnce
, &initCLocale
);
535 return strtod_l(decstr
, end
, gCLocale
);
537 char *decimalPt
= strchr(decstr
, '.');
539 // We need to know the decimal separator character that will be used with strtod().
540 // Depends on the C runtime global locale.
541 // Most commonly is '.'
542 char rep
[MAX_DIGITS
];
543 sprintf(rep
, "%+1.1f", 1.0);
546 return uprv_strtod(decstr
, end
);
550 // -------------------------------------
553 * convert this number to an int32_t. Round if there is a fractional part.
554 * Return zero if the number cannot be represented.
556 int32_t DigitList::getLong() /*const*/
559 if (getUpperExponent() > 10) {
560 // Overflow, absolute value too big.
563 if (fDecNumber
->exponent
!= 0) {
564 // Force to an integer, with zero exponent, rounding if necessary.
565 // (decNumberToInt32 will only work if the exponent is exactly zero.)
566 DigitList
copy(*this);
568 uprv_decNumberQuantize(copy
.fDecNumber
, copy
.fDecNumber
, zero
.fDecNumber
, &fContext
);
569 result
= uprv_decNumberToInt32(copy
.fDecNumber
, &fContext
);
571 result
= uprv_decNumberToInt32(fDecNumber
, &fContext
);
578 * convert this number to an int64_t. Truncate if there is a fractional part.
579 * Return zero if the number cannot be represented.
581 int64_t DigitList::getInt64() /*const*/ {
582 // TODO: fast conversion if fHave == fDouble
584 // Truncate if non-integer.
585 // Return 0 if out of range.
586 // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digits)
588 if (getUpperExponent() > 19) {
589 // Overflow, absolute value too big.
593 // The number of integer digits may differ from the number of digits stored
594 // in the decimal number.
595 // for 12.345 numIntDigits = 2, number->digits = 5
596 // for 12E4 numIntDigits = 6, number->digits = 2
597 // The conversion ignores the fraction digits in the first case,
598 // and fakes up extra zero digits in the second.
599 // TODO: It would be faster to store a table of powers of ten to multiply by
600 // instead of looping over zero digits, multiplying each time.
602 int32_t numIntDigits
= getUpperExponent();
604 for (int32_t i
= 0; i
< numIntDigits
; i
++) {
605 // Loop is iterating over digits starting with the most significant.
606 // Numbers are stored with the least significant digit at index zero.
607 int32_t digitIndex
= fDecNumber
->digits
- i
- 1;
608 int32_t v
= (digitIndex
>= 0) ? fDecNumber
->lsu
[digitIndex
] : 0;
609 value
= value
* (uint64_t)10 + (uint64_t)v
;
612 if (decNumberIsNegative(fDecNumber
)) {
616 int64_t svalue
= (int64_t)value
;
618 // Check overflow. It's convenient that the MSD is 9 only on overflow, the amount of
619 // overflow can't wrap too far. The test will also fail -0, but
620 // that does no harm; the right answer is 0.
621 if (numIntDigits
== 19) {
622 if (( decNumberIsNegative(fDecNumber
) && svalue
>0) ||
623 (!decNumberIsNegative(fDecNumber
) && svalue
<0)) {
633 * Return a string form of this number.
634 * Format is as defined by the decNumber library, for interchange of
637 void DigitList::getDecimal(CharString
&str
, UErrorCode
&status
) {
638 if (U_FAILURE(status
)) {
642 // A decimal number in string form can, worst case, be 14 characters longer
643 // than the number of digits. So says the decNumber library doc.
644 int32_t maxLength
= fDecNumber
->digits
+ 14;
645 int32_t capacity
= 0;
646 char *buffer
= str
.clear().getAppendBuffer(maxLength
, 0, capacity
, status
);
647 if (U_FAILURE(status
)) {
648 return; // Memory allocation error on growing the string.
650 U_ASSERT(capacity
>= maxLength
);
651 uprv_decNumberToString(this->fDecNumber
, buffer
);
652 U_ASSERT((int32_t)uprv_strlen(buffer
) <= maxLength
);
653 str
.append(buffer
, -1, status
);
657 * Return true if this is an integer value that can be held
658 * by an int32_t type.
661 DigitList::fitsIntoLong(UBool ignoreNegativeZero
) /*const*/
663 if (decNumberIsSpecial(this->fDecNumber
)) {
664 // NaN or Infinity. Does not fit in int32.
667 uprv_decNumberTrim(this->fDecNumber
);
668 if (fDecNumber
->exponent
< 0) {
669 // Number contains fraction digits.
672 if (decNumberIsZero(this->fDecNumber
) && !ignoreNegativeZero
&&
673 (fDecNumber
->bits
& DECNEG
) != 0) {
674 // Negative Zero, not ingored. Cannot represent as a long.
677 if (getUpperExponent() < 10) {
678 // The number is 9 or fewer digits.
679 // The max and min int32 are 10 digts, so this number fits.
680 // This is the common case.
684 // TODO: Should cache these constants; construction is relatively costly.
685 // But not of huge consequence; they're only needed for 10 digit ints.
686 UErrorCode status
= U_ZERO_ERROR
;
687 DigitList min32
; min32
.set("-2147483648", status
);
688 if (this->compare(min32
) < 0) {
691 DigitList max32
; max32
.set("2147483647", status
);
692 if (this->compare(max32
) > 0) {
695 if (U_FAILURE(status
)) {
704 * Return true if the number represented by this object can fit into
708 DigitList::fitsIntoInt64(UBool ignoreNegativeZero
) /*const*/
710 if (decNumberIsSpecial(this->fDecNumber
)) {
711 // NaN or Infinity. Does not fit in int32.
714 uprv_decNumberTrim(this->fDecNumber
);
715 if (fDecNumber
->exponent
< 0) {
716 // Number contains fraction digits.
719 if (decNumberIsZero(this->fDecNumber
) && !ignoreNegativeZero
&&
720 (fDecNumber
->bits
& DECNEG
) != 0) {
721 // Negative Zero, not ingored. Cannot represent as a long.
724 if (getUpperExponent() < 19) {
725 // The number is 18 or fewer digits.
726 // The max and min int64 are 19 digts, so this number fits.
727 // This is the common case.
731 // TODO: Should cache these constants; construction is relatively costly.
732 // But not of huge consequence; they're only needed for 19 digit ints.
733 UErrorCode status
= U_ZERO_ERROR
;
734 DigitList min64
; min64
.set("-9223372036854775808", status
);
735 if (this->compare(min64
) < 0) {
738 DigitList max64
; max64
.set("9223372036854775807", status
);
739 if (this->compare(max64
) > 0) {
742 if (U_FAILURE(status
)) {
749 // -------------------------------------
752 DigitList::set(int32_t source
)
754 set((int64_t)source
);
755 internalSetDouble(source
);
758 // -------------------------------------
760 * Set an int64, via decnumber
763 DigitList::set(int64_t source
)
765 char str
[MAX_DIGITS
+2]; // Leave room for sign and trailing nul.
766 formatBase10(source
, str
);
767 U_ASSERT(uprv_strlen(str
) < sizeof(str
));
769 uprv_decNumberFromString(fDecNumber
, str
, &fContext
);
770 internalSetDouble(static_cast<double>(source
));
773 // -------------------------------------
775 * Set the DigitList from a decimal number string.
777 * The incoming string _must_ be nul terminated, even though it is arriving
778 * as a StringPiece because that is what the decNumber library wants.
779 * We can get away with this for an internal function; it would not
780 * be acceptable for a public API.
783 DigitList::set(StringPiece source
, UErrorCode
&status
, uint32_t /*fastpathBits*/) {
784 if (U_FAILURE(status
)) {
789 if(fastpathBits
==(kFastpathOk
|kNoDecimal
)) {
790 int32_t size
= source
.size();
791 const char *data
= source
.data();
796 char ch
= data
[--size
];
804 //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m);
809 //printf("R=%d\n", r);
814 // Figure out a max number of digits to use during the conversion, and
815 // resize the number up if necessary.
816 int32_t numDigits
= source
.length();
817 if (numDigits
> fContext
.digits
) {
818 // fContext.digits == fStorage.getCapacity()
819 decNumber
*t
= fStorage
.resize(numDigits
, fStorage
.getCapacity());
821 status
= U_MEMORY_ALLOCATION_ERROR
;
825 fContext
.digits
= numDigits
;
829 uprv_decNumberFromString(fDecNumber
, source
.data(), &fContext
);
830 if ((fContext
.status
& DEC_Conversion_syntax
) != 0) {
831 status
= U_DECIMAL_NUMBER_SYNTAX_ERROR
;
838 * Set the digit list to a representation of the given double value.
839 * This method supports both fixed-point and exponential notation.
840 * @param source Value to be converted.
843 DigitList::set(double source
)
845 // for now, simple implementation; later, do proper IEEE stuff
846 char rep
[MAX_DIGITS
+ 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough)
848 // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/
849 // Can also generate /[+-]nan/ or /[+-]inf/
850 // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific.
851 // That is why infinity is special cased here.
852 if (uprv_isInfinite(source
)) {
853 if (uprv_isNegativeInfinity(source
)) {
854 uprv_strcpy(rep
,"-inf"); // Handle negative infinity
856 uprv_strcpy(rep
,"inf");
858 } else if (uprv_isNaN(source
)) {
859 uprv_strcpy(rep
, "NaN");
860 } else if (!fFormatFullPrecision
) { // Apple
861 sprintf(rep
, "%+1.14e", source
); // 14 = DBL_DIG - 1
866 DoubleToStringConverter::DoubleToAscii(
868 DoubleToStringConverter::DtoaMode::SHORTEST
,
877 // Convert the raw buffer into a string for decNumber
878 int32_t power
= point
- length
;
893 rep
[length
++] = power
+ '0';
894 } else if (power
< 100) {
895 rep
[length
++] = (power
/ 10) + '0';
896 rep
[length
++] = (power
% 10) + '0';
898 U_ASSERT(power
< 1000);
899 rep
[length
+ 2] = (power
% 10) + '0';
901 rep
[length
+ 1] = (power
% 10) + '0';
903 rep
[length
] = power
+ '0';
908 U_ASSERT(uprv_strlen(rep
) < sizeof(rep
));
910 // uprv_decNumberFromString() will parse the string expecting '.' as a
911 // decimal separator, however sprintf() can use ',' in certain locales.
912 // Overwrite a ',' with '.' here before proceeding.
913 char *decimalSeparator
= strchr(rep
, ',');
914 if (decimalSeparator
!= NULL
) {
915 *decimalSeparator
= '.';
918 // Create a decNumber from the string.
919 uprv_decNumberFromString(fDecNumber
, rep
, &fContext
);
920 uprv_decNumberTrim(fDecNumber
);
921 internalSetDouble(source
);
924 // -------------------------------------
928 * The number will be expanded if need be to retain full precision.
929 * In practice, for formatting, multiply is by 10, 100 or 1000, so more digits
930 * will not be required for this use.
933 DigitList::mult(const DigitList
&other
, UErrorCode
&status
) {
934 if (U_FAILURE(status
)) {
938 int32_t requiredDigits
= this->digits() + other
.digits();
939 if (requiredDigits
> fContext
.digits
) {
940 reduce(); // Remove any trailing zeros
941 int32_t requiredDigits
= this->digits() + other
.digits();
942 ensureCapacity(requiredDigits
, status
);
944 uprv_decNumberMultiply(fDecNumber
, fDecNumber
, other
.fDecNumber
, &fContext
);
948 // -------------------------------------
952 * The number will _not_ be expanded for inexact results.
953 * TODO: probably should expand some, for rounding increments that
954 * could add a few digits, e.g. .25, but not expand arbitrarily.
957 DigitList::div(const DigitList
&other
, UErrorCode
&status
) {
958 if (U_FAILURE(status
)) {
961 uprv_decNumberDivide(fDecNumber
, fDecNumber
, other
.fDecNumber
, &fContext
);
965 // -------------------------------------
968 * ensureCapacity. Grow the digit storage for the number if it's less than the requested
969 * amount. Never reduce it. Available size is kept in fContext.digits.
972 DigitList::ensureCapacity(int32_t requestedCapacity
, UErrorCode
&status
) {
973 if (U_FAILURE(status
)) {
976 if (requestedCapacity
<= 0) {
977 status
= U_ILLEGAL_ARGUMENT_ERROR
;
980 if (requestedCapacity
> DEC_MAX_DIGITS
) {
981 // Don't report an error for requesting too much.
982 // Arithemetic Results will be rounded to what can be supported.
983 // At 999,999,999 max digits, exceeding the limit is not too likely!
984 requestedCapacity
= DEC_MAX_DIGITS
;
986 if (requestedCapacity
> fContext
.digits
) {
987 decNumber
*newBuffer
= fStorage
.resize(requestedCapacity
, fStorage
.getCapacity());
988 if (newBuffer
== NULL
) {
989 status
= U_MEMORY_ALLOCATION_ERROR
;
992 fContext
.digits
= requestedCapacity
;
993 fDecNumber
= newBuffer
;
997 // -------------------------------------
1000 * Round the representation to the given number of digits.
1001 * @param maximumDigits The maximum number of digits to be shown.
1002 * Upon return, count will be less than or equal to maximumDigits.
1005 DigitList::round(int32_t maximumDigits
)
1008 if (maximumDigits
>= fDecNumber
->digits
) {
1011 int32_t savedDigits
= fContext
.digits
;
1012 fContext
.digits
= maximumDigits
;
1013 uprv_decNumberPlus(fDecNumber
, fDecNumber
, &fContext
);
1014 fContext
.digits
= savedDigits
;
1015 uprv_decNumberTrim(fDecNumber
);
1022 DigitList::roundFixedPoint(int32_t maximumFractionDigits
) {
1023 reduce(); // Remove trailing zeros.
1024 if (fDecNumber
->exponent
>= -maximumFractionDigits
) {
1027 decNumber scale
; // Dummy decimal number, but with the desired number of
1028 uprv_decNumberZero(&scale
); // fraction digits.
1029 scale
.exponent
= -maximumFractionDigits
;
1032 uprv_decNumberQuantize(fDecNumber
, fDecNumber
, &scale
, &fContext
);
1037 // -------------------------------------
1040 DigitList::toIntegralValue() {
1041 uprv_decNumberToIntegralValue(fDecNumber
, fDecNumber
, &fContext
);
1045 // -------------------------------------
1047 DigitList::isZero() const
1049 return decNumberIsZero(fDecNumber
);
1052 // -------------------------------------
1054 DigitList::getUpperExponent() const {
1055 return fDecNumber
->digits
+ fDecNumber
->exponent
;
1059 DigitList::getSmallestInterval(DigitInterval
&result
) const {
1060 result
.setLeastSignificantInclusive(fDecNumber
->exponent
);
1061 result
.setMostSignificantExclusive(getUpperExponent());
1066 DigitList::getDigitByExponent(int32_t exponent
) const {
1067 int32_t idx
= exponent
- fDecNumber
->exponent
;
1068 if (idx
< 0 || idx
>= fDecNumber
->digits
) {
1071 return fDecNumber
->lsu
[idx
];
1075 DigitList::appendDigitsTo(CharString
&str
, UErrorCode
&status
) const {
1076 str
.append((const char *) fDecNumber
->lsu
, fDecNumber
->digits
, status
);
1080 DigitList::roundAtExponent(int32_t exponent
, int32_t maxSigDigits
) {
1082 if (maxSigDigits
< fDecNumber
->digits
) {
1083 int32_t minExponent
= getUpperExponent() - maxSigDigits
;
1084 if (exponent
< minExponent
) {
1085 exponent
= minExponent
;
1088 if (exponent
<= fDecNumber
->exponent
) {
1091 int32_t digits
= getUpperExponent() - exponent
;
1095 roundFixedPoint(-exponent
);
1100 DigitList::quantize(const DigitList
&quantity
, UErrorCode
&status
) {
1101 if (U_FAILURE(status
)) {
1104 div(quantity
, status
);
1106 mult(quantity
, status
);
1111 DigitList::getScientificExponent(
1112 int32_t minIntDigitCount
, int32_t exponentMultiplier
) const {
1113 // The exponent for zero is always zero.
1117 int32_t intDigitCount
= getUpperExponent();
1119 if (intDigitCount
>= minIntDigitCount
) {
1120 int32_t maxAdjustment
= intDigitCount
- minIntDigitCount
;
1121 exponent
= (maxAdjustment
/ exponentMultiplier
) * exponentMultiplier
;
1123 int32_t minAdjustment
= minIntDigitCount
- intDigitCount
;
1124 exponent
= ((minAdjustment
+ exponentMultiplier
- 1) / exponentMultiplier
) * -exponentMultiplier
;
1130 DigitList::toScientific(
1131 int32_t minIntDigitCount
, int32_t exponentMultiplier
) {
1132 int32_t exponent
= getScientificExponent(
1133 minIntDigitCount
, exponentMultiplier
);
1134 shiftDecimalRight(-exponent
);
1139 DigitList::shiftDecimalRight(int32_t n
) {
1140 fDecNumber
->exponent
+= n
;
1145 #endif // #if !UCONFIG_NO_FORMATTING