]>
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 fArbitrary
= src
.fArbitrary
;
70 // Take ownership away from src if necessary
71 src
.fArbitrary
= nullptr;
84 Scale
Scale::powerOfTen(int32_t power
) {
85 return {power
, nullptr};
88 Scale
Scale::byDecimal(StringPiece multiplicand
) {
89 UErrorCode localError
= U_ZERO_ERROR
;
90 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
91 if (U_FAILURE(localError
)) {
94 decnum
->setTo(multiplicand
, localError
);
95 if (U_FAILURE(localError
)) {
98 return {0, decnum
.orphan()};
101 Scale
Scale::byDouble(double multiplicand
) {
102 UErrorCode localError
= U_ZERO_ERROR
;
103 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
104 if (U_FAILURE(localError
)) {
107 decnum
->setTo(multiplicand
, localError
);
108 if (U_FAILURE(localError
)) {
111 return {0, decnum
.orphan()};
114 Scale
Scale::byDoubleAndPowerOfTen(double multiplicand
, int32_t power
) {
115 UErrorCode localError
= U_ZERO_ERROR
;
116 LocalPointer
<DecNum
> decnum(new DecNum(), localError
);
117 if (U_FAILURE(localError
)) {
120 decnum
->setTo(multiplicand
, localError
);
121 if (U_FAILURE(localError
)) {
124 return {power
, decnum
.orphan()};
127 void Scale::applyTo(impl::DecimalQuantity
& quantity
) const {
128 quantity
.adjustMagnitude(fMagnitude
);
129 if (fArbitrary
!= nullptr) {
130 UErrorCode localStatus
= U_ZERO_ERROR
;
131 quantity
.multiplyBy(*fArbitrary
, localStatus
);
135 void Scale::applyReciprocalTo(impl::DecimalQuantity
& quantity
) const {
136 quantity
.adjustMagnitude(-fMagnitude
);
137 if (fArbitrary
!= nullptr) {
138 UErrorCode localStatus
= U_ZERO_ERROR
;
139 quantity
.divideBy(*fArbitrary
, localStatus
);
145 MultiplierFormatHandler::setAndChain(const Scale
& multiplier
, const MicroPropsGenerator
* parent
) {
146 this->multiplier
= multiplier
;
147 this->parent
= parent
;
150 void MultiplierFormatHandler::processQuantity(DecimalQuantity
& quantity
, MicroProps
& micros
,
151 UErrorCode
& status
) const {
152 parent
->processQuantity(quantity
, micros
, status
);
153 multiplier
.applyTo(quantity
);
156 #endif /* #if !UCONFIG_NO_FORMATTING */