1 /*
2 ******************************************************************************
3 *
4 * Copyright (C) 1997-2007, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 ******************************************************************************
8 *
9 * File DIGITLST.H
10 *
11 * Modification History:
12 *
13 * Date Name Description
14 * 02/25/97 aliu Converted from java.
15 * 03/21/97 clhuang Updated per C++ implementation.
16 * 04/15/97 aliu Changed MAX_COUNT to DBL_DIG. Changed Digit to char.
17 * 09/09/97 aliu Adapted for exponential notation support.
18 * 08/02/98 stephen Added nearest/even rounding
19 * 06/29/99 stephen Made LONG_DIGITS a macro to satisfy SUN compiler
20 * 07/09/99 stephen Removed kMaxCount (unused, for HP compiler)
21 ******************************************************************************
22 */
23
24 #ifndef DIGITLST_H
25 #define DIGITLST_H
26
27 #include "unicode/uobject.h"
28
29 #if !UCONFIG_NO_FORMATTING
30 #include "unicode/decimfmt.h"
31 #include <float.h>
32
33 // Decimal digits in a 64-bit int
34 //#define LONG_DIGITS 19
35 #define INT64_DIGITS 19
36
37 typedef enum EDigitListValues {
38 MAX_DBL_DIGITS = DBL_DIG,
39 MAX_I64_DIGITS = INT64_DIGITS,
40 MAX_DIGITS = MAX_I64_DIGITS,
41 MAX_EXPONENT = DBL_DIG,
42 DIGIT_PADDING = 3,
43
44 // "+." + fDigits + "e" + fDecimalAt
45 MAX_DEC_DIGITS = MAX_DIGITS + DIGIT_PADDING + MAX_EXPONENT
46 } EDigitListValues;
47
48 U_NAMESPACE_BEGIN
49
50 /**
51 * Digit List utility class. Private to DecimalFormat. Handles the transcoding
52 * between numeric values and strings of characters. Only handles
53 * non-negative numbers. The division of labor between DigitList and
54 * DecimalFormat is that DigitList handles the radix 10 representation
55 * issues; DecimalFormat handles the locale-specific issues such as
56 * positive/negative, grouping, decimal point, currency, and so on.
57 * <P>
58 * A DigitList is really a representation of a floating point value.
59 * It may be an integer value; we assume that a double has sufficient
60 * precision to represent all digits of a long.
61 * <P>
62 * The DigitList representation consists of a string of characters,
63 * which are the digits radix 10, from '0' to '9'. It also has a radix
64 * 10 exponent associated with it. The value represented by a DigitList
65 * object can be computed by mulitplying the fraction f, where 0 <= f < 1,
66 * derived by placing all the digits of the list to the right of the
67 * decimal point, by 10^exponent.
68 */
69 class DigitList : public UMemory { // Declare external to make compiler happy
70 public:
71 DigitList();
72 ~DigitList();
73
74 // BEGIN android-added
75 /* capacity constructor
76 * @param capacity The size of the digit list buffer
77 * @return the newly created object.
78 */
79 DigitList(int capacity);
80 // END android-added
81
82 /* copy constructor
83 * @param DigitList The object to be copied.
84 * @return the newly created object.
85 */
86 DigitList(const DigitList&); // copy constructor
87
88 /* assignment operator
89 * @param DigitList The object to be copied.
90 * @return the newly created object.
91 */
92 DigitList& operator=(const DigitList&); // assignment operator
93
94 /**
95 * Return true if another object is semantically equal to this one.
96 * @param other The DigitList to be compared for equality
97 * @return true if another object is semantically equal to this one.
98 * return false otherwise.
99 */
100 UBool operator==(const DigitList& other) const;
101
102 private:
103 /**
104 * Commented out due to lack of usage and low code coverage.
105 */
106 inline UBool operator!=(const DigitList& other) const;
107 public:
108
109 /**
110 * Clears out the digits.
111 * Use before appending them.
112 * Typically, you set a series of digits with append, then at the point
113 * you hit the decimal point, you set myDigitList.fDecimalAt = myDigitList.fCount;
114 * then go on appending digits.
115 */
116 void clear(void);
117
118 /**
119 * Appends digits to the list. Ignores all digits beyond the first DBL_DIG,
120 * since they are not significant for either longs or doubles.
121 * @param digit The digit to be appended.
122 */
123 inline void append(char digit);
124
125 /**
126 * Utility routine to get the value of the digit list
127 * Returns 0.0 if zero length.
128 * @return the value of the digit list.
129 */
130 double getDouble(void) /*const*/;
131
132 /**
133 * Utility routine to get the value of the digit list
134 * Make sure that fitsIntoLong() is called before calling this function.
135 * Returns 0 if zero length.
136 * @return the value of the digit list, return 0 if it is zero length
137 */
138 int32_t getLong(void) /*const*/;
139
140 /**
141 * Utility routine to get the value of the digit list
142 * Make sure that fitsIntoInt64() is called before calling this function.
143 * Returns 0 if zero length.
144 * @return the value of the digit list, return 0 if it is zero length
145 */
146 int64_t getInt64(void) /*const*/;
147
148 /**
149 * Return true if the number represented by this object can fit into
150 * a long.
151 * @param ignoreNegativeZero True if negative zero is ignored.
152 * @return true if the number represented by this object can fit into
153 * a long, return false otherwise.
154 */
155 UBool fitsIntoLong(UBool ignoreNegativeZero) /*const*/;
156
157 /**
158 * Return true if the number represented by this object can fit into
159 * an int64_t.
160 * @param ignoreNegativeZero True if negative zero is ignored.
161 * @return true if the number represented by this object can fit into
162 * a long, return false otherwise.
163 */
164 UBool fitsIntoInt64(UBool ignoreNegativeZero) /*const*/;
165
166 /**
167 * Utility routine to set the value of the digit list from a double
168 * Input must be non-negative, and must not be Inf, -Inf, or NaN.
169 * The maximum fraction digits helps us round properly.
170 * @param source The value to be set
171 * @param maximunDigits The maximum number of digits to be shown
172 * @param fixedPoint True if the point is fixed
173 */
174 void set(double source, int32_t maximumDigits, UBool fixedPoint = TRUE);
175
176 /**
177 * Utility routine to set the value of the digit list from a long.
178 * If a non-zero maximumDigits is specified, no more than that number of
179 * significant digits will be produced.
180 * @param source The value to be set
181 * @param maximunDigits The maximum number of digits to be shown
182 */
183 void set(int32_t source, int32_t maximumDigits = 0);
184
185 /**
186 * Utility routine to set the value of the digit list from an int64.
187 * If a non-zero maximumDigits is specified, no more than that number of
188 * significant digits will be produced.
189 * @param source The value to be set
190 * @param maximunDigits The maximum number of digits to be shown
191 */
192 void set(int64_t source, int32_t maximumDigits = 0);
193
194 /**
195 * Return true if this is a representation of zero.
196 * @return true if this is a representation of zero.
197 */
198 UBool isZero(void) const;
199
200 /**
201 * Return true if this is a representation of LONG_MIN. You must use
202 * this method to determine if this is so; you cannot check directly,
203 * because a special format is used to handle this.
204 */
205 // This code is unused.
206 //UBool isLONG_MIN(void) const;
207
208 public:
209 /**
210 * These data members are intentionally public and can be set directly.
211 *<P>
212 * The value represented is given by placing the decimal point before
213 * fDigits[fDecimalAt]. If fDecimalAt is < 0, then leading zeros between
214 * the decimal point and the first nonzero digit are implied. If fDecimalAt
215 * is > fCount, then trailing zeros between the fDigits[fCount-1] and the
216 * decimal point are implied.
217 * <P>
218 * Equivalently, the represented value is given by f * 10^fDecimalAt. Here
219 * f is a value 0.1 <= f < 1 arrived at by placing the digits in fDigits to
220 * the right of the decimal.
221 * <P>
222 * DigitList is normalized, so if it is non-zero, fDigits[0] is non-zero. We
223 * don't allow denormalized numbers because our exponent is effectively of
224 * unlimited magnitude. The fCount value contains the number of significant
225 * digits present in fDigits[].
226 * <P>
227 * Zero is represented by any DigitList with fCount == 0 or with each fDigits[i]
228 * for all i <= fCount == '0'.
229 */
230 int32_t fDecimalAt;
231 int32_t fCount;
232 UBool fIsPositive;
233 char *fDigits;
234 DecimalFormat::ERoundingMode fRoundingMode;
235
236 private:
237
238 // BEGIN android-changed
239 /* One character before fDigits for the decimal*/
240 char *fDecimalDigits;
241
242 char fDecimalDigitsBuffer[MAX_DEC_DIGITS + 1];
243
244 int fBufferSize;
245 // END android-changed
246
247 /**
248 * Round the representation to the given number of digits.
249 * @param maximumDigits The maximum number of digits to be shown.
250 * Upon return, count will be less than or equal to maximumDigits.
251 */
252 void round(int32_t maximumDigits);
253
254 UBool shouldRoundUp(int32_t maximumDigits) const;
255 };
256
257 // -------------------------------------
258 // Appends the digit to the digit list if it's not out of scope.
259 // Ignores the digit, otherwise.
260
261 inline void
append(char digit)262 DigitList::append(char digit)
263 {
264 // BEGIN android-changed
265 // Ignore digits which exceed the precision we can represent
266 if (fCount < fBufferSize)
267 fDigits[fCount++] = digit;
268 // END android-changed
269 }
270
271 #if 0
272 inline UBool
273 DigitList::operator!=(const DigitList& other) const {
274 return !operator==(other);
275 }
276 #endif
277
278 U_NAMESPACE_END
279
280 #endif // #if !UCONFIG_NO_FORMATTING
281 #endif // _DIGITLST
282
283 //eof
284