1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT
7 #ifndef __NUMBER_DECIMALQUANTITY_H__
8 #define __NUMBER_DECIMALQUANTITY_H__
9 
10 #include <cstdint>
11 #include "unicode/umachine.h"
12 #include "decNumber.h"
13 #include "standardplural.h"
14 #include "plurrule_impl.h"
15 #include "number_types.h"
16 
17 U_NAMESPACE_BEGIN namespace number {
18 namespace impl {
19 
20 /**
21  * An class for representing a number to be processed by the decimal formatting pipeline. Includes
22  * methods for rounding, plural rules, and decimal digit extraction.
23  *
24  * <p>By design, this is NOT IMMUTABLE and NOT THREAD SAFE. It is intended to be an intermediate
25  * object holding state during a pass through the decimal formatting pipeline.
26  *
27  * <p>Represents numbers and digit display properties using Binary Coded Decimal (BCD).
28  *
29  * <p>Java has multiple implementations for testing, but C++ has only one implementation.
30  */
31 class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
32   public:
33     /** Copy constructor. */
34     DecimalQuantity(const DecimalQuantity &other);
35 
36     DecimalQuantity();
37 
38     ~DecimalQuantity();
39 
40     /**
41      * Sets this instance to be equal to another instance.
42      *
43      * @param other The instance to copy from.
44      */
45     DecimalQuantity &operator=(const DecimalQuantity &other);
46 
47     /**
48      * Sets the minimum and maximum integer digits that this {@link DecimalQuantity} should generate.
49      * This method does not perform rounding.
50      *
51      * @param minInt The minimum number of integer digits.
52      * @param maxInt The maximum number of integer digits.
53      */
54     void setIntegerLength(int32_t minInt, int32_t maxInt);
55 
56     /**
57      * Sets the minimum and maximum fraction digits that this {@link DecimalQuantity} should generate.
58      * This method does not perform rounding.
59      *
60      * @param minFrac The minimum number of fraction digits.
61      * @param maxFrac The maximum number of fraction digits.
62      */
63     void setFractionLength(int32_t minFrac, int32_t maxFrac);
64 
65     /**
66      * Rounds the number to a specified interval, such as 0.05.
67      *
68      * <p>If rounding to a power of ten, use the more efficient {@link #roundToMagnitude} instead.
69      *
70      * @param roundingIncrement The increment to which to round.
71      * @param mathContext The {@link RoundingMode} to use if rounding is necessary.
72      */
73     void roundToIncrement(double roundingIncrement, RoundingMode roundingMode,
74                           int32_t minMaxFrac, UErrorCode& status);
75 
76     /**
77      * Rounds the number to a specified magnitude (power of ten).
78      *
79      * @param roundingMagnitude The power of ten to which to round. For example, a value of -2 will
80      *     round to 2 decimal places.
81      * @param mathContext The {@link RoundingMode} to use if rounding is necessary.
82      */
83     void roundToMagnitude(int32_t magnitude, RoundingMode roundingMode, UErrorCode& status);
84 
85     /**
86      * Rounds the number to an infinite number of decimal points. This has no effect except for
87      * forcing the double in {@link DecimalQuantity_AbstractBCD} to adopt its exact representation.
88      */
89     void roundToInfinity();
90 
91     /**
92      * Multiply the internal value.
93      *
94      * @param multiplicand The value by which to multiply.
95      */
96     void multiplyBy(int32_t multiplicand);
97 
98     /**
99      * Scales the number by a power of ten. For example, if the value is currently "1234.56", calling
100      * this method with delta=-3 will change the value to "1.23456".
101      *
102      * @param delta The number of magnitudes of ten to change by.
103      */
104     void adjustMagnitude(int32_t delta);
105 
106     /**
107      * @return The power of ten corresponding to the most significant nonzero digit.
108      * The number must not be zero.
109      */
110     int32_t getMagnitude() const;
111 
112     /** @return Whether the value represented by this {@link DecimalQuantity} is zero. */
113     bool isZero() const;
114 
115     /** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */
116     bool isNegative() const;
117 
118     /** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */
119     bool isInfinite() const U_OVERRIDE;
120 
121     /** @return Whether the value represented by this {@link DecimalQuantity} is not a number. */
122     bool isNaN() const U_OVERRIDE;
123 
124     int64_t toLong() const;
125 
126     int64_t toFractionLong(bool includeTrailingZeros) const;
127 
128     /** @return The value contained in this {@link DecimalQuantity} approximated as a double. */
129     double toDouble() const;
130 
131     DecimalQuantity &setToInt(int32_t n);
132 
133     DecimalQuantity &setToLong(int64_t n);
134 
135     DecimalQuantity &setToDouble(double n);
136 
137     /** decNumber is similar to BigDecimal in Java. */
138 
139     DecimalQuantity &setToDecNumber(StringPiece n);
140 
141     /**
142      * Appends a digit, optionally with one or more leading zeros, to the end of the value represented
143      * by this DecimalQuantity.
144      *
145      * <p>The primary use of this method is to construct numbers during a parsing loop. It allows
146      * parsing to take advantage of the digit list infrastructure primarily designed for formatting.
147      *
148      * @param value The digit to append.
149      * @param leadingZeros The number of zeros to append before the digit. For example, if the value
150      *     in this instance starts as 12.3, and you append a 4 with 1 leading zero, the value becomes
151      *     12.304.
152      * @param appendAsInteger If true, increase the magnitude of existing digits to make room for the
153      *     new digit. If false, append to the end like a fraction digit. If true, there must not be
154      *     any fraction digits already in the number.
155      * @internal
156      * @deprecated This API is ICU internal only.
157      */
158     void appendDigit(int8_t value, int32_t leadingZeros, bool appendAsInteger);
159 
160     /**
161      * Computes the plural form for this number based on the specified set of rules.
162      *
163      * @param rules A {@link PluralRules} object representing the set of rules.
164      * @return The {@link StandardPlural} according to the PluralRules. If the plural form is not in
165      *     the set of standard plurals, {@link StandardPlural#OTHER} is returned instead.
166      */
167     StandardPlural::Form getStandardPlural(const PluralRules *rules) const;
168 
169     double getPluralOperand(PluralOperand operand) const U_OVERRIDE;
170 
171     /**
172      * Gets the digit at the specified magnitude. For example, if the represented number is 12.3,
173      * getDigit(-1) returns 3, since 3 is the digit corresponding to 10^-1.
174      *
175      * @param magnitude The magnitude of the digit.
176      * @return The digit at the specified magnitude.
177      */
178     int8_t getDigit(int32_t magnitude) const;
179 
180     /**
181      * Gets the largest power of ten that needs to be displayed. The value returned by this function
182      * will be bounded between minInt and maxInt.
183      *
184      * @return The highest-magnitude digit to be displayed.
185      */
186     int32_t getUpperDisplayMagnitude() const;
187 
188     /**
189      * Gets the smallest power of ten that needs to be displayed. The value returned by this function
190      * will be bounded between -minFrac and -maxFrac.
191      *
192      * @return The lowest-magnitude digit to be displayed.
193      */
194     int32_t getLowerDisplayMagnitude() const;
195 
196     int32_t fractionCount() const;
197 
198     int32_t fractionCountWithoutTrailingZeros() const;
199 
200     void clear();
201 
202     /** This method is for internal testing only. */
203     uint64_t getPositionFingerprint() const;
204 
205 //    /**
206 //     * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction
207 //     * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing
208 //     * happens.
209 //     *
210 //     * @param fp The {@link UFieldPosition} to populate.
211 //     */
212 //    void populateUFieldPosition(FieldPosition fp);
213 
214     /**
215      * Checks whether the bytes stored in this instance are all valid. For internal unit testing only.
216      *
217      * @return An error message if this instance is invalid, or null if this instance is healthy.
218      */
219     const char16_t* checkHealth() const;
220 
221     UnicodeString toString() const;
222 
223     /* Returns the string in exponential notation. */
224     UnicodeString toNumberString() const;
225 
226     /* Returns the string without exponential notation. Slightly slower than toNumberString(). */
227     UnicodeString toPlainString() const;
228 
229     /** Visible for testing */
230     inline bool isUsingBytes() { return usingBytes; }
231 
232     /** Visible for testing */
233     inline bool isExplicitExactDouble() { return explicitExactDouble; };
234 
235   private:
236     /**
237      * The power of ten corresponding to the least significant digit in the BCD. For example, if this
238      * object represents the number "3.14", the BCD will be "0x314" and the scale will be -2.
239      *
240      * <p>Note that in {@link java.math.BigDecimal}, the scale is defined differently: the number of
241      * digits after the decimal place, which is the negative of our definition of scale.
242      */
243     int32_t scale;
244 
245     /**
246      * The number of digits in the BCD. For example, "1007" has BCD "0x1007" and precision 4. The
247      * maximum precision is 16 since a long can hold only 16 digits.
248      *
249      * <p>This value must be re-calculated whenever the value in bcd changes by using {@link
250      * #computePrecisionAndCompact()}.
251      */
252     int32_t precision;
253 
254     /**
255      * A bitmask of properties relating to the number represented by this object.
256      *
257      * @see #NEGATIVE_FLAG
258      * @see #INFINITY_FLAG
259      * @see #NAN_FLAG
260      */
261     int8_t flags;
262 
263     // The following three fields relate to the double-to-ascii fast path algorithm.
264     // When a double is given to DecimalQuantityBCD, it is converted to using a fast algorithm. The
265     // fast algorithm guarantees correctness to only the first ~12 digits of the double. The process
266     // of rounding the number ensures that the converted digits are correct, falling back to a slow-
267     // path algorithm if required.  Therefore, if a DecimalQuantity is constructed from a double, it
268     // is *required* that roundToMagnitude(), roundToIncrement(), or roundToInfinity() is called. If
269     // you don't round, assertions will fail in certain other methods if you try calling them.
270 
271     /**
272      * Whether the value in the BCD comes from the double fast path without having been rounded to
273      * ensure correctness
274      */
275     UBool isApproximate;
276 
277     /**
278      * The original number provided by the user and which is represented in BCD. Used when we need to
279      * re-compute the BCD for an exact double representation.
280      */
281     double origDouble;
282 
283     /**
284      * The change in magnitude relative to the original double. Used when we need to re-compute the
285      * BCD for an exact double representation.
286      */
287     int32_t origDelta;
288 
289     // Four positions: left optional '(', left required '[', right required ']', right optional ')'.
290     // These four positions determine which digits are displayed in the output string.  They do NOT
291     // affect rounding.  These positions are internal-only and can be specified only by the public
292     // endpoints like setFractionLength, setIntegerLength, and setSignificantDigits, among others.
293     //
294     //   * Digits between lReqPos and rReqPos are in the "required zone" and are always displayed.
295     //   * Digits between lOptPos and rOptPos but outside the required zone are in the "optional zone"
296     //     and are displayed unless they are trailing off the left or right edge of the number and
297     //     have a numerical value of zero.  In order to be "trailing", the digits need to be beyond
298     //     the decimal point in their respective directions.
299     //   * Digits outside of the "optional zone" are never displayed.
300     //
301     // See the table below for illustrative examples.
302     //
303     // +---------+---------+---------+---------+------------+------------------------+--------------+
304     // | lOptPos | lReqPos | rReqPos | rOptPos |   number   |        positions       | en-US string |
305     // +---------+---------+---------+---------+------------+------------------------+--------------+
306     // |    5    |    2    |   -1    |   -5    |   1234.567 |     ( 12[34.5]67  )    |   1,234.567  |
307     // |    3    |    2    |   -1    |   -5    |   1234.567 |      1(2[34.5]67  )    |     234.567  |
308     // |    3    |    2    |   -1    |   -2    |   1234.567 |      1(2[34.5]6)7      |     234.56   |
309     // |    6    |    4    |    2    |   -5    | 123456789. |  123(45[67]89.     )   | 456,789.     |
310     // |    6    |    4    |    2    |    1    | 123456789. |     123(45[67]8)9.     | 456,780.     |
311     // |   -1    |   -1    |   -3    |   -4    | 0.123456   |     0.1([23]4)56       |        .0234 |
312     // |    6    |    4    |   -2    |   -2    |     12.3   |     (  [  12.3 ])      |    0012.30   |
313     // +---------+---------+---------+---------+------------+------------------------+--------------+
314     //
315     int32_t lOptPos = INT32_MAX;
316     int32_t lReqPos = 0;
317     int32_t rReqPos = 0;
318     int32_t rOptPos = INT32_MIN;
319 
320     /**
321      * The BCD of the 16 digits of the number represented by this object. Every 4 bits of the long map
322      * to one digit. For example, the number "12345" in BCD is "0x12345".
323      *
324      * <p>Whenever bcd changes internally, {@link #compact()} must be called, except in special cases
325      * like setting the digit to zero.
326      */
327     union {
328         struct {
329             int8_t *ptr;
330             int32_t len;
331         } bcdBytes;
332         uint64_t bcdLong;
333     } fBCD;
334 
335     bool usingBytes = false;
336 
337     /**
338      * Whether this {@link DecimalQuantity} has been explicitly converted to an exact double. true if
339      * backed by a double that was explicitly converted via convertToAccurateDouble; false otherwise.
340      * Used for testing.
341      */
342     bool explicitExactDouble = false;
343 
344     /**
345      * Returns a single digit from the BCD list. No internal state is changed by calling this method.
346      *
347      * @param position The position of the digit to pop, counted in BCD units from the least
348      *     significant digit. If outside the range supported by the implementation, zero is returned.
349      * @return The digit at the specified location.
350      */
351     int8_t getDigitPos(int32_t position) const;
352 
353     /**
354      * Sets the digit in the BCD list. This method only sets the digit; it is the caller's
355      * responsibility to call {@link #compact} after setting the digit.
356      *
357      * @param position The position of the digit to pop, counted in BCD units from the least
358      *     significant digit. If outside the range supported by the implementation, an AssertionError
359      *     is thrown.
360      * @param value The digit to set at the specified location.
361      */
362     void setDigitPos(int32_t position, int8_t value);
363 
364     /**
365      * Adds zeros to the end of the BCD list. This will result in an invalid BCD representation; it is
366      * the caller's responsibility to do further manipulation and then call {@link #compact}.
367      *
368      * @param numDigits The number of zeros to add.
369      */
370     void shiftLeft(int32_t numDigits);
371 
372     void shiftRight(int32_t numDigits);
373 
374     /**
375      * Sets the internal representation to zero. Clears any values stored in scale, precision,
376      * hasDouble, origDouble, origDelta, and BCD data.
377      */
378     void setBcdToZero();
379 
380     /**
381      * Sets the internal BCD state to represent the value in the given int. The int is guaranteed to
382      * be either positive. The internal state is guaranteed to be empty when this method is called.
383      *
384      * @param n The value to consume.
385      */
386     void readIntToBcd(int32_t n);
387 
388     /**
389      * Sets the internal BCD state to represent the value in the given long. The long is guaranteed to
390      * be either positive. The internal state is guaranteed to be empty when this method is called.
391      *
392      * @param n The value to consume.
393      */
394     void readLongToBcd(int64_t n);
395 
396     void readDecNumberToBcd(decNumber *dn);
397 
398     void copyBcdFrom(const DecimalQuantity &other);
399 
400     /**
401      * Removes trailing zeros from the BCD (adjusting the scale as required) and then computes the
402      * precision. The precision is the number of digits in the number up through the greatest nonzero
403      * digit.
404      *
405      * <p>This method must always be called when bcd changes in order for assumptions to be correct in
406      * methods like {@link #fractionCount()}.
407      */
408     void compact();
409 
410     void _setToInt(int32_t n);
411 
412     void _setToLong(int64_t n);
413 
414     void _setToDoubleFast(double n);
415 
416     void _setToDecNumber(decNumber *n);
417 
418     void convertToAccurateDouble();
419 
420     double toDoubleFromOriginal() const;
421 
422     /** Ensure that a byte array of at least 40 digits is allocated. */
423     void ensureCapacity();
424 
425     void ensureCapacity(int32_t capacity);
426 
427     /** Switches the internal storage mechanism between the 64-bit long and the byte array. */
428     void switchStorage();
429 };
430 
431 } // namespace impl
432 } // namespace number
433 U_NAMESPACE_END
434 
435 
436 #endif //__NUMBER_DECIMALQUANTITY_H__
437 
438 #endif /* #if !UCONFIG_NO_FORMATTING */
439