Line data Source code
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 0 : 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 0 : UBool equals(const FixedPrecision &rhs) const {
86 0 : return (fMin.equals(rhs.fMin) &&
87 0 : fMax.equals(rhs.fMax) &&
88 0 : fSignificant.equals(rhs.fSignificant) &&
89 0 : (fRoundingIncrement == rhs.fRoundingIncrement) &&
90 0 : fExactOnly == rhs.fExactOnly &&
91 0 : fFailIfOverMax == rhs.fFailIfOverMax &&
92 0 : 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 0 : 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 0 : UBool equals(const ScientificPrecision &rhs) const {
273 0 : 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__
|