1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
10 * created on: 2015jan06
11 * created by: Travis Keep
14 #ifndef __PRECISION_H__
15 #define __PRECISION_H__
17 #include "unicode/uobject.h"
19 #if !UCONFIG_NO_FORMATTING
20 #include "unicode/utypes.h"
22 #include "digitinterval.h"
24 #include "significantdigitinterval.h"
29 class VisibleDigitsWithExponent
;
33 * A precision manager for values to be formatted as fixed point.
34 * Handles rounding of number to prepare it for formatting.
36 class U_I18N_API FixedPrecision
: public UMemory
{
40 * The smallest format interval allowed. Default is 1 integer digit and no
46 * The largest format interval allowed. Must contain fMin.
47 * Default is all digits.
52 * Min and max significant digits allowed. The default is no constraints.
54 SignificantDigitInterval fSignificant
;
57 * The rounding increment or zero if there is no rounding increment.
60 DigitList fRoundingIncrement
;
63 * If set, causes round() to set status to U_FORMAT_INEXACT_ERROR if
64 * any rounding is done. Default is FALSE.
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.
75 * Controls the rounding mode that initVisibleDigits uses.
76 * Default is DecimalFormat::kRoundHalfEven
78 DecimalFormat::ERoundingMode fRoundingMode
;
83 * Returns TRUE if this object equals rhs.
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
);
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.
104 DigitList
&round(DigitList
&value
, int32_t exponent
, UErrorCode
&status
) const;
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
111 * @return a reference to interval.
113 DigitInterval
&getInterval(
114 const DigitList
&roundedValue
, DigitInterval
&interval
) const;
117 * Returns TRUE if this instance allows for fast formatting of integers.
119 UBool
isFastFormattable() const;
122 * Initializes a VisibleDigits.
123 * @param value value for VisibleDigits
124 * Caller must not assume that the value of this parameter will remain
126 * @param digits This is the value that is initialized.
127 * @param status any error returned here.
130 VisibleDigits
&initVisibleDigits(
132 VisibleDigits
&digits
,
133 UErrorCode
&status
) const;
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.
142 VisibleDigits
&initVisibleDigits(
144 VisibleDigits
&digits
,
145 UErrorCode
&status
) const;
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.
154 VisibleDigits
&initVisibleDigits(
156 VisibleDigits
&digits
,
157 UErrorCode
&status
) const;
160 * Initializes a VisibleDigitsWithExponent.
161 * @param value value for VisibleDigits
162 * Caller must not assume that the value of this parameter will remain
164 * @param digits This is the value that is initialized.
165 * @param status any error returned here.
168 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
170 VisibleDigitsWithExponent
&digits
,
171 UErrorCode
&status
) const;
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.
180 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
182 VisibleDigitsWithExponent
&digits
,
183 UErrorCode
&status
) const;
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.
192 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
194 VisibleDigitsWithExponent
&digits
,
195 UErrorCode
&status
) const;
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.
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.
209 * Before calling this method, caller must verify that this object
210 * has no rounding increment set.
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.
218 * @param mantissa the digits. May be positive or negative. May contain
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.
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
);
238 friend class ScientificPrecision
;
242 * A precision manager for values to be expressed as scientific notation.
244 class U_I18N_API ScientificPrecision
: public UMemory
{
246 FixedPrecision fMantissa
;
247 int32_t fMinExponentDigits
;
249 ScientificPrecision();
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.
257 DigitList
&round(DigitList
&value
, UErrorCode
&status
) const;
260 * Converts value to a mantissa and exponent.
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.
267 int32_t toScientific(DigitList
&value
) const;
270 * Returns TRUE if this object equals rhs.
272 UBool
equals(const ScientificPrecision
&rhs
) const {
273 return fMantissa
.equals(rhs
.fMantissa
) && fMinExponentDigits
== rhs
.fMinExponentDigits
;
277 * Initializes a VisibleDigitsWithExponent.
278 * @param value the value
279 * Caller must not assume that the value of this parameter will remain
281 * @param digits This is the value that is initialized.
282 * @param status any error returned here.
285 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
287 VisibleDigitsWithExponent
&digits
,
288 UErrorCode
&status
) const;
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.
297 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
299 VisibleDigitsWithExponent
&digits
,
300 UErrorCode
&status
) const;
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.
309 VisibleDigitsWithExponent
&initVisibleDigitsWithExponent(
311 VisibleDigitsWithExponent
&digits
,
312 UErrorCode
&status
) const;
315 int32_t getMultiplier() const;
322 #endif // #if !UCONFIG_NO_FORMATTING
323 #endif // __PRECISION_H__