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