]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/precision.h
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / precision.h
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) const;
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.fMinExponentDigits;
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__