1 // © 2017 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 package com.ibm.icu.impl.number; 4 5 import java.math.BigDecimal; 6 import java.math.MathContext; 7 import java.text.FieldPosition; 8 9 import com.ibm.icu.impl.StandardPlural; 10 import com.ibm.icu.impl.number.Modifier.Signum; 11 import com.ibm.icu.text.PluralRules; 12 import com.ibm.icu.text.UFieldPosition; 13 14 /** 15 * An interface representing a number to be processed by the decimal formatting pipeline. Includes 16 * methods for rounding, plural rules, and decimal digit extraction. 17 * 18 * <p> 19 * By design, this is NOT IMMUTABLE and NOT THREAD SAFE. It is intended to be an intermediate object 20 * holding state during a pass through the decimal formatting pipeline. 21 * 22 * <p> 23 * Implementations of this interface are free to use any internal storage mechanism. 24 * 25 * <p> 26 * TODO: Should I change this to an abstract class so that logic for min/max digits doesn't need to be 27 * copied to every implementation? 28 */ 29 public interface DecimalQuantity extends PluralRules.IFixedDecimal { 30 /** 31 * Sets the minimum integer digits that this {@link DecimalQuantity} should generate. 32 * This method does not perform rounding. 33 * 34 * @param minInt 35 * The minimum number of integer digits. 36 */ setMinInteger(int minInt)37 public void setMinInteger(int minInt); 38 39 /** 40 * Sets the minimum fraction digits that this {@link DecimalQuantity} should generate. 41 * This method does not perform rounding. 42 * 43 * @param minFrac 44 * The minimum number of fraction digits. 45 */ setMinFraction(int minFrac)46 public void setMinFraction(int minFrac); 47 48 /** 49 * Truncates digits from the upper magnitude of the number in order to satisfy the 50 * specified maximum number of integer digits. 51 * 52 * @param maxInt 53 * The maximum number of integer digits. 54 */ applyMaxInteger(int maxInt)55 public void applyMaxInteger(int maxInt); 56 57 /** 58 * Rounds the number to a specified interval, such as 0.05. 59 * 60 * <p> 61 * If rounding to a power of ten, use the more efficient {@link #roundToMagnitude} instead. 62 * 63 * @param roundingInterval 64 * The increment to which to round. 65 * @param mathContext 66 * The {@link MathContext} to use if rounding is necessary. Undefined behavior if null. 67 */ roundToIncrement(BigDecimal roundingInterval, MathContext mathContext)68 public void roundToIncrement(BigDecimal roundingInterval, MathContext mathContext); 69 70 /** 71 * Rounds the number to the nearest multiple of 5 at the specified magnitude. 72 * For example, when magnitude == -2, this performs rounding to the nearest 0.05. 73 * 74 * @param magnitude 75 * The magnitude at which the digit should become either 0 or 5. 76 * @param mathContext 77 * Rounding strategy. 78 */ roundToNickel(int magnitude, MathContext mathContext)79 public void roundToNickel(int magnitude, MathContext mathContext); 80 81 /** 82 * Rounds the number to a specified magnitude (power of ten). 83 * 84 * @param roundingMagnitude 85 * The power of ten to which to round. For example, a value of -2 will round to 2 decimal 86 * places. 87 * @param mathContext 88 * The {@link MathContext} to use if rounding is necessary. Undefined behavior if null. 89 */ roundToMagnitude(int roundingMagnitude, MathContext mathContext)90 public void roundToMagnitude(int roundingMagnitude, MathContext mathContext); 91 92 /** 93 * Rounds the number to an infinite number of decimal points. This has no effect except for forcing 94 * the double in {@link DecimalQuantity_AbstractBCD} to adopt its exact representation. 95 */ roundToInfinity()96 public void roundToInfinity(); 97 98 /** 99 * Multiply the internal value. 100 * 101 * @param multiplicand 102 * The value by which to multiply. 103 */ multiplyBy(BigDecimal multiplicand)104 public void multiplyBy(BigDecimal multiplicand); 105 106 /** Flips the sign from positive to negative and back. */ negate()107 void negate(); 108 109 /** 110 * Scales the number by a power of ten. For example, if the value is currently "1234.56", calling 111 * this method with delta=-3 will change the value to "1.23456". 112 * 113 * @param delta 114 * The number of magnitudes of ten to change by. 115 */ adjustMagnitude(int delta)116 public void adjustMagnitude(int delta); 117 118 /** 119 * @return The power of ten corresponding to the most significant nonzero digit. 120 * @throws ArithmeticException 121 * If the value represented is zero. 122 */ getMagnitude()123 public int getMagnitude() throws ArithmeticException; 124 125 /** 126 * @return The value of the (suppressed) exponent after the number has been 127 * put into a notation with exponents (ex: compact, scientific). Ex: given 128 * the number 1000 as "1K" / "1E3", the return value will be 3 (positive). 129 */ getExponent()130 public int getExponent(); 131 132 /** 133 * Adjusts the value for the (suppressed) exponent stored when using 134 * notation with exponents (ex: compact, scientific). 135 * 136 * <p>Adjusting the exponent is decoupled from {@link #adjustMagnitude} in 137 * order to allow flexibility for {@link StandardPlural} to be selected in 138 * formatting (ex: for compact notation) either with or without the exponent 139 * applied in the value of the number. 140 * @param delta 141 * The value to adjust the exponent by. 142 */ adjustExponent(int delta)143 public void adjustExponent(int delta); 144 145 /** 146 * Resets the DecimalQuantity to the value before adjustMagnitude and adjustExponent. 147 */ resetExponent()148 public void resetExponent(); 149 150 /** 151 * @return Whether the value represented by this {@link DecimalQuantity} is 152 * zero, infinity, or NaN. 153 */ isZeroish()154 public boolean isZeroish(); 155 156 /** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */ isNegative()157 public boolean isNegative(); 158 159 /** @return The appropriate value from the Signum enum. */ signum()160 public Signum signum(); 161 162 /** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */ 163 @Override isInfinite()164 public boolean isInfinite(); 165 166 /** @return Whether the value represented by this {@link DecimalQuantity} is not a number. */ 167 @Override isNaN()168 public boolean isNaN(); 169 170 /** @return The value contained in this {@link DecimalQuantity} approximated as a double. */ toDouble()171 public double toDouble(); 172 toBigDecimal()173 public BigDecimal toBigDecimal(); 174 175 /** 176 * Returns a long approximating the decimal quantity. A long can only represent the 177 * integral part of the number. Note: this method incorporates the value of 178 * {@code getExponent} (for cases such as compact notation) to return the proper long 179 * value represented by the result. 180 * 181 * @param truncateIfOverflow if false and the number does NOT fit, fails with an error. 182 * See comment about call site guards in DecimalQuantity_AbstractBCD.java 183 * @return A 64-bit integer representation of the internal number. 184 */ toLong(boolean truncateIfOverflow)185 public long toLong(boolean truncateIfOverflow); 186 setToBigDecimal(BigDecimal input)187 public void setToBigDecimal(BigDecimal input); 188 maxRepresentableDigits()189 public int maxRepresentableDigits(); 190 191 // TODO: Should this method be removed, since DecimalQuantity implements IFixedDecimal now? 192 /** 193 * Computes the plural form for this number based on the specified set of rules. 194 * 195 * @param rules 196 * A {@link PluralRules} object representing the set of rules. 197 * @return The {@link StandardPlural} according to the PluralRules. If the plural form is not in the 198 * set of standard plurals, {@link StandardPlural#OTHER} is returned instead. 199 */ getStandardPlural(PluralRules rules)200 public StandardPlural getStandardPlural(PluralRules rules); 201 202 /** 203 * Gets the digit at the specified magnitude. For example, if the represented number is 12.3, 204 * getDigit(-1) returns 3, since 3 is the digit corresponding to 10^-1. 205 * 206 * @param magnitude 207 * The magnitude of the digit. 208 * @return The digit at the specified magnitude. 209 */ getDigit(int magnitude)210 public byte getDigit(int magnitude); 211 212 /** 213 * Gets the largest power of ten that needs to be displayed. The value returned by this function will 214 * be bounded between minInt and maxInt. 215 * 216 * @return The highest-magnitude digit to be displayed. 217 */ getUpperDisplayMagnitude()218 public int getUpperDisplayMagnitude(); 219 220 /** 221 * Gets the smallest power of ten that needs to be displayed. The value returned by this function 222 * will be bounded between -minFrac and -maxFrac. 223 * 224 * @return The lowest-magnitude digit to be displayed. 225 */ getLowerDisplayMagnitude()226 public int getLowerDisplayMagnitude(); 227 228 /** 229 * Returns the string in "plain" format (no exponential notation) using ASCII digits. 230 */ toPlainString()231 public String toPlainString(); 232 233 /** 234 * Returns the string using ASCII digits and using exponential notation for non-zero 235 * exponents, following the UTS 35 specification for plural rule samples. 236 */ toExponentString()237 public String toExponentString(); 238 239 /** 240 * Like clone, but without the restrictions of the Cloneable interface clone. 241 * 242 * @return A copy of this instance which can be mutated without affecting this instance. 243 */ createCopy()244 public DecimalQuantity createCopy(); 245 246 /** 247 * Sets this instance to be equal to another instance. 248 * 249 * @param other 250 * The instance to copy from. 251 */ copyFrom(DecimalQuantity other)252 public void copyFrom(DecimalQuantity other); 253 254 /** This method is for internal testing only. */ getPositionFingerprint()255 public long getPositionFingerprint(); 256 257 /** 258 * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction 259 * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing happens. 260 * 261 * @param fp 262 * The {@link UFieldPosition} to populate. 263 */ populateUFieldPosition(FieldPosition fp)264 public void populateUFieldPosition(FieldPosition fp); 265 } 266