12e5b6d6dSopenharmony_ci// © 2017 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci
42e5b6d6dSopenharmony_ci#include "unicode/utypes.h"
52e5b6d6dSopenharmony_ci
62e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
72e5b6d6dSopenharmony_ci#ifndef __NUMBER_DECIMALQUANTITY_H__
82e5b6d6dSopenharmony_ci#define __NUMBER_DECIMALQUANTITY_H__
92e5b6d6dSopenharmony_ci
102e5b6d6dSopenharmony_ci#include <cstdint>
112e5b6d6dSopenharmony_ci#include "unicode/umachine.h"
122e5b6d6dSopenharmony_ci#include "standardplural.h"
132e5b6d6dSopenharmony_ci#include "plurrule_impl.h"
142e5b6d6dSopenharmony_ci#include "number_types.h"
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_ciU_NAMESPACE_BEGIN namespace number {
172e5b6d6dSopenharmony_cinamespace impl {
182e5b6d6dSopenharmony_ci
192e5b6d6dSopenharmony_ci// Forward-declare (maybe don't want number_utils.h included here):
202e5b6d6dSopenharmony_ciclass DecNum;
212e5b6d6dSopenharmony_ci
222e5b6d6dSopenharmony_ci/**
232e5b6d6dSopenharmony_ci * A class for representing a number to be processed by the decimal formatting pipeline. Includes
242e5b6d6dSopenharmony_ci * methods for rounding, plural rules, and decimal digit extraction.
252e5b6d6dSopenharmony_ci *
262e5b6d6dSopenharmony_ci * <p>By design, this is NOT IMMUTABLE and NOT THREAD SAFE. It is intended to be an intermediate
272e5b6d6dSopenharmony_ci * object holding state during a pass through the decimal formatting pipeline.
282e5b6d6dSopenharmony_ci *
292e5b6d6dSopenharmony_ci * <p>Represents numbers and digit display properties using Binary Coded Decimal (BCD).
302e5b6d6dSopenharmony_ci *
312e5b6d6dSopenharmony_ci * <p>Java has multiple implementations for testing, but C++ has only one implementation.
322e5b6d6dSopenharmony_ci */
332e5b6d6dSopenharmony_ciclass U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
342e5b6d6dSopenharmony_ci  public:
352e5b6d6dSopenharmony_ci    /** Copy constructor. */
362e5b6d6dSopenharmony_ci    DecimalQuantity(const DecimalQuantity &other);
372e5b6d6dSopenharmony_ci
382e5b6d6dSopenharmony_ci    /** Move constructor. */
392e5b6d6dSopenharmony_ci    DecimalQuantity(DecimalQuantity &&src) U_NOEXCEPT;
402e5b6d6dSopenharmony_ci
412e5b6d6dSopenharmony_ci    DecimalQuantity();
422e5b6d6dSopenharmony_ci
432e5b6d6dSopenharmony_ci    ~DecimalQuantity() override;
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci    /**
462e5b6d6dSopenharmony_ci     * Sets this instance to be equal to another instance.
472e5b6d6dSopenharmony_ci     *
482e5b6d6dSopenharmony_ci     * @param other The instance to copy from.
492e5b6d6dSopenharmony_ci     */
502e5b6d6dSopenharmony_ci    DecimalQuantity &operator=(const DecimalQuantity &other);
512e5b6d6dSopenharmony_ci
522e5b6d6dSopenharmony_ci    /** Move assignment */
532e5b6d6dSopenharmony_ci    DecimalQuantity &operator=(DecimalQuantity&& src) U_NOEXCEPT;
542e5b6d6dSopenharmony_ci
552e5b6d6dSopenharmony_ci    /**
562e5b6d6dSopenharmony_ci     * Sets the minimum integer digits that this {@link DecimalQuantity} should generate.
572e5b6d6dSopenharmony_ci     * This method does not perform rounding.
582e5b6d6dSopenharmony_ci     *
592e5b6d6dSopenharmony_ci     * @param minInt The minimum number of integer digits.
602e5b6d6dSopenharmony_ci     */
612e5b6d6dSopenharmony_ci    void setMinInteger(int32_t minInt);
622e5b6d6dSopenharmony_ci
632e5b6d6dSopenharmony_ci    /**
642e5b6d6dSopenharmony_ci     * Sets the minimum fraction digits that this {@link DecimalQuantity} should generate.
652e5b6d6dSopenharmony_ci     * This method does not perform rounding.
662e5b6d6dSopenharmony_ci     *
672e5b6d6dSopenharmony_ci     * @param minFrac The minimum number of fraction digits.
682e5b6d6dSopenharmony_ci     */
692e5b6d6dSopenharmony_ci    void setMinFraction(int32_t minFrac);
702e5b6d6dSopenharmony_ci
712e5b6d6dSopenharmony_ci    /**
722e5b6d6dSopenharmony_ci     * Truncates digits from the upper magnitude of the number in order to satisfy the
732e5b6d6dSopenharmony_ci     * specified maximum number of integer digits.
742e5b6d6dSopenharmony_ci     *
752e5b6d6dSopenharmony_ci     * @param maxInt The maximum number of integer digits.
762e5b6d6dSopenharmony_ci     */
772e5b6d6dSopenharmony_ci    void applyMaxInteger(int32_t maxInt);
782e5b6d6dSopenharmony_ci
792e5b6d6dSopenharmony_ci    /**
802e5b6d6dSopenharmony_ci     * Rounds the number to a specified interval, such as 0.05.
812e5b6d6dSopenharmony_ci     *
822e5b6d6dSopenharmony_ci     * <p>If rounding to a power of ten, use the more efficient {@link #roundToMagnitude} instead.
832e5b6d6dSopenharmony_ci     *
842e5b6d6dSopenharmony_ci     * @param increment The increment to which to round.
852e5b6d6dSopenharmony_ci     * @param magnitude The power of 10 to which to round.
862e5b6d6dSopenharmony_ci     * @param roundingMode The {@link RoundingMode} to use if rounding is necessary.
872e5b6d6dSopenharmony_ci     */
882e5b6d6dSopenharmony_ci    void roundToIncrement(
892e5b6d6dSopenharmony_ci        uint64_t increment,
902e5b6d6dSopenharmony_ci        digits_t magnitude,
912e5b6d6dSopenharmony_ci        RoundingMode roundingMode,
922e5b6d6dSopenharmony_ci        UErrorCode& status);
932e5b6d6dSopenharmony_ci
942e5b6d6dSopenharmony_ci    /** Removes all fraction digits. */
952e5b6d6dSopenharmony_ci    void truncate();
962e5b6d6dSopenharmony_ci
972e5b6d6dSopenharmony_ci    /**
982e5b6d6dSopenharmony_ci     * Rounds the number to the nearest multiple of 5 at the specified magnitude.
992e5b6d6dSopenharmony_ci     * For example, when magnitude == -2, this performs rounding to the nearest 0.05.
1002e5b6d6dSopenharmony_ci     *
1012e5b6d6dSopenharmony_ci     * @param magnitude The magnitude at which the digit should become either 0 or 5.
1022e5b6d6dSopenharmony_ci     * @param roundingMode Rounding strategy.
1032e5b6d6dSopenharmony_ci     */
1042e5b6d6dSopenharmony_ci    void roundToNickel(int32_t magnitude, RoundingMode roundingMode, UErrorCode& status);
1052e5b6d6dSopenharmony_ci
1062e5b6d6dSopenharmony_ci    /**
1072e5b6d6dSopenharmony_ci     * Rounds the number to a specified magnitude (power of ten).
1082e5b6d6dSopenharmony_ci     *
1092e5b6d6dSopenharmony_ci     * @param roundingMagnitude The power of ten to which to round. For example, a value of -2 will
1102e5b6d6dSopenharmony_ci     *     round to 2 decimal places.
1112e5b6d6dSopenharmony_ci     * @param roundingMode The {@link RoundingMode} to use if rounding is necessary.
1122e5b6d6dSopenharmony_ci     */
1132e5b6d6dSopenharmony_ci    void roundToMagnitude(int32_t magnitude, RoundingMode roundingMode, UErrorCode& status);
1142e5b6d6dSopenharmony_ci
1152e5b6d6dSopenharmony_ci    /**
1162e5b6d6dSopenharmony_ci     * Rounds the number to an infinite number of decimal points. This has no effect except for
1172e5b6d6dSopenharmony_ci     * forcing the double in {@link DecimalQuantity_AbstractBCD} to adopt its exact representation.
1182e5b6d6dSopenharmony_ci     */
1192e5b6d6dSopenharmony_ci    void roundToInfinity();
1202e5b6d6dSopenharmony_ci
1212e5b6d6dSopenharmony_ci    /**
1222e5b6d6dSopenharmony_ci     * Multiply the internal value. Uses decNumber.
1232e5b6d6dSopenharmony_ci     *
1242e5b6d6dSopenharmony_ci     * @param multiplicand The value by which to multiply.
1252e5b6d6dSopenharmony_ci     */
1262e5b6d6dSopenharmony_ci    void multiplyBy(const DecNum& multiplicand, UErrorCode& status);
1272e5b6d6dSopenharmony_ci
1282e5b6d6dSopenharmony_ci    /**
1292e5b6d6dSopenharmony_ci     * Divide the internal value. Uses decNumber.
1302e5b6d6dSopenharmony_ci     *
1312e5b6d6dSopenharmony_ci     * @param multiplicand The value by which to multiply.
1322e5b6d6dSopenharmony_ci     */
1332e5b6d6dSopenharmony_ci    void divideBy(const DecNum& divisor, UErrorCode& status);
1342e5b6d6dSopenharmony_ci
1352e5b6d6dSopenharmony_ci    /** Flips the sign from positive to negative and back. */
1362e5b6d6dSopenharmony_ci    void negate();
1372e5b6d6dSopenharmony_ci
1382e5b6d6dSopenharmony_ci    /**
1392e5b6d6dSopenharmony_ci     * Scales the number by a power of ten. For example, if the value is currently "1234.56", calling
1402e5b6d6dSopenharmony_ci     * this method with delta=-3 will change the value to "1.23456".
1412e5b6d6dSopenharmony_ci     *
1422e5b6d6dSopenharmony_ci     * @param delta The number of magnitudes of ten to change by.
1432e5b6d6dSopenharmony_ci     * @return true if integer overflow occurred; false otherwise.
1442e5b6d6dSopenharmony_ci     */
1452e5b6d6dSopenharmony_ci    bool adjustMagnitude(int32_t delta);
1462e5b6d6dSopenharmony_ci
1472e5b6d6dSopenharmony_ci    /**
1482e5b6d6dSopenharmony_ci     * Scales the number such that the least significant nonzero digit is at magnitude 0.
1492e5b6d6dSopenharmony_ci     *
1502e5b6d6dSopenharmony_ci     * @return The previous magnitude of the least significant digit.
1512e5b6d6dSopenharmony_ci     */
1522e5b6d6dSopenharmony_ci    int32_t adjustToZeroScale();
1532e5b6d6dSopenharmony_ci
1542e5b6d6dSopenharmony_ci    /**
1552e5b6d6dSopenharmony_ci     * @return The power of ten corresponding to the most significant nonzero digit.
1562e5b6d6dSopenharmony_ci     * The number must not be zero.
1572e5b6d6dSopenharmony_ci     */
1582e5b6d6dSopenharmony_ci    int32_t getMagnitude() const;
1592e5b6d6dSopenharmony_ci
1602e5b6d6dSopenharmony_ci    /**
1612e5b6d6dSopenharmony_ci     * @return The value of the (suppressed) exponent after the number has been
1622e5b6d6dSopenharmony_ci     * put into a notation with exponents (ex: compact, scientific).  Ex: given
1632e5b6d6dSopenharmony_ci     * the number 1000 as "1K" / "1E3", the return value will be 3 (positive).
1642e5b6d6dSopenharmony_ci     */
1652e5b6d6dSopenharmony_ci    int32_t getExponent() const;
1662e5b6d6dSopenharmony_ci
1672e5b6d6dSopenharmony_ci    /**
1682e5b6d6dSopenharmony_ci     * Adjusts the value for the (suppressed) exponent stored when using
1692e5b6d6dSopenharmony_ci     * notation with exponents (ex: compact, scientific).
1702e5b6d6dSopenharmony_ci     *
1712e5b6d6dSopenharmony_ci     * <p>Adjusting the exponent is decoupled from {@link #adjustMagnitude} in
1722e5b6d6dSopenharmony_ci     * order to allow flexibility for {@link StandardPlural} to be selected in
1732e5b6d6dSopenharmony_ci     * formatting (ex: for compact notation) either with or without the exponent
1742e5b6d6dSopenharmony_ci     * applied in the value of the number.
1752e5b6d6dSopenharmony_ci     * @param delta
1762e5b6d6dSopenharmony_ci     *             The value to adjust the exponent by.
1772e5b6d6dSopenharmony_ci     */
1782e5b6d6dSopenharmony_ci    void adjustExponent(int32_t delta);
1792e5b6d6dSopenharmony_ci
1802e5b6d6dSopenharmony_ci    /**
1812e5b6d6dSopenharmony_ci     * Resets the DecimalQuantity to the value before adjustMagnitude and adjustExponent.
1822e5b6d6dSopenharmony_ci     */
1832e5b6d6dSopenharmony_ci    void resetExponent();
1842e5b6d6dSopenharmony_ci
1852e5b6d6dSopenharmony_ci    /**
1862e5b6d6dSopenharmony_ci     * @return Whether the value represented by this {@link DecimalQuantity} is
1872e5b6d6dSopenharmony_ci     * zero, infinity, or NaN.
1882e5b6d6dSopenharmony_ci     */
1892e5b6d6dSopenharmony_ci    bool isZeroish() const;
1902e5b6d6dSopenharmony_ci
1912e5b6d6dSopenharmony_ci    /** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */
1922e5b6d6dSopenharmony_ci    bool isNegative() const;
1932e5b6d6dSopenharmony_ci
1942e5b6d6dSopenharmony_ci    /** @return The appropriate value from the Signum enum. */
1952e5b6d6dSopenharmony_ci    Signum signum() const;
1962e5b6d6dSopenharmony_ci
1972e5b6d6dSopenharmony_ci    /** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */
1982e5b6d6dSopenharmony_ci    bool isInfinite() const U_OVERRIDE;
1992e5b6d6dSopenharmony_ci
2002e5b6d6dSopenharmony_ci    /** @return Whether the value represented by this {@link DecimalQuantity} is not a number. */
2012e5b6d6dSopenharmony_ci    bool isNaN() const U_OVERRIDE;
2022e5b6d6dSopenharmony_ci
2032e5b6d6dSopenharmony_ci    /**
2042e5b6d6dSopenharmony_ci     * Note: this method incorporates the value of {@code exponent}
2052e5b6d6dSopenharmony_ci     * (for cases such as compact notation) to return the proper long value
2062e5b6d6dSopenharmony_ci     * represented by the result.
2072e5b6d6dSopenharmony_ci     * @param truncateIfOverflow if false and the number does NOT fit, fails with an assertion error.
2082e5b6d6dSopenharmony_ci     */
2092e5b6d6dSopenharmony_ci    int64_t toLong(bool truncateIfOverflow = false) const;
2102e5b6d6dSopenharmony_ci
2112e5b6d6dSopenharmony_ci    /**
2122e5b6d6dSopenharmony_ci     * Note: this method incorporates the value of {@code exponent}
2132e5b6d6dSopenharmony_ci     * (for cases such as compact notation) to return the proper long value
2142e5b6d6dSopenharmony_ci     * represented by the result.
2152e5b6d6dSopenharmony_ci     */
2162e5b6d6dSopenharmony_ci    uint64_t toFractionLong(bool includeTrailingZeros) const;
2172e5b6d6dSopenharmony_ci
2182e5b6d6dSopenharmony_ci    /**
2192e5b6d6dSopenharmony_ci     * Returns whether or not a Long can fully represent the value stored in this DecimalQuantity.
2202e5b6d6dSopenharmony_ci     * @param ignoreFraction if true, silently ignore digits after the decimal place.
2212e5b6d6dSopenharmony_ci     */
2222e5b6d6dSopenharmony_ci    bool fitsInLong(bool ignoreFraction = false) const;
2232e5b6d6dSopenharmony_ci
2242e5b6d6dSopenharmony_ci    /** @return The value contained in this {@link DecimalQuantity} approximated as a double. */
2252e5b6d6dSopenharmony_ci    double toDouble() const;
2262e5b6d6dSopenharmony_ci
2272e5b6d6dSopenharmony_ci    /** Computes a DecNum representation of this DecimalQuantity, saving it to the output parameter. */
2282e5b6d6dSopenharmony_ci    DecNum& toDecNum(DecNum& output, UErrorCode& status) const;
2292e5b6d6dSopenharmony_ci
2302e5b6d6dSopenharmony_ci    DecimalQuantity &setToInt(int32_t n);
2312e5b6d6dSopenharmony_ci
2322e5b6d6dSopenharmony_ci    DecimalQuantity &setToLong(int64_t n);
2332e5b6d6dSopenharmony_ci
2342e5b6d6dSopenharmony_ci    DecimalQuantity &setToDouble(double n);
2352e5b6d6dSopenharmony_ci
2362e5b6d6dSopenharmony_ci    /**
2372e5b6d6dSopenharmony_ci     * Produces a DecimalQuantity that was parsed from a string by the decNumber
2382e5b6d6dSopenharmony_ci     * C Library.
2392e5b6d6dSopenharmony_ci     *
2402e5b6d6dSopenharmony_ci     * decNumber is similar to BigDecimal in Java, and supports parsing strings
2412e5b6d6dSopenharmony_ci     * such as "123.456621E+40".
2422e5b6d6dSopenharmony_ci     */
2432e5b6d6dSopenharmony_ci    DecimalQuantity &setToDecNumber(StringPiece n, UErrorCode& status);
2442e5b6d6dSopenharmony_ci
2452e5b6d6dSopenharmony_ci    /** Internal method if the caller already has a DecNum. */
2462e5b6d6dSopenharmony_ci    DecimalQuantity &setToDecNum(const DecNum& n, UErrorCode& status);
2472e5b6d6dSopenharmony_ci
2482e5b6d6dSopenharmony_ci    /** Returns a DecimalQuantity after parsing the input string. */
2492e5b6d6dSopenharmony_ci    static DecimalQuantity fromExponentString(UnicodeString n, UErrorCode& status);
2502e5b6d6dSopenharmony_ci
2512e5b6d6dSopenharmony_ci    /**
2522e5b6d6dSopenharmony_ci     * Appends a digit, optionally with one or more leading zeros, to the end of the value represented
2532e5b6d6dSopenharmony_ci     * by this DecimalQuantity.
2542e5b6d6dSopenharmony_ci     *
2552e5b6d6dSopenharmony_ci     * <p>The primary use of this method is to construct numbers during a parsing loop. It allows
2562e5b6d6dSopenharmony_ci     * parsing to take advantage of the digit list infrastructure primarily designed for formatting.
2572e5b6d6dSopenharmony_ci     *
2582e5b6d6dSopenharmony_ci     * @param value The digit to append.
2592e5b6d6dSopenharmony_ci     * @param leadingZeros The number of zeros to append before the digit. For example, if the value
2602e5b6d6dSopenharmony_ci     *     in this instance starts as 12.3, and you append a 4 with 1 leading zero, the value becomes
2612e5b6d6dSopenharmony_ci     *     12.304.
2622e5b6d6dSopenharmony_ci     * @param appendAsInteger If true, increase the magnitude of existing digits to make room for the
2632e5b6d6dSopenharmony_ci     *     new digit. If false, append to the end like a fraction digit. If true, there must not be
2642e5b6d6dSopenharmony_ci     *     any fraction digits already in the number.
2652e5b6d6dSopenharmony_ci     * @internal
2662e5b6d6dSopenharmony_ci     * @deprecated This API is ICU internal only.
2672e5b6d6dSopenharmony_ci     */
2682e5b6d6dSopenharmony_ci    void appendDigit(int8_t value, int32_t leadingZeros, bool appendAsInteger);
2692e5b6d6dSopenharmony_ci
2702e5b6d6dSopenharmony_ci    double getPluralOperand(PluralOperand operand) const U_OVERRIDE;
2712e5b6d6dSopenharmony_ci
2722e5b6d6dSopenharmony_ci    bool hasIntegerValue() const U_OVERRIDE;
2732e5b6d6dSopenharmony_ci
2742e5b6d6dSopenharmony_ci    /**
2752e5b6d6dSopenharmony_ci     * Gets the digit at the specified magnitude. For example, if the represented number is 12.3,
2762e5b6d6dSopenharmony_ci     * getDigit(-1) returns 3, since 3 is the digit corresponding to 10^-1.
2772e5b6d6dSopenharmony_ci     *
2782e5b6d6dSopenharmony_ci     * @param magnitude The magnitude of the digit.
2792e5b6d6dSopenharmony_ci     * @return The digit at the specified magnitude.
2802e5b6d6dSopenharmony_ci     */
2812e5b6d6dSopenharmony_ci    int8_t getDigit(int32_t magnitude) const;
2822e5b6d6dSopenharmony_ci
2832e5b6d6dSopenharmony_ci    /**
2842e5b6d6dSopenharmony_ci     * Gets the largest power of ten that needs to be displayed. The value returned by this function
2852e5b6d6dSopenharmony_ci     * will be bounded between minInt and maxInt.
2862e5b6d6dSopenharmony_ci     *
2872e5b6d6dSopenharmony_ci     * @return The highest-magnitude digit to be displayed.
2882e5b6d6dSopenharmony_ci     */
2892e5b6d6dSopenharmony_ci    int32_t getUpperDisplayMagnitude() const;
2902e5b6d6dSopenharmony_ci
2912e5b6d6dSopenharmony_ci    /**
2922e5b6d6dSopenharmony_ci     * Gets the smallest power of ten that needs to be displayed. The value returned by this function
2932e5b6d6dSopenharmony_ci     * will be bounded between -minFrac and -maxFrac.
2942e5b6d6dSopenharmony_ci     *
2952e5b6d6dSopenharmony_ci     * @return The lowest-magnitude digit to be displayed.
2962e5b6d6dSopenharmony_ci     */
2972e5b6d6dSopenharmony_ci    int32_t getLowerDisplayMagnitude() const;
2982e5b6d6dSopenharmony_ci
2992e5b6d6dSopenharmony_ci    int32_t fractionCount() const;
3002e5b6d6dSopenharmony_ci
3012e5b6d6dSopenharmony_ci    int32_t fractionCountWithoutTrailingZeros() const;
3022e5b6d6dSopenharmony_ci
3032e5b6d6dSopenharmony_ci    void clear();
3042e5b6d6dSopenharmony_ci
3052e5b6d6dSopenharmony_ci    /** This method is for internal testing only. */
3062e5b6d6dSopenharmony_ci    uint64_t getPositionFingerprint() const;
3072e5b6d6dSopenharmony_ci
3082e5b6d6dSopenharmony_ci//    /**
3092e5b6d6dSopenharmony_ci//     * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction
3102e5b6d6dSopenharmony_ci//     * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing
3112e5b6d6dSopenharmony_ci//     * happens.
3122e5b6d6dSopenharmony_ci//     *
3132e5b6d6dSopenharmony_ci//     * @param fp The {@link UFieldPosition} to populate.
3142e5b6d6dSopenharmony_ci//     */
3152e5b6d6dSopenharmony_ci//    void populateUFieldPosition(FieldPosition fp);
3162e5b6d6dSopenharmony_ci
3172e5b6d6dSopenharmony_ci    /**
3182e5b6d6dSopenharmony_ci     * Checks whether the bytes stored in this instance are all valid. For internal unit testing only.
3192e5b6d6dSopenharmony_ci     *
3202e5b6d6dSopenharmony_ci     * @return An error message if this instance is invalid, or null if this instance is healthy.
3212e5b6d6dSopenharmony_ci     */
3222e5b6d6dSopenharmony_ci    const char16_t* checkHealth() const;
3232e5b6d6dSopenharmony_ci
3242e5b6d6dSopenharmony_ci    UnicodeString toString() const;
3252e5b6d6dSopenharmony_ci
3262e5b6d6dSopenharmony_ci    /** Returns the string in standard exponential notation. */
3272e5b6d6dSopenharmony_ci    UnicodeString toScientificString() const;
3282e5b6d6dSopenharmony_ci
3292e5b6d6dSopenharmony_ci    /** Returns the string without exponential notation. Slightly slower than toScientificString(). */
3302e5b6d6dSopenharmony_ci    UnicodeString toPlainString() const;
3312e5b6d6dSopenharmony_ci
3322e5b6d6dSopenharmony_ci    /** Returns the string using ASCII digits and using exponential notation for non-zero
3332e5b6d6dSopenharmony_ci    exponents, following the UTS 35 specification for plural rule samples. */
3342e5b6d6dSopenharmony_ci    UnicodeString toExponentString() const;
3352e5b6d6dSopenharmony_ci
3362e5b6d6dSopenharmony_ci    /** Visible for testing */
3372e5b6d6dSopenharmony_ci    inline bool isUsingBytes() { return usingBytes; }
3382e5b6d6dSopenharmony_ci
3392e5b6d6dSopenharmony_ci    /** Visible for testing */
3402e5b6d6dSopenharmony_ci    inline bool isExplicitExactDouble() { return explicitExactDouble; }
3412e5b6d6dSopenharmony_ci
3422e5b6d6dSopenharmony_ci    bool operator==(const DecimalQuantity& other) const;
3432e5b6d6dSopenharmony_ci
3442e5b6d6dSopenharmony_ci    inline bool operator!=(const DecimalQuantity& other) const {
3452e5b6d6dSopenharmony_ci        return !(*this == other);
3462e5b6d6dSopenharmony_ci    }
3472e5b6d6dSopenharmony_ci
3482e5b6d6dSopenharmony_ci    /**
3492e5b6d6dSopenharmony_ci     * Bogus flag for when a DecimalQuantity is stored on the stack.
3502e5b6d6dSopenharmony_ci     */
3512e5b6d6dSopenharmony_ci    bool bogus = false;
3522e5b6d6dSopenharmony_ci
3532e5b6d6dSopenharmony_ci  private:
3542e5b6d6dSopenharmony_ci    /**
3552e5b6d6dSopenharmony_ci     * The power of ten corresponding to the least significant digit in the BCD. For example, if this
3562e5b6d6dSopenharmony_ci     * object represents the number "3.14", the BCD will be "0x314" and the scale will be -2.
3572e5b6d6dSopenharmony_ci     *
3582e5b6d6dSopenharmony_ci     * <p>Note that in {@link java.math.BigDecimal}, the scale is defined differently: the number of
3592e5b6d6dSopenharmony_ci     * digits after the decimal place, which is the negative of our definition of scale.
3602e5b6d6dSopenharmony_ci     */
3612e5b6d6dSopenharmony_ci    int32_t scale;
3622e5b6d6dSopenharmony_ci
3632e5b6d6dSopenharmony_ci    /**
3642e5b6d6dSopenharmony_ci     * The number of digits in the BCD. For example, "1007" has BCD "0x1007" and precision 4. The
3652e5b6d6dSopenharmony_ci     * maximum precision is 16 since a long can hold only 16 digits.
3662e5b6d6dSopenharmony_ci     *
3672e5b6d6dSopenharmony_ci     * <p>This value must be re-calculated whenever the value in bcd changes by using {@link
3682e5b6d6dSopenharmony_ci     * #computePrecisionAndCompact()}.
3692e5b6d6dSopenharmony_ci     */
3702e5b6d6dSopenharmony_ci    int32_t precision;
3712e5b6d6dSopenharmony_ci
3722e5b6d6dSopenharmony_ci    /**
3732e5b6d6dSopenharmony_ci     * A bitmask of properties relating to the number represented by this object.
3742e5b6d6dSopenharmony_ci     *
3752e5b6d6dSopenharmony_ci     * @see #NEGATIVE_FLAG
3762e5b6d6dSopenharmony_ci     * @see #INFINITY_FLAG
3772e5b6d6dSopenharmony_ci     * @see #NAN_FLAG
3782e5b6d6dSopenharmony_ci     */
3792e5b6d6dSopenharmony_ci    int8_t flags;
3802e5b6d6dSopenharmony_ci
3812e5b6d6dSopenharmony_ci    // The following three fields relate to the double-to-ascii fast path algorithm.
3822e5b6d6dSopenharmony_ci    // When a double is given to DecimalQuantityBCD, it is converted to using a fast algorithm. The
3832e5b6d6dSopenharmony_ci    // fast algorithm guarantees correctness to only the first ~12 digits of the double. The process
3842e5b6d6dSopenharmony_ci    // of rounding the number ensures that the converted digits are correct, falling back to a slow-
3852e5b6d6dSopenharmony_ci    // path algorithm if required.  Therefore, if a DecimalQuantity is constructed from a double, it
3862e5b6d6dSopenharmony_ci    // is *required* that roundToMagnitude(), roundToIncrement(), or roundToInfinity() is called. If
3872e5b6d6dSopenharmony_ci    // you don't round, assertions will fail in certain other methods if you try calling them.
3882e5b6d6dSopenharmony_ci
3892e5b6d6dSopenharmony_ci    /**
3902e5b6d6dSopenharmony_ci     * Whether the value in the BCD comes from the double fast path without having been rounded to
3912e5b6d6dSopenharmony_ci     * ensure correctness
3922e5b6d6dSopenharmony_ci     */
3932e5b6d6dSopenharmony_ci    UBool isApproximate;
3942e5b6d6dSopenharmony_ci
3952e5b6d6dSopenharmony_ci    /**
3962e5b6d6dSopenharmony_ci     * The original number provided by the user and which is represented in BCD. Used when we need to
3972e5b6d6dSopenharmony_ci     * re-compute the BCD for an exact double representation.
3982e5b6d6dSopenharmony_ci     */
3992e5b6d6dSopenharmony_ci    double origDouble;
4002e5b6d6dSopenharmony_ci
4012e5b6d6dSopenharmony_ci    /**
4022e5b6d6dSopenharmony_ci     * The change in magnitude relative to the original double. Used when we need to re-compute the
4032e5b6d6dSopenharmony_ci     * BCD for an exact double representation.
4042e5b6d6dSopenharmony_ci     */
4052e5b6d6dSopenharmony_ci    int32_t origDelta;
4062e5b6d6dSopenharmony_ci
4072e5b6d6dSopenharmony_ci    // Positions to keep track of leading and trailing zeros.
4082e5b6d6dSopenharmony_ci    // lReqPos is the magnitude of the first required leading zero.
4092e5b6d6dSopenharmony_ci    // rReqPos is the magnitude of the last required trailing zero.
4102e5b6d6dSopenharmony_ci    int32_t lReqPos = 0;
4112e5b6d6dSopenharmony_ci    int32_t rReqPos = 0;
4122e5b6d6dSopenharmony_ci
4132e5b6d6dSopenharmony_ci    // The value of the (suppressed) exponent after the number has been put into
4142e5b6d6dSopenharmony_ci    // a notation with exponents (ex: compact, scientific).
4152e5b6d6dSopenharmony_ci    int32_t exponent = 0;
4162e5b6d6dSopenharmony_ci
4172e5b6d6dSopenharmony_ci    /**
4182e5b6d6dSopenharmony_ci     * The BCD of the 16 digits of the number represented by this object. Every 4 bits of the long map
4192e5b6d6dSopenharmony_ci     * to one digit. For example, the number "12345" in BCD is "0x12345".
4202e5b6d6dSopenharmony_ci     *
4212e5b6d6dSopenharmony_ci     * <p>Whenever bcd changes internally, {@link #compact()} must be called, except in special cases
4222e5b6d6dSopenharmony_ci     * like setting the digit to zero.
4232e5b6d6dSopenharmony_ci     */
4242e5b6d6dSopenharmony_ci    union {
4252e5b6d6dSopenharmony_ci        struct {
4262e5b6d6dSopenharmony_ci            int8_t *ptr;
4272e5b6d6dSopenharmony_ci            int32_t len;
4282e5b6d6dSopenharmony_ci        } bcdBytes;
4292e5b6d6dSopenharmony_ci        uint64_t bcdLong;
4302e5b6d6dSopenharmony_ci    } fBCD;
4312e5b6d6dSopenharmony_ci
4322e5b6d6dSopenharmony_ci    bool usingBytes = false;
4332e5b6d6dSopenharmony_ci
4342e5b6d6dSopenharmony_ci    /**
4352e5b6d6dSopenharmony_ci     * Whether this {@link DecimalQuantity} has been explicitly converted to an exact double. true if
4362e5b6d6dSopenharmony_ci     * backed by a double that was explicitly converted via convertToAccurateDouble; false otherwise.
4372e5b6d6dSopenharmony_ci     * Used for testing.
4382e5b6d6dSopenharmony_ci     */
4392e5b6d6dSopenharmony_ci    bool explicitExactDouble = false;
4402e5b6d6dSopenharmony_ci
4412e5b6d6dSopenharmony_ci    void roundToMagnitude(int32_t magnitude, RoundingMode roundingMode, bool nickel, UErrorCode& status);
4422e5b6d6dSopenharmony_ci
4432e5b6d6dSopenharmony_ci    /**
4442e5b6d6dSopenharmony_ci     * Returns a single digit from the BCD list. No internal state is changed by calling this method.
4452e5b6d6dSopenharmony_ci     *
4462e5b6d6dSopenharmony_ci     * @param position The position of the digit to pop, counted in BCD units from the least
4472e5b6d6dSopenharmony_ci     *     significant digit. If outside the range supported by the implementation, zero is returned.
4482e5b6d6dSopenharmony_ci     * @return The digit at the specified location.
4492e5b6d6dSopenharmony_ci     */
4502e5b6d6dSopenharmony_ci    int8_t getDigitPos(int32_t position) const;
4512e5b6d6dSopenharmony_ci
4522e5b6d6dSopenharmony_ci    /**
4532e5b6d6dSopenharmony_ci     * Sets the digit in the BCD list. This method only sets the digit; it is the caller's
4542e5b6d6dSopenharmony_ci     * responsibility to call {@link #compact} after setting the digit, and to ensure
4552e5b6d6dSopenharmony_ci     * that the precision field is updated to reflect the correct number of digits if a
4562e5b6d6dSopenharmony_ci     * nonzero digit is added to the decimal.
4572e5b6d6dSopenharmony_ci     *
4582e5b6d6dSopenharmony_ci     * @param position The position of the digit to pop, counted in BCD units from the least
4592e5b6d6dSopenharmony_ci     *     significant digit. If outside the range supported by the implementation, an AssertionError
4602e5b6d6dSopenharmony_ci     *     is thrown.
4612e5b6d6dSopenharmony_ci     * @param value The digit to set at the specified location.
4622e5b6d6dSopenharmony_ci     */
4632e5b6d6dSopenharmony_ci    void setDigitPos(int32_t position, int8_t value);
4642e5b6d6dSopenharmony_ci
4652e5b6d6dSopenharmony_ci    /**
4662e5b6d6dSopenharmony_ci     * Adds zeros to the end of the BCD list. This will result in an invalid BCD representation; it is
4672e5b6d6dSopenharmony_ci     * the caller's responsibility to do further manipulation and then call {@link #compact}.
4682e5b6d6dSopenharmony_ci     *
4692e5b6d6dSopenharmony_ci     * @param numDigits The number of zeros to add.
4702e5b6d6dSopenharmony_ci     */
4712e5b6d6dSopenharmony_ci    void shiftLeft(int32_t numDigits);
4722e5b6d6dSopenharmony_ci
4732e5b6d6dSopenharmony_ci    /**
4742e5b6d6dSopenharmony_ci     * Directly removes digits from the end of the BCD list.
4752e5b6d6dSopenharmony_ci     * Updates the scale and precision.
4762e5b6d6dSopenharmony_ci     *
4772e5b6d6dSopenharmony_ci     * CAUTION: it is the caller's responsibility to call {@link #compact} after this method.
4782e5b6d6dSopenharmony_ci     */
4792e5b6d6dSopenharmony_ci    void shiftRight(int32_t numDigits);
4802e5b6d6dSopenharmony_ci
4812e5b6d6dSopenharmony_ci    /**
4822e5b6d6dSopenharmony_ci     * Directly removes digits from the front of the BCD list.
4832e5b6d6dSopenharmony_ci     * Updates precision.
4842e5b6d6dSopenharmony_ci     *
4852e5b6d6dSopenharmony_ci     * CAUTION: it is the caller's responsibility to call {@link #compact} after this method.
4862e5b6d6dSopenharmony_ci     */
4872e5b6d6dSopenharmony_ci    void popFromLeft(int32_t numDigits);
4882e5b6d6dSopenharmony_ci
4892e5b6d6dSopenharmony_ci    /**
4902e5b6d6dSopenharmony_ci     * Sets the internal representation to zero. Clears any values stored in scale, precision,
4912e5b6d6dSopenharmony_ci     * hasDouble, origDouble, origDelta, exponent, and BCD data.
4922e5b6d6dSopenharmony_ci     */
4932e5b6d6dSopenharmony_ci    void setBcdToZero();
4942e5b6d6dSopenharmony_ci
4952e5b6d6dSopenharmony_ci    /**
4962e5b6d6dSopenharmony_ci     * Sets the internal BCD state to represent the value in the given int. The int is guaranteed to
4972e5b6d6dSopenharmony_ci     * be either positive. The internal state is guaranteed to be empty when this method is called.
4982e5b6d6dSopenharmony_ci     *
4992e5b6d6dSopenharmony_ci     * @param n The value to consume.
5002e5b6d6dSopenharmony_ci     */
5012e5b6d6dSopenharmony_ci    void readIntToBcd(int32_t n);
5022e5b6d6dSopenharmony_ci
5032e5b6d6dSopenharmony_ci    /**
5042e5b6d6dSopenharmony_ci     * Sets the internal BCD state to represent the value in the given long. The long is guaranteed to
5052e5b6d6dSopenharmony_ci     * be either positive. The internal state is guaranteed to be empty when this method is called.
5062e5b6d6dSopenharmony_ci     *
5072e5b6d6dSopenharmony_ci     * @param n The value to consume.
5082e5b6d6dSopenharmony_ci     */
5092e5b6d6dSopenharmony_ci    void readLongToBcd(int64_t n);
5102e5b6d6dSopenharmony_ci
5112e5b6d6dSopenharmony_ci    void readDecNumberToBcd(const DecNum& dn);
5122e5b6d6dSopenharmony_ci
5132e5b6d6dSopenharmony_ci    void readDoubleConversionToBcd(const char* buffer, int32_t length, int32_t point);
5142e5b6d6dSopenharmony_ci
5152e5b6d6dSopenharmony_ci    void copyFieldsFrom(const DecimalQuantity& other);
5162e5b6d6dSopenharmony_ci
5172e5b6d6dSopenharmony_ci    void copyBcdFrom(const DecimalQuantity &other);
5182e5b6d6dSopenharmony_ci
5192e5b6d6dSopenharmony_ci    void moveBcdFrom(DecimalQuantity& src);
5202e5b6d6dSopenharmony_ci
5212e5b6d6dSopenharmony_ci    /**
5222e5b6d6dSopenharmony_ci     * Removes trailing zeros from the BCD (adjusting the scale as required) and then computes the
5232e5b6d6dSopenharmony_ci     * precision. The precision is the number of digits in the number up through the greatest nonzero
5242e5b6d6dSopenharmony_ci     * digit.
5252e5b6d6dSopenharmony_ci     *
5262e5b6d6dSopenharmony_ci     * <p>This method must always be called when bcd changes in order for assumptions to be correct in
5272e5b6d6dSopenharmony_ci     * methods like {@link #fractionCount()}.
5282e5b6d6dSopenharmony_ci     */
5292e5b6d6dSopenharmony_ci    void compact();
5302e5b6d6dSopenharmony_ci
5312e5b6d6dSopenharmony_ci    void _setToInt(int32_t n);
5322e5b6d6dSopenharmony_ci
5332e5b6d6dSopenharmony_ci    void _setToLong(int64_t n);
5342e5b6d6dSopenharmony_ci
5352e5b6d6dSopenharmony_ci    void _setToDoubleFast(double n);
5362e5b6d6dSopenharmony_ci
5372e5b6d6dSopenharmony_ci    void _setToDecNum(const DecNum& dn, UErrorCode& status);
5382e5b6d6dSopenharmony_ci
5392e5b6d6dSopenharmony_ci    static int32_t getVisibleFractionCount(UnicodeString value);
5402e5b6d6dSopenharmony_ci
5412e5b6d6dSopenharmony_ci    void convertToAccurateDouble();
5422e5b6d6dSopenharmony_ci
5432e5b6d6dSopenharmony_ci    /** Ensure that a byte array of at least 40 digits is allocated. */
5442e5b6d6dSopenharmony_ci    void ensureCapacity();
5452e5b6d6dSopenharmony_ci
5462e5b6d6dSopenharmony_ci    void ensureCapacity(int32_t capacity);
5472e5b6d6dSopenharmony_ci
5482e5b6d6dSopenharmony_ci    /** Switches the internal storage mechanism between the 64-bit long and the byte array. */
5492e5b6d6dSopenharmony_ci    void switchStorage();
5502e5b6d6dSopenharmony_ci};
5512e5b6d6dSopenharmony_ci
5522e5b6d6dSopenharmony_ci} // namespace impl
5532e5b6d6dSopenharmony_ci} // namespace number
5542e5b6d6dSopenharmony_ciU_NAMESPACE_END
5552e5b6d6dSopenharmony_ci
5562e5b6d6dSopenharmony_ci
5572e5b6d6dSopenharmony_ci#endif //__NUMBER_DECIMALQUANTITY_H__
5582e5b6d6dSopenharmony_ci
5592e5b6d6dSopenharmony_ci#endif /* #if !UCONFIG_NO_FORMATTING */
560