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 /* copy constructor 75 * @param DigitList The object to be copied. 76 * @return the newly created object. 77 */ 78 DigitList(const DigitList&); // copy constructor 79 80 /* assignment operator 81 * @param DigitList The object to be copied. 82 * @return the newly created object. 83 */ 84 DigitList& operator=(const DigitList&); // assignment operator 85 86 /** 87 * Return true if another object is semantically equal to this one. 88 * @param other The DigitList to be compared for equality 89 * @return true if another object is semantically equal to this one. 90 * return false otherwise. 91 */ 92 UBool operator==(const DigitList& other) const; 93 94 private: 95 /** 96 * Commented out due to lack of usage and low code coverage. 97 */ 98 inline UBool operator!=(const DigitList& other) const; 99 public: 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 */ 122 double getDouble(void) /*const*/; 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 */ 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*/; 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 */ 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*/; 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 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 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; 226 DecimalFormat::ERoundingMode fRoundingMode; 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 240 UBool shouldRoundUp(int32_t maximumDigits) const; 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 #if 0 256 inline UBool 257 DigitList::operator!=(const DigitList& other) const { 258 return !operator==(other); 259 } 260 #endif 261 262 U_NAMESPACE_END 263 264 #endif // #if !UCONFIG_NO_FORMATTING 265 #endif // _DIGITLST 266 267 //eof 268