• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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