number_multiplier.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // © 2018 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. // Allow implicit conversion from char16_t* to UnicodeString for this file:
  6. // Helpful in toString methods and elsewhere.
  7. #define UNISTR_FROM_STRING_EXPLICIT
  8. #include "number_decnum.h"
  9. #include "number_types.h"
  10. #include "number_multiplier.h"
  11. #include "numparse_validators.h"
  12. #include "number_utils.h"
  13. #include "decNumber.h"
  14. using namespace icu;
  15. using namespace icu::number;
  16. using namespace icu::number::impl;
  17. using namespace icu::numparse::impl;
  18. Scale::Scale(int32_t magnitude, DecNum* arbitraryToAdopt)
  19. : fMagnitude(magnitude), fArbitrary(arbitraryToAdopt), fError(U_ZERO_ERROR) {
  20. if (fArbitrary != nullptr) {
  21. // Attempt to convert the DecNum to a magnitude multiplier.
  22. fArbitrary->normalize();
  23. if (fArbitrary->getRawDecNumber()->digits == 1 && fArbitrary->getRawDecNumber()->lsu[0] == 1 &&
  24. !fArbitrary->isNegative()) {
  25. // Success!
  26. fMagnitude += fArbitrary->getRawDecNumber()->exponent;
  27. delete fArbitrary;
  28. fArbitrary = nullptr;
  29. }
  30. }
  31. }
  32. Scale::Scale(const Scale& other)
  33. : fMagnitude(other.fMagnitude), fArbitrary(nullptr), fError(other.fError) {
  34. if (other.fArbitrary != nullptr) {
  35. UErrorCode localStatus = U_ZERO_ERROR;
  36. fArbitrary = new DecNum(*other.fArbitrary, localStatus);
  37. }
  38. }
  39. Scale& Scale::operator=(const Scale& other) {
  40. if (this == &other) { return *this; } // self-assignment: no-op
  41. fMagnitude = other.fMagnitude;
  42. if (other.fArbitrary != nullptr) {
  43. UErrorCode localStatus = U_ZERO_ERROR;
  44. fArbitrary = new DecNum(*other.fArbitrary, localStatus);
  45. } else {
  46. fArbitrary = nullptr;
  47. }
  48. fError = other.fError;
  49. return *this;
  50. }
  51. Scale::Scale(Scale&& src) noexcept
  52. : fMagnitude(src.fMagnitude), fArbitrary(src.fArbitrary), fError(src.fError) {
  53. // Take ownership away from src if necessary
  54. src.fArbitrary = nullptr;
  55. }
  56. Scale& Scale::operator=(Scale&& src) noexcept {
  57. fMagnitude = src.fMagnitude;
  58. if (fArbitrary != nullptr) {
  59. delete fArbitrary;
  60. }
  61. fArbitrary = src.fArbitrary;
  62. fError = src.fError;
  63. // Take ownership away from src if necessary
  64. src.fArbitrary = nullptr;
  65. return *this;
  66. }
  67. Scale::~Scale() {
  68. delete fArbitrary;
  69. }
  70. Scale Scale::none() {
  71. return {0, nullptr};
  72. }
  73. Scale Scale::powerOfTen(int32_t power) {
  74. return {power, nullptr};
  75. }
  76. Scale Scale::byDecimal(StringPiece multiplicand) {
  77. UErrorCode localError = U_ZERO_ERROR;
  78. LocalPointer<DecNum> decnum(new DecNum(), localError);
  79. if (U_FAILURE(localError)) {
  80. return {localError};
  81. }
  82. decnum->setTo(multiplicand, localError);
  83. if (U_FAILURE(localError)) {
  84. return {localError};
  85. }
  86. return {0, decnum.orphan()};
  87. }
  88. Scale Scale::byDouble(double multiplicand) {
  89. UErrorCode localError = U_ZERO_ERROR;
  90. LocalPointer<DecNum> decnum(new DecNum(), localError);
  91. if (U_FAILURE(localError)) {
  92. return {localError};
  93. }
  94. decnum->setTo(multiplicand, localError);
  95. if (U_FAILURE(localError)) {
  96. return {localError};
  97. }
  98. return {0, decnum.orphan()};
  99. }
  100. Scale Scale::byDoubleAndPowerOfTen(double multiplicand, int32_t power) {
  101. UErrorCode localError = U_ZERO_ERROR;
  102. LocalPointer<DecNum> decnum(new DecNum(), localError);
  103. if (U_FAILURE(localError)) {
  104. return {localError};
  105. }
  106. decnum->setTo(multiplicand, localError);
  107. if (U_FAILURE(localError)) {
  108. return {localError};
  109. }
  110. return {power, decnum.orphan()};
  111. }
  112. void Scale::applyTo(impl::DecimalQuantity& quantity) const {
  113. quantity.adjustMagnitude(fMagnitude);
  114. if (fArbitrary != nullptr) {
  115. UErrorCode localStatus = U_ZERO_ERROR;
  116. quantity.multiplyBy(*fArbitrary, localStatus);
  117. }
  118. }
  119. void Scale::applyReciprocalTo(impl::DecimalQuantity& quantity) const {
  120. quantity.adjustMagnitude(-fMagnitude);
  121. if (fArbitrary != nullptr) {
  122. UErrorCode localStatus = U_ZERO_ERROR;
  123. quantity.divideBy(*fArbitrary, localStatus);
  124. }
  125. }
  126. void
  127. MultiplierFormatHandler::setAndChain(const Scale& multiplier, const MicroPropsGenerator* parent) {
  128. fMultiplier = multiplier;
  129. fParent = parent;
  130. }
  131. void MultiplierFormatHandler::processQuantity(DecimalQuantity& quantity, MicroProps& micros,
  132. UErrorCode& status) const {
  133. fParent->processQuantity(quantity, micros, status);
  134. fMultiplier.applyTo(quantity);
  135. }
  136. #endif /* #if !UCONFIG_NO_FORMATTING */