]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/digitlst.h
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / i18n / digitlst.h
CommitLineData
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
36typedef 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
47U_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 68class U_I18N_API DigitList : public UMemory { // Declare external to make compiler happy
b75a7d8f
A
69public:
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
200public:
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
228private:
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
247inline void
248DigitList::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
255U_NAMESPACE_END
256#endif // _DIGITLST
257
258//eof