1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2018 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 package ohos.global.icu.number; 5 6 import java.math.BigDecimal; 7 import java.math.BigInteger; 8 import java.math.MathContext; 9 10 import ohos.global.icu.impl.number.DecimalQuantity; 11 import ohos.global.icu.impl.number.RoundingUtils; 12 13 /** 14 * A class that defines a quantity by which a number should be multiplied when formatting. 15 * 16 * <p> 17 * To create a Multiplier, use one of the factory methods. 18 * 19 * @see NumberFormatter 20 * @hide exposed on OHOS 21 */ 22 public class Scale { 23 24 private static final Scale DEFAULT = new Scale(0, null); 25 private static final Scale HUNDRED = new Scale(2, null); 26 private static final Scale THOUSAND = new Scale(3, null); 27 28 private static final BigDecimal BIG_DECIMAL_100 = BigDecimal.valueOf(100); 29 private static final BigDecimal BIG_DECIMAL_1000 = BigDecimal.valueOf(1000); 30 31 final int magnitude; 32 final BigDecimal arbitrary; 33 final BigDecimal reciprocal; 34 final MathContext mc; 35 Scale(int magnitude, BigDecimal arbitrary)36 private Scale(int magnitude, BigDecimal arbitrary) { 37 this(magnitude, arbitrary, RoundingUtils.DEFAULT_MATH_CONTEXT_34_DIGITS); 38 } 39 Scale(int magnitude, BigDecimal arbitrary, MathContext mc)40 private Scale(int magnitude, BigDecimal arbitrary, MathContext mc) { 41 if (arbitrary != null) { 42 // Attempt to convert the BigDecimal to a magnitude multiplier. 43 // ICU-20000: JDKs have inconsistent behavior on stripTrailingZeros() for Zero. 44 arbitrary = 45 arbitrary.compareTo(BigDecimal.ZERO) == 0 46 ? BigDecimal.ZERO 47 : arbitrary.stripTrailingZeros(); 48 if (arbitrary.precision() == 1 && arbitrary.unscaledValue().equals(BigInteger.ONE)) { 49 // Success! 50 magnitude -= arbitrary.scale(); 51 arbitrary = null; 52 } 53 } 54 55 this.magnitude = magnitude; 56 this.arbitrary = arbitrary; 57 this.mc = mc; 58 // We need to use a math context in order to prevent non-terminating decimal expansions. 59 // This is only used when dividing by the multiplier. 60 if (arbitrary != null && BigDecimal.ZERO.compareTo(arbitrary) != 0) { 61 this.reciprocal = BigDecimal.ONE.divide(arbitrary, mc); 62 } else { 63 this.reciprocal = null; 64 } 65 } 66 67 /** 68 * Do not change the value of numbers when formatting or parsing. 69 * 70 * @return A Multiplier to prevent any multiplication. 71 * @see NumberFormatter 72 */ none()73 public static Scale none() { 74 return DEFAULT; 75 } 76 77 /** 78 * Multiply numbers by 100 before formatting. Useful for combining with a percent unit: 79 * 80 * <pre> 81 * NumberFormatter.with().unit(NoUnit.PERCENT).multiplier(Multiplier.powerOfTen(2)) 82 * </pre> 83 * 84 * @return A Multiplier for passing to the setter in NumberFormatter. 85 * @see NumberFormatter 86 */ powerOfTen(int power)87 public static Scale powerOfTen(int power) { 88 if (power == 0) { 89 return DEFAULT; 90 } else if (power == 2) { 91 return HUNDRED; 92 } else if (power == 3) { 93 return THOUSAND; 94 } else { 95 return new Scale(power, null); 96 } 97 } 98 99 /** 100 * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. 101 * <p> 102 * This method takes a BigDecimal; also see the version that takes a double. 103 * 104 * @return A Multiplier for passing to the setter in NumberFormatter. 105 * @see NumberFormatter 106 */ byBigDecimal(BigDecimal multiplicand)107 public static Scale byBigDecimal(BigDecimal multiplicand) { 108 if (multiplicand.compareTo(BigDecimal.ONE) == 0) { 109 return DEFAULT; 110 } else if (multiplicand.compareTo(BIG_DECIMAL_100) == 0) { 111 return HUNDRED; 112 } else if (multiplicand.compareTo(BIG_DECIMAL_1000) == 0) { 113 return THOUSAND; 114 } else { 115 return new Scale(0, multiplicand); 116 } 117 } 118 119 /** 120 * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. 121 * <p> 122 * This method takes a double; also see the version that takes a BigDecimal. 123 * 124 * @return A Multiplier for passing to the setter in NumberFormatter. 125 * @see NumberFormatter 126 */ byDouble(double multiplicand)127 public static Scale byDouble(double multiplicand) { 128 if (multiplicand == 1) { 129 return DEFAULT; 130 } else if (multiplicand == 100.0) { 131 return HUNDRED; 132 } else if (multiplicand == 1000.0) { 133 return THOUSAND; 134 } else { 135 return new Scale(0, BigDecimal.valueOf(multiplicand)); 136 } 137 } 138 139 /** 140 * Multiply a number by both a power of ten and by an arbitrary double value before formatting. 141 * 142 * @return A Multiplier for passing to the setter in NumberFormatter. 143 * @see NumberFormatter 144 */ byDoubleAndPowerOfTen(double multiplicand, int power)145 public static Scale byDoubleAndPowerOfTen(double multiplicand, int power) { 146 return new Scale(power, BigDecimal.valueOf(multiplicand)); 147 } 148 149 /** 150 * Returns whether the multiplier will change the number. 151 */ isValid()152 boolean isValid() { 153 return magnitude != 0 || arbitrary != null; 154 } 155 156 /** 157 * @deprecated ICU 62 This API is ICU internal only. 158 * @hide draft / provisional / internal are hidden on OHOS 159 */ 160 @Deprecated withMathContext(MathContext mc)161 public Scale withMathContext(MathContext mc) { 162 // TODO: Make this public? 163 if (this.mc.equals(mc)) { 164 return this; 165 } 166 return new Scale(magnitude, arbitrary, mc); 167 } 168 169 /** 170 * @deprecated ICU 62 This API is ICU internal only. 171 * @hide draft / provisional / internal are hidden on OHOS 172 */ 173 @Deprecated applyTo(DecimalQuantity quantity)174 public void applyTo(DecimalQuantity quantity) { 175 quantity.adjustMagnitude(magnitude); 176 if (arbitrary != null) { 177 quantity.multiplyBy(arbitrary); 178 } 179 } 180 181 /** 182 * @deprecated ICU 62 This API is ICU internal only. 183 * @hide draft / provisional / internal are hidden on OHOS 184 */ 185 @Deprecated applyReciprocalTo(DecimalQuantity quantity)186 public void applyReciprocalTo(DecimalQuantity quantity) { 187 quantity.adjustMagnitude(-magnitude); 188 if (reciprocal != null) { 189 quantity.multiplyBy(reciprocal); 190 quantity.roundToMagnitude(quantity.getMagnitude() - mc.getPrecision(), mc); 191 } 192 } 193 194 } 195