OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * Copyright (C) 2015, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. |
| 5 ******************************************************************************* |
| 6 * precision.h |
| 7 * |
| 8 * created on: 2015jan06 |
| 9 * created by: Travis Keep |
| 10 */ |
| 11 |
| 12 #ifndef __PRECISION_H__ |
| 13 #define __PRECISION_H__ |
| 14 |
| 15 #include "unicode/uobject.h" |
| 16 |
| 17 #if !UCONFIG_NO_FORMATTING |
| 18 #include "unicode/utypes.h" |
| 19 |
| 20 #include "digitinterval.h" |
| 21 #include "digitlst.h" |
| 22 #include "significantdigitinterval.h" |
| 23 |
| 24 U_NAMESPACE_BEGIN |
| 25 |
| 26 class VisibleDigits; |
| 27 class VisibleDigitsWithExponent; |
| 28 |
| 29 |
| 30 /** |
| 31 * A precision manager for values to be formatted as fixed point. |
| 32 * Handles rounding of number to prepare it for formatting. |
| 33 */ |
| 34 class U_I18N_API FixedPrecision : public UMemory { |
| 35 public: |
| 36 |
| 37 /** |
| 38 * The smallest format interval allowed. Default is 1 integer digit and no |
| 39 * fraction digits. |
| 40 */ |
| 41 DigitInterval fMin; |
| 42 |
| 43 /** |
| 44 * The largest format interval allowed. Must contain fMin. |
| 45 * Default is all digits. |
| 46 */ |
| 47 DigitInterval fMax; |
| 48 |
| 49 /** |
| 50 * Min and max significant digits allowed. The default is no constraints. |
| 51 */ |
| 52 SignificantDigitInterval fSignificant; |
| 53 |
| 54 /** |
| 55 * The rounding increment or zero if there is no rounding increment. |
| 56 * Default is zero. |
| 57 */ |
| 58 DigitList fRoundingIncrement; |
| 59 |
| 60 /** |
| 61 * If set, causes round() to set status to U_FORMAT_INEXACT_ERROR if |
| 62 * any rounding is done. Default is FALSE. |
| 63 */ |
| 64 UBool fExactOnly; |
| 65 |
| 66 /** |
| 67 * If set, causes round() to set status to U_ILLEGAL_ARGUMENT_ERROR if |
| 68 * rounded number has more than maximum integer digits. Default is FALSE. |
| 69 */ |
| 70 UBool fFailIfOverMax; |
| 71 |
| 72 /** |
| 73 * Controls the rounding mode that initVisibleDigits uses. |
| 74 * Default is DecimalFormat::kRoundHalfEven |
| 75 */ |
| 76 DecimalFormat::ERoundingMode fRoundingMode; |
| 77 |
| 78 FixedPrecision(); |
| 79 |
| 80 /** |
| 81 * Returns TRUE if this object equals rhs. |
| 82 */ |
| 83 UBool equals(const FixedPrecision &rhs) const { |
| 84 return (fMin.equals(rhs.fMin) && |
| 85 fMax.equals(rhs.fMax) && |
| 86 fSignificant.equals(rhs.fSignificant) && |
| 87 (fRoundingIncrement == rhs.fRoundingIncrement) && |
| 88 fExactOnly == rhs.fExactOnly && |
| 89 fFailIfOverMax == rhs.fFailIfOverMax && |
| 90 fRoundingMode == rhs.fRoundingMode); |
| 91 } |
| 92 |
| 93 /** |
| 94 * Rounds value in place to prepare it for formatting. |
| 95 * @param value The value to be rounded. It is rounded in place. |
| 96 * @param exponent Always pass 0 for fixed decimal formatting. scientific |
| 97 * precision passes the exponent value. Essentially, it divides value by |
| 98 * 10^exponent, rounds and then multiplies by 10^exponent. |
| 99 * @param status error returned here. |
| 100 * @return reference to value. |
| 101 */ |
| 102 DigitList &round(DigitList &value, int32_t exponent, UErrorCode &status) con
st; |
| 103 |
| 104 /** |
| 105 * Returns the interval to use to format the rounded value. |
| 106 * @param roundedValue the already rounded value to format. |
| 107 * @param interval modified in place to be the interval to use to format |
| 108 * the rounded value. |
| 109 * @return a reference to interval. |
| 110 */ |
| 111 DigitInterval &getInterval( |
| 112 const DigitList &roundedValue, DigitInterval &interval) const; |
| 113 |
| 114 /** |
| 115 * Returns TRUE if this instance allows for fast formatting of integers. |
| 116 */ |
| 117 UBool isFastFormattable() const; |
| 118 |
| 119 /** |
| 120 * Initializes a VisibleDigits. |
| 121 * @param value value for VisibleDigits |
| 122 * Caller must not assume that the value of this parameter will remain |
| 123 * unchanged. |
| 124 * @param digits This is the value that is initialized. |
| 125 * @param status any error returned here. |
| 126 * @return digits |
| 127 */ |
| 128 VisibleDigits &initVisibleDigits( |
| 129 DigitList &value, |
| 130 VisibleDigits &digits, |
| 131 UErrorCode &status) const; |
| 132 |
| 133 /** |
| 134 * Initializes a VisibleDigits. |
| 135 * @param value value for VisibleDigits |
| 136 * @param digits This is the value that is initialized. |
| 137 * @param status any error returned here. |
| 138 * @return digits |
| 139 */ |
| 140 VisibleDigits &initVisibleDigits( |
| 141 double value, |
| 142 VisibleDigits &digits, |
| 143 UErrorCode &status) const; |
| 144 |
| 145 /** |
| 146 * Initializes a VisibleDigits. |
| 147 * @param value value for VisibleDigits |
| 148 * @param digits This is the value that is initialized. |
| 149 * @param status any error returned here. |
| 150 * @return digits |
| 151 */ |
| 152 VisibleDigits &initVisibleDigits( |
| 153 int64_t value, |
| 154 VisibleDigits &digits, |
| 155 UErrorCode &status) const; |
| 156 |
| 157 /** |
| 158 * Initializes a VisibleDigitsWithExponent. |
| 159 * @param value value for VisibleDigits |
| 160 * Caller must not assume that the value of this parameter will remain |
| 161 * unchanged. |
| 162 * @param digits This is the value that is initialized. |
| 163 * @param status any error returned here. |
| 164 * @return digits |
| 165 */ |
| 166 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 167 DigitList &value, |
| 168 VisibleDigitsWithExponent &digits, |
| 169 UErrorCode &status) const; |
| 170 |
| 171 /** |
| 172 * Initializes a VisibleDigitsWithExponent. |
| 173 * @param value value for VisibleDigits |
| 174 * @param digits This is the value that is initialized. |
| 175 * @param status any error returned here. |
| 176 * @return digits |
| 177 */ |
| 178 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 179 double value, |
| 180 VisibleDigitsWithExponent &digits, |
| 181 UErrorCode &status) const; |
| 182 |
| 183 /** |
| 184 * Initializes a VisibleDigitsWithExponent. |
| 185 * @param value value for VisibleDigits |
| 186 * @param digits This is the value that is initialized. |
| 187 * @param status any error returned here. |
| 188 * @return digits |
| 189 */ |
| 190 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 191 int64_t value, |
| 192 VisibleDigitsWithExponent &digits, |
| 193 UErrorCode &status) const; |
| 194 |
| 195 private: |
| 196 /** |
| 197 * Attempts to initialize 'digits' using simple mod 10 arithmetic. |
| 198 * Returns FALSE if this is not possible such as when rounding |
| 199 * would change the value. Otherwise returns TRUE. |
| 200 * |
| 201 * If the method returns FALSE, caller should create a DigitList |
| 202 * and use it to initialize 'digits'. If this method returns TRUE, |
| 203 * caller should accept the value stored in 'digits'. If this |
| 204 * method returns TRUE along with a non zero error, caller must accept |
| 205 * the error and not try again with a DigitList. |
| 206 * |
| 207 * Before calling this method, caller must verify that this object |
| 208 * has no rounding increment set. |
| 209 * |
| 210 * The value that 'digits' is initialized to is mantissa * 10^exponent. |
| 211 * For example mantissa = 54700 and exponent = -3 means 54.7. The |
| 212 * properties of this object (such as min and max fraction digits), |
| 213 * not the number of trailing zeros in the mantissa, determine whether or |
| 214 * not the result contains any trailing 0's after the decimal point. |
| 215 * |
| 216 * @param mantissa the digits. May be positive or negative. May contain |
| 217 * trailing zeros. |
| 218 * @param exponent must always be zero or negative. An exponent > 0 |
| 219 * yields undefined results! |
| 220 * @param digits result stored here. |
| 221 * @param status any error returned here. |
| 222 */ |
| 223 UBool |
| 224 initVisibleDigits( |
| 225 int64_t mantissa, |
| 226 int32_t exponent, |
| 227 VisibleDigits &digits, |
| 228 UErrorCode &status) const; |
| 229 UBool isRoundingRequired( |
| 230 int32_t upperExponent, int32_t lowerExponent) const; |
| 231 DigitInterval &getIntervalForZero(DigitInterval &interval) const; |
| 232 DigitInterval &getInterval( |
| 233 int32_t upperExponent, DigitInterval &interval) const; |
| 234 static UBool handleNonNumeric(DigitList &value, VisibleDigits &digits); |
| 235 |
| 236 friend class ScientificPrecision; |
| 237 }; |
| 238 |
| 239 /** |
| 240 * A precision manager for values to be expressed as scientific notation. |
| 241 */ |
| 242 class U_I18N_API ScientificPrecision : public UMemory { |
| 243 public: |
| 244 FixedPrecision fMantissa; |
| 245 int32_t fMinExponentDigits; |
| 246 |
| 247 ScientificPrecision(); |
| 248 |
| 249 /** |
| 250 * rounds value in place to prepare it for formatting. |
| 251 * @param value The value to be rounded. It is rounded in place. |
| 252 * @param status error returned here. |
| 253 * @return reference to value. |
| 254 */ |
| 255 DigitList &round(DigitList &value, UErrorCode &status) const; |
| 256 |
| 257 /** |
| 258 * Converts value to a mantissa and exponent. |
| 259 * |
| 260 * @param value modified in place to be the mantissa. Depending on |
| 261 * the precision settings, the resulting mantissa may not fall |
| 262 * between 1.0 and 10.0. |
| 263 * @return the exponent of value. |
| 264 */ |
| 265 int32_t toScientific(DigitList &value) const; |
| 266 |
| 267 /** |
| 268 * Returns TRUE if this object equals rhs. |
| 269 */ |
| 270 UBool equals(const ScientificPrecision &rhs) const { |
| 271 return fMantissa.equals(rhs.fMantissa) && fMinExponentDigits == rhs.fMin
ExponentDigits; |
| 272 } |
| 273 |
| 274 /** |
| 275 * Initializes a VisibleDigitsWithExponent. |
| 276 * @param value the value |
| 277 * Caller must not assume that the value of this parameter will remain |
| 278 * unchanged. |
| 279 * @param digits This is the value that is initialized. |
| 280 * @param status any error returned here. |
| 281 * @return digits |
| 282 */ |
| 283 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 284 DigitList &value, |
| 285 VisibleDigitsWithExponent &digits, |
| 286 UErrorCode &status) const; |
| 287 |
| 288 /** |
| 289 * Initializes a VisibleDigitsWithExponent. |
| 290 * @param value the value |
| 291 * @param digits This is the value that is initialized. |
| 292 * @param status any error returned here. |
| 293 * @return digits |
| 294 */ |
| 295 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 296 double value, |
| 297 VisibleDigitsWithExponent &digits, |
| 298 UErrorCode &status) const; |
| 299 |
| 300 /** |
| 301 * Initializes a VisibleDigitsWithExponent. |
| 302 * @param value the value |
| 303 * @param digits This is the value that is initialized. |
| 304 * @param status any error returned here. |
| 305 * @return digits |
| 306 */ |
| 307 VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| 308 int64_t value, |
| 309 VisibleDigitsWithExponent &digits, |
| 310 UErrorCode &status) const; |
| 311 |
| 312 private: |
| 313 int32_t getMultiplier() const; |
| 314 |
| 315 }; |
| 316 |
| 317 |
| 318 |
| 319 U_NAMESPACE_END |
| 320 #endif // #if !UCONFIG_NO_FORMATTING |
| 321 #endif // __PRECISION_H__ |
OLD | NEW |