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