]>
git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/number_multiplier.cpp
1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 #include "unicode/utypes.h"
6 #if !UCONFIG_NO_FORMATTING
8 // Allow implicit conversion from char16_t* to UnicodeString for this file:
9 // Helpful in toString methods and elsewhere.
10 #define UNISTR_FROM_STRING_EXPLICIT
12 #include "number_decnum.h"
13 #include "number_types.h"
14 #include "number_multiplier.h"
15 #include "numparse_validators.h"
16 #include "number_utils.h"
17 #include "decNumber.h"
20 using namespace icu::number
;
21 using namespace icu::number::impl
;
22 using namespace icu::numparse::impl
;
25 Scale::Scale(int32_t magnitude
, DecNum
* arbitraryToAdopt
)
26 : fMagnitude(magnitude
), fArbitrary(arbitraryToAdopt
), fError(U_ZERO_ERROR
) {
27 if (fArbitrary
!= nullptr) {
28 // Attempt to convert the DecNum to a magnitude multiplier.
29 fArbitrary
->normalize();
30 if (fArbitrary
->getRawDecNumber()->digits
== 1 && fArbitrary
->getRawDecNumber()->lsu
[0] == 1 &&
31 !fArbitrary
->isNegative()) {
33 fMagnitude
+= fArbitrary
->getRawDecNumber()->exponent
;
40 Scale::Scale(const Scale
& other
)
41 : fMagnitude(other
.fMagnitude
), fArbitrary(nullptr), fError(other
.fError
) {
42 if (other
.fArbitrary
!= nullptr) {
43 UErrorCode localStatus
= U_ZERO_ERROR
;
44 fArbitrary
= new DecNum(*other
.fArbitrary
, localStatus
);
48 Scale
& Scale::operator=(const Scale
& other
) {
49 fMagnitude
= other
.fMagnitude
;
50 if (other
.fArbitrary
!= nullptr) {
51 UErrorCode localStatus
= U_ZERO_ERROR
;
52 fArbitrary
= new DecNum(*other
.fArbitrary
, localStatus
);
56 fError
= other
.fError
;
60 Scale::Scale(Scale
&& src
) U_NOEXCEPT
61 : fMagnitude(src
.fMagnitude
), fArbitrary(src
.fArbitrary
), fError(src
.fError
) {
62 // Take ownership away from src if necessary
63 src
.fArbitrary
= nullptr;
66 Scale
& Scale::operator=(Scale
&& src
) U_NOEXCEPT
{
67 fMagnitude
= src
.fMagnitude
;
68 if (fArbitrary
!= nullptr) {
71 fArbitrary
= src
.fArbitrary
;
73 // Take ownership away from src if necessary
74 src
.fArbitrary
= nullptr;
87 Scale
Scale::powerOfTen(int32_t power
) {
88 return {power
, nullptr};
91 Scale
Scale::byDecimal(StringPiece multiplicand
) {
92 UErrorCode localError
= U_ZERO_ERROR
;
93 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
94 if (U_FAILURE(localError
)) {
97 decnum
->setTo(multiplicand
, localError
);
98 if (U_FAILURE(localError
)) {
101 return {0, decnum
.orphan()};
104 Scale
Scale::byDouble(double multiplicand
) {
105 UErrorCode localError
= U_ZERO_ERROR
;
106 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
107 if (U_FAILURE(localError
)) {
110 decnum
->setTo(multiplicand
, localError
);
111 if (U_FAILURE(localError
)) {
114 return {0, decnum
.orphan()};
117 Scale
Scale::byDoubleAndPowerOfTen(double multiplicand
, int32_t power
) {
118 UErrorCode localError
= U_ZERO_ERROR
;
119 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
120 if (U_FAILURE(localError
)) {
123 decnum
->setTo(multiplicand
, localError
);
124 if (U_FAILURE(localError
)) {
127 return {power
, decnum
.orphan()};
130 void Scale::applyTo(impl::DecimalQuantity
& quantity
) const {
131 quantity
.adjustMagnitude(fMagnitude
);
132 if (fArbitrary
!= nullptr) {
133 UErrorCode localStatus
= U_ZERO_ERROR
;
134 quantity
.multiplyBy(*fArbitrary
, localStatus
);
138 void Scale::applyReciprocalTo(impl::DecimalQuantity
& quantity
) const {
139 quantity
.adjustMagnitude(-fMagnitude
);
140 if (fArbitrary
!= nullptr) {
141 UErrorCode localStatus
= U_ZERO_ERROR
;
142 quantity
.divideBy(*fArbitrary
, localStatus
);
148 MultiplierFormatHandler::setAndChain(const Scale
& multiplier
, const MicroPropsGenerator
* parent
) {
149 fMultiplier
= multiplier
;
153 void MultiplierFormatHandler::processQuantity(DecimalQuantity
& quantity
, MicroProps
& micros
,
154 UErrorCode
& status
) const {
155 fParent
->processQuantity(quantity
, micros
, status
);
156 fMultiplier
.applyTo(quantity
);
159 #endif /* #if !UCONFIG_NO_FORMATTING */