number_decimalquantity.h 19 KB

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