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