| /* |
| ******************************************************************************* |
| * Copyright (C) 2015, International Business Machines |
| * Corporation and others. All Rights Reserved. |
| ******************************************************************************* |
| * precision.h |
| * |
| * created on: 2015jan06 |
| * created by: Travis Keep |
| */ |
| |
| #ifndef __PRECISION_H__ |
| #define __PRECISION_H__ |
| |
| #include "unicode/uobject.h" |
| |
| #if !UCONFIG_NO_FORMATTING |
| #include "unicode/utypes.h" |
| |
| #include "digitinterval.h" |
| #include "digitlst.h" |
| #include "significantdigitinterval.h" |
| |
| U_NAMESPACE_BEGIN |
| |
| class VisibleDigits; |
| class VisibleDigitsWithExponent; |
| |
| |
| /** |
| * A precision manager for values to be formatted as fixed point. |
| * Handles rounding of number to prepare it for formatting. |
| */ |
| class U_I18N_API FixedPrecision : public UMemory { |
| public: |
| |
| /** |
| * The smallest format interval allowed. Default is 1 integer digit and no |
| * fraction digits. |
| */ |
| DigitInterval fMin; |
| |
| /** |
| * The largest format interval allowed. Must contain fMin. |
| * Default is all digits. |
| */ |
| DigitInterval fMax; |
| |
| /** |
| * Min and max significant digits allowed. The default is no constraints. |
| */ |
| SignificantDigitInterval fSignificant; |
| |
| /** |
| * The rounding increment or zero if there is no rounding increment. |
| * Default is zero. |
| */ |
| DigitList fRoundingIncrement; |
| |
| /** |
| * If set, causes round() to set status to U_FORMAT_INEXACT_ERROR if |
| * any rounding is done. Default is FALSE. |
| */ |
| UBool fExactOnly; |
| |
| /** |
| * If set, causes round() to set status to U_ILLEGAL_ARGUMENT_ERROR if |
| * rounded number has more than maximum integer digits. Default is FALSE. |
| */ |
| UBool fFailIfOverMax; |
| |
| /** |
| * Controls the rounding mode that initVisibleDigits uses. |
| * Default is DecimalFormat::kRoundHalfEven |
| */ |
| DecimalFormat::ERoundingMode fRoundingMode; |
| |
| FixedPrecision(); |
| |
| /** |
| * Returns TRUE if this object equals rhs. |
| */ |
| UBool equals(const FixedPrecision &rhs) const { |
| return (fMin.equals(rhs.fMin) && |
| fMax.equals(rhs.fMax) && |
| fSignificant.equals(rhs.fSignificant) && |
| (fRoundingIncrement == rhs.fRoundingIncrement) && |
| fExactOnly == rhs.fExactOnly && |
| fFailIfOverMax == rhs.fFailIfOverMax && |
| fRoundingMode == rhs.fRoundingMode); |
| } |
| |
| /** |
| * Rounds value in place to prepare it for formatting. |
| * @param value The value to be rounded. It is rounded in place. |
| * @param exponent Always pass 0 for fixed decimal formatting. scientific |
| * precision passes the exponent value. Essentially, it divides value by |
| * 10^exponent, rounds and then multiplies by 10^exponent. |
| * @param status error returned here. |
| * @return reference to value. |
| */ |
| DigitList &round(DigitList &value, int32_t exponent, UErrorCode &status) const; |
| |
| /** |
| * Returns the interval to use to format the rounded value. |
| * @param roundedValue the already rounded value to format. |
| * @param interval modified in place to be the interval to use to format |
| * the rounded value. |
| * @return a reference to interval. |
| */ |
| DigitInterval &getInterval( |
| const DigitList &roundedValue, DigitInterval &interval) const; |
| |
| /** |
| * Returns TRUE if this instance allows for fast formatting of integers. |
| */ |
| UBool isFastFormattable() const; |
| |
| /** |
| * Initializes a VisibleDigits. |
| * @param value value for VisibleDigits |
| * Caller must not assume that the value of this parameter will remain |
| * unchanged. |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigits &initVisibleDigits( |
| DigitList &value, |
| VisibleDigits &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigits. |
| * @param value value for VisibleDigits |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigits &initVisibleDigits( |
| double value, |
| VisibleDigits &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigits. |
| * @param value value for VisibleDigits |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigits &initVisibleDigits( |
| int64_t value, |
| VisibleDigits &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value value for VisibleDigits |
| * Caller must not assume that the value of this parameter will remain |
| * unchanged. |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| DigitList &value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value value for VisibleDigits |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| double value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value value for VisibleDigits |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| int64_t value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| private: |
| /** |
| * Attempts to initialize 'digits' using simple mod 10 arithmetic. |
| * Returns FALSE if this is not possible such as when rounding |
| * would change the value. Otherwise returns TRUE. |
| * |
| * If the method returns FALSE, caller should create a DigitList |
| * and use it to initialize 'digits'. If this method returns TRUE, |
| * caller should accept the value stored in 'digits'. If this |
| * method returns TRUE along with a non zero error, caller must accept |
| * the error and not try again with a DigitList. |
| * |
| * Before calling this method, caller must verify that this object |
| * has no rounding increment set. |
| * |
| * The value that 'digits' is initialized to is mantissa * 10^exponent. |
| * For example mantissa = 54700 and exponent = -3 means 54.7. The |
| * properties of this object (such as min and max fraction digits), |
| * not the number of trailing zeros in the mantissa, determine whether or |
| * not the result contains any trailing 0's after the decimal point. |
| * |
| * @param mantissa the digits. May be positive or negative. May contain |
| * trailing zeros. |
| * @param exponent must always be zero or negative. An exponent > 0 |
| * yields undefined results! |
| * @param digits result stored here. |
| * @param status any error returned here. |
| */ |
| UBool |
| initVisibleDigits( |
| int64_t mantissa, |
| int32_t exponent, |
| VisibleDigits &digits, |
| UErrorCode &status) const; |
| UBool isRoundingRequired( |
| int32_t upperExponent, int32_t lowerExponent) const; |
| DigitInterval &getIntervalForZero(DigitInterval &interval) const; |
| DigitInterval &getInterval( |
| int32_t upperExponent, DigitInterval &interval) const; |
| static UBool handleNonNumeric(DigitList &value, VisibleDigits &digits); |
| |
| friend class ScientificPrecision; |
| }; |
| |
| /** |
| * A precision manager for values to be expressed as scientific notation. |
| */ |
| class U_I18N_API ScientificPrecision : public UMemory { |
| public: |
| FixedPrecision fMantissa; |
| int32_t fMinExponentDigits; |
| |
| ScientificPrecision(); |
| |
| /** |
| * rounds value in place to prepare it for formatting. |
| * @param value The value to be rounded. It is rounded in place. |
| * @param status error returned here. |
| * @return reference to value. |
| */ |
| DigitList &round(DigitList &value, UErrorCode &status) const; |
| |
| /** |
| * Converts value to a mantissa and exponent. |
| * |
| * @param value modified in place to be the mantissa. Depending on |
| * the precision settings, the resulting mantissa may not fall |
| * between 1.0 and 10.0. |
| * @return the exponent of value. |
| */ |
| int32_t toScientific(DigitList &value) const; |
| |
| /** |
| * Returns TRUE if this object equals rhs. |
| */ |
| UBool equals(const ScientificPrecision &rhs) const { |
| return fMantissa.equals(rhs.fMantissa) && fMinExponentDigits == rhs.fMinExponentDigits; |
| } |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value the value |
| * Caller must not assume that the value of this parameter will remain |
| * unchanged. |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| DigitList &value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value the value |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| double value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| /** |
| * Initializes a VisibleDigitsWithExponent. |
| * @param value the value |
| * @param digits This is the value that is initialized. |
| * @param status any error returned here. |
| * @return digits |
| */ |
| VisibleDigitsWithExponent &initVisibleDigitsWithExponent( |
| int64_t value, |
| VisibleDigitsWithExponent &digits, |
| UErrorCode &status) const; |
| |
| private: |
| int32_t getMultiplier() const; |
| |
| }; |
| |
| |
| |
| U_NAMESPACE_END |
| #endif // #if !UCONFIG_NO_FORMATTING |
| #endif // __PRECISION_H__ |