1 // Copyright (C) 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__