]>
git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/visibledigits.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 * Copyright (C) 2016, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 * file name: visibledigits.cpp
12 #include "unicode/utypes.h"
14 #if !UCONFIG_NO_FORMATTING
17 #include "decNumber.h"
20 #include "visibledigits.h"
22 static const int32_t kNegative
= 1;
23 static const int32_t kInfinite
= 2;
24 static const int32_t kNaN
= 4;
28 void VisibleDigits::setNegative() {
32 void VisibleDigits::setNaN() {
36 void VisibleDigits::setInfinite() {
40 void VisibleDigits::clear() {
46 fAbsIntValueSet
= FALSE
;
47 fAbsDoubleValue
= 0.0;
48 fAbsDoubleValueSet
= FALSE
;
51 UBool
VisibleDigits::isNegative() const {
52 return (fFlags
& kNegative
);
55 UBool
VisibleDigits::isNaN() const {
56 return (fFlags
& kNaN
);
59 UBool
VisibleDigits::isInfinite() const {
60 return (fFlags
& kInfinite
);
63 int32_t VisibleDigits::getDigitByExponent(int32_t digitPos
) const {
64 if (digitPos
< fExponent
|| digitPos
>= fExponent
+ fDigits
.length()) {
67 const char *ptr
= fDigits
.data();
68 return ptr
[digitPos
- fExponent
];
71 UBool
VisibleDigits::isOverMaxDigits() const {
72 return (fExponent
+ fDigits
.length() > fInterval
.getMostSignificantExclusive());
75 UBool
VisibleDigits::isNaNOrInfinity() const {
76 return (fFlags
& (kInfinite
| kNaN
)) != 0;
79 double VisibleDigits::computeAbsDoubleValue() const {
80 // Take care of NaN and infinity
85 return uprv_getInfinity();
88 // stack allocate a decNumber to hold MAX_DBL_DIGITS+3 significant digits
91 char digits
[MAX_DBL_DIGITS
+3];
92 } decNumberWithStorage
;
93 decNumber
*numberPtr
= &decNumberWithStorage
.decNum
;
95 int32_t mostSig
= fInterval
.getMostSignificantExclusive();
96 int32_t mostSigNonZero
= fExponent
+ fDigits
.length();
97 int32_t end
= mostSig
> mostSigNonZero
? mostSigNonZero
: mostSig
;
98 int32_t leastSig
= fInterval
.getLeastSignificantInclusive();
99 int32_t start
= leastSig
> fExponent
? leastSig
: fExponent
;
103 if (start
< end
- (MAX_DBL_DIGITS
+3)) {
104 start
= end
- (MAX_DBL_DIGITS
+3);
106 uint8_t *pos
= numberPtr
->lsu
;
107 const char *src
= &(fDigits
.data()[start
- fExponent
]);
108 for (int32_t i
= start
; i
< end
; ++i
) {
109 *pos
++ = (uint8_t) (*src
++);
111 numberPtr
->exponent
= start
;
113 numberPtr
->digits
= end
- start
;
114 char str
[MAX_DBL_DIGITS
+18];
115 uprv_decNumberToString(numberPtr
, str
);
116 U_ASSERT(uprv_strlen(str
) < MAX_DBL_DIGITS
+18);
118 return DigitList::decimalStrToDouble(str
, &unused
);
121 void VisibleDigits::getFixedDecimal(
122 double &source
, int64_t &intValue
, int64_t &f
, int64_t &t
, int32_t &v
, UBool
&hasIntValue
) const {
129 if (isNaNOrInfinity()) {
134 if (fAbsDoubleValueSet
) {
135 source
= fAbsDoubleValue
;
137 source
= computeAbsDoubleValue();
140 // visible decimal digits
141 v
= fInterval
.getFracDigitCount();
145 // If we initialized from an int64 just use that instead of
147 if (fAbsIntValueSet
) {
148 intValue
= fAbsIntValue
;
150 int32_t startPos
= fInterval
.getMostSignificantExclusive();
154 // process the integer digits
155 for (int32_t i
= startPos
- 1; i
>= 0; --i
) {
156 intValue
= intValue
* 10LL + getDigitByExponent(i
);
158 if (intValue
== 0LL && startPos
> 0) {
159 intValue
= 100000000000000000LL;
163 // f (decimal digits)
164 // skip over any leading 0's in fraction digits.
166 for (; idx
>= -v
&& getDigitByExponent(idx
) == 0; --idx
)
169 // Only process up to first 18 non zero fraction digits for decimalDigits
170 // since that is all we can fit into an int64.
171 for (int32_t i
= idx
; i
>= -v
&& i
> idx
- 18; --i
) {
172 f
= f
* 10LL + getDigitByExponent(i
);
175 // If we have no decimal digits, we don't have an integer value
176 hasIntValue
= (f
== 0LL);
178 // t (decimal digits without trailing zeros)
180 while (t
> 0 && t
% 10LL == 0) {
186 #endif /* #if !UCONFIG_NO_FORMATTING */