1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */ 5 /* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */ 6 package android.icu.math; 7 8 import java.math.BigInteger; 9 10 import android.icu.lang.UCharacter; 11 12 /* ------------------------------------------------------------------ */ 13 /* BigDecimal -- Decimal arithmetic for Java */ 14 /* ------------------------------------------------------------------ */ 15 /* Copyright IBM Corporation, 1996-2016. All Rights Reserved. */ 16 /* */ 17 /* The BigDecimal class provides immutable arbitrary-precision */ 18 /* floating point (including integer) decimal numbers. */ 19 /* */ 20 /* As the numbers are decimal, there is an exact correspondence */ 21 /* between an instance of a BigDecimal object and its String */ 22 /* representation; the BigDecimal class provides direct conversions */ 23 /* to and from String and character array objects, and well as */ 24 /* conversions to and from the Java primitive types (which may not */ 25 /* be exact). */ 26 /* ------------------------------------------------------------------ */ 27 /* Notes: */ 28 /* */ 29 /* 1. A BigDecimal object is never changed in value once constructed; */ 30 /* this avoids the need for locking. Note in particular that the */ 31 /* mantissa array may be shared between many BigDecimal objects, */ 32 /* so that once exposed it must not be altered. */ 33 /* */ 34 /* 2. This class looks at MathContext class fields directly (for */ 35 /* performance). It must not and does not change them. */ 36 /* */ 37 /* 3. Exponent checking is delayed until finish(), as we know */ 38 /* intermediate calculations cannot cause 31-bit overflow. */ 39 /* [This assertion depends on MAX_DIGITS in MathContext.] */ 40 /* */ 41 /* 4. Comments for the public API now follow the javadoc conventions. */ 42 /* The NetRexx -comments option is used to pass these comments */ 43 /* through to the generated Java code (with -format, if desired). */ 44 /* */ 45 /* 5. System.arraycopy is faster than explicit loop as follows */ 46 /* Mean length 4: equal */ 47 /* Mean length 8: x2 */ 48 /* Mean length 16: x3 */ 49 /* Mean length 24: x4 */ 50 /* From prior experience, we expect mean length a little below 8, */ 51 /* but arraycopy is still the one to use, in general, until later */ 52 /* measurements suggest otherwise. */ 53 /* */ 54 /* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */ 55 /* assembler code implementation of the algorithms below; it is */ 56 /* now called IXXRCN and is available with the OS/390 and VM/ESA */ 57 /* operating systems. */ 58 /* ------------------------------------------------------------------ */ 59 /* Change History: */ 60 /* 1997.09.02 Initial version (derived from netrexx.lang classes) */ 61 /* 1997.09.12 Add lostDigits checking */ 62 /* 1997.10.06 Change mantissa to a byte array */ 63 /* 1997.11.22 Rework power [did not prepare arguments, etc.] */ 64 /* 1997.12.13 multiply did not prepare arguments */ 65 /* 1997.12.14 add did not prepare and align arguments correctly */ 66 /* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */ 67 /* 1998.05.21 adjust remainder operator finalization */ 68 /* 1998.06.04 rework to pass MathContext to finish() and round() */ 69 /* 1998.06.06 change format to use round(); support rounding modes */ 70 /* 1998.06.25 rename to BigDecimal and begin merge */ 71 /* zero can now have trailing zeros (i.e., exp\=0) */ 72 /* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */ 73 /* unscaledValue, valueof */ 74 /* 1998.07.01 improve byteaddsub to allow array reuse, etc. */ 75 /* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */ 76 /* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */ 77 /* 1998.07.08 setScale, faster equals */ 78 /* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */ 79 /* 1998.10.12 change package to android.icu.math */ 80 /* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */ 81 /* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */ 82 /* 1998.12.29 improve byteaddsub by using table lookup */ 83 /* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */ 84 /* 1999.02.05 cleaner code for BigDecimal(char[]) */ 85 /* 1999.02.06 add javadoc comments */ 86 /* 1999.02.11 format() changed from 7 to 2 method form */ 87 /* 1999.03.05 null pointer checking is no longer explicit */ 88 /* 1999.03.05 simplify; changes from discussion with J. Bloch: */ 89 /* null no longer permitted for MathContext; drop boolean, */ 90 /* byte, char, float, short constructor, deprecate double */ 91 /* constructor, no blanks in string constructor, add */ 92 /* offset and length version of char[] constructor; */ 93 /* add valueOf(double); drop booleanValue, charValue; */ 94 /* add ...Exact versions of remaining convertors */ 95 /* 1999.03.13 add toBigIntegerExact */ 96 /* 1999.03.13 1.00 release to IBM Centre for Java Technology */ 97 /* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */ 98 /* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */ 99 /* 1999.07.03 1.03 lost digits should not be checked if digits=0 */ 100 /* 1999.07.06 lost digits Exception message changed */ 101 /* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */ 102 /* 1999.07.17 improve messages from pow method */ 103 /* 1999.08.08 performance tweaks */ 104 /* 1999.08.15 fastpath in multiply */ 105 /* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */ 106 /* 1999.12.22 1.06 remove multiply fastpath, and improve performance */ 107 /* 2000.01.01 copyright update [Y2K has arrived] */ 108 /* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */ 109 /* ------------------------------------------------------------------ */ 110 111 /** 112 * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the 113 * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format 114 * conversions, and hashing. 115 * <p> 116 * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object 117 * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from 118 * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java 119 * primitive types (which may not be exact) and <code>BigInteger</code>. 120 * <p> 121 * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number 122 * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal 123 * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any 124 * operation. 125 * <p> 126 * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also 127 * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br> 128 * <i>[This URL will change.]</i> 129 * 130 * <h3>Operator methods</h3> 131 * <p> 132 * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the 133 * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code> 134 * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as 135 * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9, 136 * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point 137 * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>. 138 * <p> 139 * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this 140 * version of each method, the context settings used are <code>digits=0, 141 * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with 142 * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2. 143 * <p> 144 * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the 145 * current object. 146 * <p> 147 * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The 148 * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being 149 * the right-hand operand. 150 * <p> 151 * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and 152 * <code>extra</code> could be written as any of: 153 * <p> 154 * <code> 155 * award.add(extra) 156 * <br>award.add(extra, MathContext.DEFAULT) 157 * <br>award.add(extra, acontext) 158 * </code> 159 * <p> 160 * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code> 161 * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context 162 * settings. 163 * <p> 164 * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by 165 * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal 166 * arithmetic documentation (see the URL above), but in summary: 167 * <ul> 168 * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the 169 * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be 170 * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br> 171 * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code> 172 * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled) 173 * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code> 174 * parameter). <br> 175 * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm. 176 * <li> 177 * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is 178 * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part). 179 * <li> 180 * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast 181 * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros 182 * in the fractional part of results). <br> 183 * So, for example: 184 * <p> 185 * <code> 186 * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40" 187 * <br>new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40" 188 * <br>new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80" 189 * <br>new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2" 190 * </code> 191 * <p> 192 * where the value on the right of the <code>=></code> would be the result of the operation, expressed as a 193 * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code> 194 * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If 195 * necessary, trailing zeros may be easily removed using division by 1. 196 * <li> 197 * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of 198 * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the 199 * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number 200 * will be expressed in exponential notation; thus 201 * <p> 202 * <code> 203 * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def) 204 * </code> 205 * <p> 206 * results in <code>1E+12</code> instead of <code>1000000000000</code>, and 207 * <p> 208 * <code> 209 * new BigDecimal("1").divide(new BigDecimal("3E+10"), def) 210 * </code> 211 * <p> 212 * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>. 213 * <p> 214 * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting. 215 * </ul> 216 * <p> 217 * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>, 218 * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2. 219 * 220 * @see MathContext 221 * @author Mike Cowlishaw 222 */ 223 224 public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> { 225 // private static final java.lang.String $0="BigDecimal.nrx"; 226 227 /* ----- Constants ----- */ 228 /* properties constant public */// useful to others 229 /** 230 * The <code>BigDecimal</code> constant "0". 231 * 232 * @see #ONE 233 * @see #TEN 234 */ 235 public static final android.icu.math.BigDecimal ZERO = new android.icu.math.BigDecimal((long) 0); // use long as we 236 // want the int 237 // constructor 238 // .. to be able to use this, for speed 239 240 /** 241 * The <code>BigDecimal</code> constant "1". 242 * 243 * @see #TEN 244 * @see #ZERO 245 */ 246 public static final android.icu.math.BigDecimal ONE = new android.icu.math.BigDecimal((long) 1); // use long as we 247 // want the int 248 // constructor 249 // .. to be able to use this, for speed 250 251 /** 252 * The <code>BigDecimal</code> constant "10". 253 * 254 * @see #ONE 255 * @see #ZERO 256 */ 257 public static final android.icu.math.BigDecimal TEN = new android.icu.math.BigDecimal(10); 258 259 // the rounding modes (copied here for upwards compatibility) 260 /** 261 * Rounding mode to round to a more positive number. 262 * 263 * @see MathContext#ROUND_CEILING 264 */ 265 public static final int ROUND_CEILING = android.icu.math.MathContext.ROUND_CEILING; 266 267 /** 268 * Rounding mode to round towards zero. 269 * 270 * @see MathContext#ROUND_DOWN 271 */ 272 public static final int ROUND_DOWN = android.icu.math.MathContext.ROUND_DOWN; 273 274 /** 275 * Rounding mode to round to a more negative number. 276 * 277 * @see MathContext#ROUND_FLOOR 278 */ 279 public static final int ROUND_FLOOR = android.icu.math.MathContext.ROUND_FLOOR; 280 281 /** 282 * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down. 283 * 284 * @see MathContext#ROUND_HALF_DOWN 285 */ 286 public static final int ROUND_HALF_DOWN = android.icu.math.MathContext.ROUND_HALF_DOWN; 287 288 /** 289 * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor. 290 * 291 * @see MathContext#ROUND_HALF_EVEN 292 */ 293 public static final int ROUND_HALF_EVEN = android.icu.math.MathContext.ROUND_HALF_EVEN; 294 295 /** 296 * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up. 297 * 298 * @see MathContext#ROUND_HALF_UP 299 */ 300 public static final int ROUND_HALF_UP = android.icu.math.MathContext.ROUND_HALF_UP; 301 302 /** 303 * Rounding mode to assert that no rounding is necessary. 304 * 305 * @see MathContext#ROUND_UNNECESSARY 306 */ 307 public static final int ROUND_UNNECESSARY = android.icu.math.MathContext.ROUND_UNNECESSARY; 308 309 /** 310 * Rounding mode to round away from zero. 311 * 312 * @see MathContext#ROUND_UP 313 */ 314 public static final int ROUND_UP = android.icu.math.MathContext.ROUND_UP; 315 316 /* properties constant private */// locals 317 private static final byte ispos = 1; // ind: indicates positive (must be 1) 318 private static final byte iszero = 0; // ind: indicates zero (must be 0) 319 private static final byte isneg = -1; // ind: indicates negative (must be -1) 320 // [later could add NaN, +/- infinity, here] 321 322 private static final int MinExp = -999999999; // minimum exponent allowed 323 private static final int MaxExp = 999999999; // maximum exponent allowed 324 private static final int MinArg = -999999999; // minimum argument integer 325 private static final int MaxArg = 999999999; // maximum argument integer 326 327 private static final android.icu.math.MathContext plainMC = new android.icu.math.MathContext(0, 328 android.icu.math.MathContext.PLAIN); // context for plain unlimited math 329 330 /* properties constant private unused */// present but not referenced 331 // Serialization version 332 private static final long serialVersionUID = 8245355804974198832L; 333 334 // private static final java.lang.String 335 // copyright=" Copyright (c) IBM Corporation 1996, 2000. All rights reserved. "; 336 337 /* properties static private */ 338 // Precalculated constant arrays (used by byteaddsub) 339 private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array 340 private static byte bytedig[] = diginit(); // next digit array 341 342 /* ----- Instance properties [all private and immutable] ----- */ 343 /* properties private */ 344 345 /** 346 * The indicator. This may take the values: 347 * <ul> 348 * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative 349 * </ul> 350 * 351 * @serial 352 */ 353 private byte ind; // assumed undefined 354 // Note: some code below assumes IND = Sign [-1, 0, 1], at present. 355 // We only need two bits for this, but use a byte [also permits 356 // smooth future extension]. 357 358 /** 359 * The formatting style. This may take the values: 360 * <ul> 361 * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li> 362 * MathContext.ENGINEERING -- engineering notation required 363 * </ul> 364 * <p> 365 * This property is an optimization; it allows us to defer number layout until it is actually needed as a string, 366 * hence avoiding unnecessary formatting. 367 * 368 * @serial 369 */ 370 private byte form = (byte) android.icu.math.MathContext.PLAIN; // assumed PLAIN 371 // We only need two bits for this, at present, but use a byte 372 // [again, to allow for smooth future extension] 373 374 /** 375 * The value of the mantissa. 376 * <p> 377 * Once constructed, this may become shared between several BigDecimal objects, so must not be altered. 378 * <p> 379 * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9. 380 * <p> 381 * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a 382 * plain number, for example, 0.000). 383 * 384 * @serial 385 */ 386 private byte mant[]; // assumed null 387 388 /** 389 * The exponent. 390 * <p> 391 * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero. 392 * 393 * Note that this property can have a value less than MinExp when the mantissa has more than one digit. 394 * 395 * @serial 396 */ 397 private int exp; 398 399 // assumed 0 400 401 /* ---------------------------------------------------------------- */ 402 /* Constructors */ 403 /* ---------------------------------------------------------------- */ 404 405 /** 406 * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>. 407 * <p> 408 * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using 409 * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. 410 * The parameter must not be <code>null</code>. 411 * <p> 412 * <i>(Note: this constructor is provided only in the <code>android.icu.math</code> version of the BigDecimal class. 413 * It would not be present in a <code>java.math</code> version.)</i> 414 * 415 * @param bd The <code>BigDecimal</code> to be translated. 416 */ 417 BigDecimal(java.math.BigDecimal bd)418 public BigDecimal(java.math.BigDecimal bd) { 419 this(bd.toString()); 420 return; 421 } 422 423 /** 424 * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code>, with scale 0. 425 * <p> 426 * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>, 427 * with a scale of zero. The value of the <code>BigDecimal</code> is identical to the value of the <code>BigInteger 428 * </code>. The parameter must not be <code>null</code>. 429 * <p> 430 * The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the 431 * <code>BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero. 432 * 433 * @param bi The <code>BigInteger</code> to be converted. 434 */ 435 BigDecimal(java.math.BigInteger bi)436 public BigDecimal(java.math.BigInteger bi) { 437 this(bi.toString(10)); 438 return; 439 } 440 441 // exp remains 0 442 443 /** 444 * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code> and a scale. 445 * <p> 446 * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>, 447 * scaled by the second parameter, which may not be negative. The value of the <code>BigDecimal</code> is the <code> 448 * BigInteger</code> divided by ten to the power of the scale. The <code>BigInteger</code> parameter must not be 449 * <code>null</code>. 450 * <p> 451 * The <code>BigDecimal</code> will contain only decimal digits, (with an embedded decimal point followed by <code> 452 * scale</code> decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the <code> 453 * BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero. 454 * 455 * @param bi The <code>BigInteger</code> to be converted. 456 * @param scale The <code>int</code> specifying the scale. 457 * @throws NumberFormatException If the scale is negative. 458 */ 459 BigDecimal(java.math.BigInteger bi, int scale)460 public BigDecimal(java.math.BigInteger bi, int scale) { 461 this(bi.toString(10)); 462 if (scale < 0) 463 throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); 464 exp = -scale; // exponent is -scale 465 return; 466 } 467 468 /** 469 * Constructs a <code>BigDecimal</code> object from an array of characters. 470 * <p> 471 * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character 472 * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be 473 * <code>null</code>. 474 * <p> 475 * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is 476 * already available in character array form. 477 * 478 * @param inchars The <code>char[]</code> array containing the number to be converted. 479 * @throws NumberFormatException If the parameter is not a valid number. 480 */ 481 BigDecimal(char inchars[])482 public BigDecimal(char inchars[]) { 483 this(inchars, 0, inchars.length); 484 return; 485 } 486 487 /** 488 * Constructs a <code>BigDecimal</code> object from an array of characters. 489 * <p> 490 * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character 491 * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. 492 * The first parameter must not be <code>null</code>, and the subarray must be wholly contained within it. 493 * <p> 494 * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is 495 * already available within a character array. 496 * 497 * @param inchars The <code>char[]</code> array containing the number to be converted. 498 * @param offset The <code>int</code> offset into the array of the start of the number to be converted. 499 * @param length The <code>int</code> length of the number. 500 * @throws NumberFormatException If the parameter is not a valid number for any reason. 501 */ 502 BigDecimal(char inchars[], int offset, int length)503 public BigDecimal(char inchars[], int offset, int length) { 504 super(); 505 boolean exotic; 506 boolean hadexp; 507 int d; 508 int dotoff; 509 int last; 510 int i = 0; 511 char si = 0; 512 boolean eneg = false; 513 int k = 0; 514 int elen = 0; 515 int j = 0; 516 char sj = 0; 517 int dvalue = 0; 518 int mag = 0; 519 // This is the primary constructor; all incoming strings end up 520 // here; it uses explicit (inline) parsing for speed and to avoid 521 // generating intermediate (temporary) objects of any kind. 522 // 1998.06.25: exponent form built only if E/e in string 523 // 1998.06.25: trailing zeros not removed for zero 524 // 1999.03.06: no embedded blanks; allow offset and length 525 if (length <= 0) 526 bad(inchars); // bad conversion (empty string) 527 // [bad offset will raise array bounds exception] 528 529 /* Handle and step past sign */ 530 ind = ispos; // assume positive 531 if (inchars[offset] == ('-')) { 532 length--; 533 if (length == 0) 534 bad(inchars); // nothing after sign 535 ind = isneg; 536 offset++; 537 } else if (inchars[offset] == ('+')) { 538 length--; 539 if (length == 0) 540 bad(inchars); // nothing after sign 541 offset++; 542 } 543 544 /* We're at the start of the number */ 545 exotic = false; // have extra digits 546 hadexp = false; // had explicit exponent 547 d = 0; // count of digits found 548 dotoff = -1; // offset where dot was found 549 last = -1; // last character of mantissa 550 { 551 int $1 = length; 552 i = offset; 553 i: for (; $1 > 0; $1--, i++) { 554 si = inchars[i]; 555 if (si >= '0') // test for Arabic digit 556 if (si <= '9') { 557 last = i; 558 d++; // still in mantissa 559 continue i; 560 } 561 if (si == '.') { // record and ignore 562 if (dotoff >= 0) 563 bad(inchars); // two dots 564 dotoff = i - offset; // offset into mantissa 565 continue i; 566 } 567 if (si != 'e') 568 if (si != 'E') { // expect an extra digit 569 if ((!(UCharacter.isDigit(si)))) 570 bad(inchars); // not a number 571 // defer the base 10 check until later to avoid extra method call 572 exotic = true; // will need conversion later 573 last = i; 574 d++; // still in mantissa 575 continue i; 576 } 577 /* Found 'e' or 'E' -- now process explicit exponent */ 578 // 1998.07.11: sign no longer required 579 if ((i - offset) > (length - 2)) 580 bad(inchars); // no room for even one digit 581 eneg = false; 582 if ((inchars[i + 1]) == ('-')) { 583 eneg = true; 584 k = i + 2; 585 } else if ((inchars[i + 1]) == ('+')) 586 k = i + 2; 587 else 588 k = i + 1; 589 // k is offset of first expected digit 590 elen = length - ((k - offset)); // possible number of digits 591 if ((elen == 0) | (elen > 9)) 592 bad(inchars); // 0 or more than 9 digits 593 { 594 int $2 = elen; 595 j = k; 596 for (; $2 > 0; $2--, j++) { 597 sj = inchars[j]; 598 if (sj < '0') 599 bad(inchars); // always bad 600 if (sj > '9') { // maybe an exotic digit 601 if ((!(UCharacter.isDigit(sj)))) 602 bad(inchars); // not a number 603 dvalue = UCharacter.digit(sj, 10); // check base 604 if (dvalue < 0) 605 bad(inchars); // not base 10 606 } else 607 dvalue = ((sj)) - (('0')); 608 exp = (exp * 10) + dvalue; 609 } 610 }/* j */ 611 if (eneg) 612 exp = -exp; // was negative 613 hadexp = true; // remember we had one 614 break i; // we are done 615 } 616 }/* i */ 617 618 /* Here when all inspected */ 619 if (d == 0) 620 bad(inchars); // no mantissa digits 621 if (dotoff >= 0) 622 exp = (exp + dotoff) - d; // adjust exponent if had dot 623 624 /* strip leading zeros/dot (leave final if all 0's) */ 625 { 626 int $3 = last - 1; 627 i = offset; 628 i: for (; i <= $3; i++) { 629 si = inchars[i]; 630 if (si == '0') { 631 offset++; 632 dotoff--; 633 d--; 634 } else if (si == '.') { 635 offset++; // step past dot 636 dotoff--; 637 } else if (si <= '9') 638 break i;/* non-0 */ 639 else {/* exotic */ 640 if ((UCharacter.digit(si, 10)) != 0) 641 break i; // non-0 or bad 642 // is 0 .. strip like '0' 643 offset++; 644 dotoff--; 645 d--; 646 } 647 } 648 }/* i */ 649 650 /* Create the mantissa array */ 651 mant = new byte[d]; // we know the length 652 j = offset; // input offset 653 if (exotic) { 654 do { // slow: check for exotica 655 { 656 int $4 = d; 657 i = 0; 658 for (; $4 > 0; $4--, i++) { 659 if (i == dotoff) 660 j++; // at dot 661 sj = inchars[j]; 662 if (sj <= '9') 663 mant[i] = (byte) (((sj)) - (('0')));/* easy */ 664 else { 665 dvalue = UCharacter.digit(sj, 10); 666 if (dvalue < 0) 667 bad(inchars); // not a number after all 668 mant[i] = (byte) dvalue; 669 } 670 j++; 671 } 672 }/* i */ 673 } while (false); 674 }/* exotica */ 675 else { 676 do { 677 { 678 int $5 = d; 679 i = 0; 680 for (; $5 > 0; $5--, i++) { 681 if (i == dotoff) 682 j++; 683 mant[i] = (byte) (((inchars[j])) - (('0'))); 684 j++; 685 } 686 }/* i */ 687 } while (false); 688 }/* simple */ 689 690 /* Looks good. Set the sign indicator and form, as needed. */ 691 // Trailing zeros are preserved 692 // The rule here for form is: 693 // If no E-notation, then request plain notation 694 // Otherwise act as though add(0,DEFAULT) and request scientific notation 695 // [form is already PLAIN] 696 if (mant[0] == 0) { 697 ind = iszero; // force to show zero 698 // negative exponent is significant (e.g., -3 for 0.000) if plain 699 if (exp > 0) 700 exp = 0; // positive exponent can be ignored 701 if (hadexp) { // zero becomes single digit from add 702 mant = ZERO.mant; 703 exp = 0; 704 } 705 } else { // non-zero 706 // [ind was set earlier] 707 // now determine form 708 if (hadexp) { 709 form = (byte) android.icu.math.MathContext.SCIENTIFIC; 710 // 1999.06.29 check for overflow 711 mag = (exp + mant.length) - 1; // true exponent in scientific notation 712 if ((mag < MinExp) | (mag > MaxExp)) 713 bad(inchars); 714 } 715 } 716 // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form 717 return; 718 } 719 720 /** 721 * Constructs a <code>BigDecimal</code> object directly from a <code>double</code>. 722 * <p> 723 * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary 724 * floating point parameter. 725 * <p> 726 * Note that this constructor it an exact conversion; it does not give the same result as converting <code>num 727 * </code> to a <code>String</code> using the <code>Double.toString()</code> method and then using the 728 * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)} 729 * method to construct a <code>BigDecimal</code> from a <code>double</code>. 730 * 731 * @param num The <code>double</code> to be converted. 732 * @throws NumberFormatException If the parameter is infinite or not a number. 733 */ 734 BigDecimal(double num)735 public BigDecimal(double num) { 736 // 1999.03.06: use exactly the old algorithm 737 // 2000.01.01: note that this constructor does give an exact result, 738 // so perhaps it should not be deprecated 739 // 2000.06.18: no longer deprecated 740 this((new java.math.BigDecimal(num)).toString()); 741 return; 742 } 743 744 /** 745 * Constructs a <code>BigDecimal</code> object directly from a <code>int</code>. 746 * <p> 747 * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 32-bit signed binary 748 * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus 749 * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. 750 * 751 * @param num The <code>int</code> to be converted. 752 */ 753 BigDecimal(int num)754 public BigDecimal(int num) { 755 super(); 756 int mun; 757 int i = 0; 758 // We fastpath commoners 759 if (num <= 9) 760 if (num >= (-9)) { 761 do { 762 // very common single digit case 763 {/* select */ 764 if (num == 0) { 765 mant = ZERO.mant; 766 ind = iszero; 767 } else if (num == 1) { 768 mant = ONE.mant; 769 ind = ispos; 770 } else if (num == (-1)) { 771 mant = ONE.mant; 772 ind = isneg; 773 } else { 774 { 775 mant = new byte[1]; 776 if (num > 0) { 777 mant[0] = (byte) num; 778 ind = ispos; 779 } else { // num<-1 780 mant[0] = (byte) -num; 781 ind = isneg; 782 } 783 } 784 } 785 } 786 return; 787 } while (false); 788 }/* singledigit */ 789 790 /* We work on negative numbers so we handle the most negative number */ 791 if (num > 0) { 792 ind = ispos; 793 num = -num; 794 } else 795 ind = isneg;/* negative */// [0 case already handled] 796 // [it is quicker, here, to pre-calculate the length with 797 // one loop, then allocate exactly the right length of byte array, 798 // then re-fill it with another loop] 799 mun = num; // working copy 800 { 801 i = 9; 802 i: for (;; i--) { 803 mun = mun / 10; 804 if (mun == 0) 805 break i; 806 } 807 }/* i */ 808 // i is the position of the leftmost digit placed 809 mant = new byte[10 - i]; 810 { 811 i = (10 - i) - 1; 812 i: for (;; i--) { 813 mant[i] = (byte) -(((byte) (num % 10))); 814 num = num / 10; 815 if (num == 0) 816 break i; 817 } 818 }/* i */ 819 return; 820 } 821 822 /** 823 * Constructs a <code>BigDecimal</code> object directly from a <code>long</code>. 824 * <p> 825 * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary 826 * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus 827 * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. 828 * 829 * @param num The <code>long</code> to be converted. 830 */ 831 BigDecimal(long num)832 public BigDecimal(long num) { 833 super(); 834 long mun; 835 int i = 0; 836 // Not really worth fastpathing commoners in this constructor [also, 837 // we use this to construct the static constants]. 838 // This is much faster than: this(String.valueOf(num).toCharArray()) 839 /* We work on negative num so we handle the most negative number */ 840 if (num > 0) { 841 ind = ispos; 842 num = -num; 843 } else if (num == 0) 844 ind = iszero; 845 else 846 ind = isneg;/* negative */ 847 mun = num; 848 { 849 i = 18; 850 i: for (;; i--) { 851 mun = mun / 10; 852 if (mun == 0) 853 break i; 854 } 855 }/* i */ 856 // i is the position of the leftmost digit placed 857 mant = new byte[19 - i]; 858 { 859 i = (19 - i) - 1; 860 i: for (;; i--) { 861 mant[i] = (byte) -(((byte) (num % 10))); 862 num = num / 10; 863 if (num == 0) 864 break i; 865 } 866 }/* i */ 867 return; 868 } 869 870 /** 871 * Constructs a <code>BigDecimal</code> object from a <code>String</code>. 872 * <p> 873 * Constructs a <code>BigDecimal</code> from the parameter, which must not be <code>null</code> and must represent a 874 * valid <i>number</i>, as described formally in the documentation referred to {@link BigDecimal above}. 875 * <p> 876 * In summary, numbers in <code>String</code> form must have at least one digit, may have a leading sign, may have a 877 * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks. 878 * <p> 879 * Some valid strings from which a <code>BigDecimal</code> might be constructed are: 880 * 881 * <pre> 882 * 883 * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus 884 * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" -- 885 * Exponential notation 886 * 887 * </pre> 888 * <p> 889 * (Exponential notation means that the number includes an optional sign and a power of ten following an 890 * '<code>E</code>' that indicates how the decimal point will be shifted. Thus the <code>"4E+9"</code> above is 891 * just a short way of writing <code>4000000000</code>, and the <code>"0.73e-7"</code> is short for <code> 892 * 0.000000073</code>.) 893 * <p> 894 * The <code>BigDecimal</code> constructed from the String is in a standard form, with no blanks, as though the 895 * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string 896 * uses exponential notation (that is, includes an <code>e</code> or an <code>E</code>), then the <code>BigDecimal 897 * </code> number will be expressed in scientific notation (where the power of ten is adjusted so there is a single 898 * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as 899 * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must 900 * fit in nine digits both before and after it is expressed in scientific notation. 901 * <p> 902 * Any digits in the parameter must be decimal; that is, <code>Character.digit(c, 10)</code> (where <code>c</code> 903 * is the character in question) would not return -1. 904 * 905 * @param string The <code>String</code> to be converted. 906 * @throws NumberFormatException If the parameter is not a valid number. 907 */ 908 BigDecimal(java.lang.String string)909 public BigDecimal(java.lang.String string) { 910 this(string.toCharArray(), 0, string.length()); 911 return; 912 } 913 914 /* <sgml> Make a default BigDecimal object for local use. </sgml> */ 915 BigDecimal()916 private BigDecimal() { 917 super(); 918 return; 919 } 920 921 /* ---------------------------------------------------------------- */ 922 /* Operator methods [methods which take a context parameter] */ 923 /* ---------------------------------------------------------------- */ 924 925 /** 926 * Returns a plain <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>. 927 * <p> 928 * The same as {@link #abs(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 929 * <p> 930 * The length of the decimal part (the scale) of the result will be <code>this.scale()</code> 931 * 932 * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>. 933 */ 934 abs()935 public android.icu.math.BigDecimal abs() { 936 return this.abs(plainMC); 937 } 938 939 /** 940 * Returns a <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>. 941 * <p> 942 * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method 943 * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)} 944 * method with the same parameter is returned. 945 * 946 * @param set The <code>MathContext</code> arithmetic settings. 947 * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>. 948 */ 949 abs(android.icu.math.MathContext set)950 public android.icu.math.BigDecimal abs(android.icu.math.MathContext set) { 951 if (this.ind == isneg) 952 return this.negate(set); 953 return this.plus(set); 954 } 955 956 /** 957 * Returns a plain <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic. 958 * <p> 959 * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 960 * context is <code>new MathContext(0, MathContext.PLAIN)</code>. 961 * <p> 962 * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. 963 * 964 * @param rhs The <code>BigDecimal</code> for the right hand side of the addition. 965 * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic. 966 */ 967 add(android.icu.math.BigDecimal rhs)968 public android.icu.math.BigDecimal add(android.icu.math.BigDecimal rhs) { 969 return this.add(rhs, plainMC); 970 } 971 972 /** 973 * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>. 974 * <p> 975 * Implements the addition (<b><code>+</code></b>) operator (as defined in the decimal documentation, see 976 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 977 * 978 * @param rhs The <code>BigDecimal</code> for the right hand side of the addition. 979 * @param set The <code>MathContext</code> arithmetic settings. 980 * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>. 981 */ 982 add(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)983 public android.icu.math.BigDecimal add(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 984 android.icu.math.BigDecimal lhs; 985 int reqdig; 986 android.icu.math.BigDecimal res; 987 byte usel[]; 988 int usellen; 989 byte user[]; 990 int userlen; 991 int newlen = 0; 992 int tlen = 0; 993 int mult = 0; 994 byte t[] = null; 995 int ia = 0; 996 int ib = 0; 997 int ea = 0; 998 int eb = 0; 999 byte ca = 0; 1000 byte cb = 0; 1001 /* determine requested digits and form */ 1002 if (set.lostDigits) 1003 checkdigits(rhs, set.digits); 1004 lhs = this; // name for clarity and proxy 1005 1006 /* Quick exit for add floating 0 */ 1007 // plus() will optimize to return same object if possible 1008 if (lhs.ind == 0) 1009 if (set.form != android.icu.math.MathContext.PLAIN) 1010 return rhs.plus(set); 1011 if (rhs.ind == 0) 1012 if (set.form != android.icu.math.MathContext.PLAIN) 1013 return lhs.plus(set); 1014 1015 /* Prepare numbers (round, unless unlimited precision) */ 1016 reqdig = set.digits; // local copy (heavily used) 1017 if (reqdig > 0) { 1018 if (lhs.mant.length > reqdig) 1019 lhs = clone(lhs).round(set); 1020 if (rhs.mant.length > reqdig) 1021 rhs = clone(rhs).round(set); 1022 // [we could reuse the new LHS for result in this case] 1023 } 1024 1025 res = new android.icu.math.BigDecimal(); // build result here 1026 1027 /* 1028 * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much 1029 * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to 1030 * DIGITS trailing zeros]. 1031 */ 1032 // Note sign may be 0 if digits (reqdig) is 0 1033 // usel and user will be the byte arrays passed to the adder; we'll 1034 // use them on all paths except quick exits 1035 usel = lhs.mant; 1036 usellen = lhs.mant.length; 1037 user = rhs.mant; 1038 userlen = rhs.mant.length; 1039 { 1040 do {/* select */ 1041 if (lhs.exp == rhs.exp) {/* no padding needed */ 1042 // This is the most common, and fastest, path 1043 res.exp = lhs.exp; 1044 } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs 1045 newlen = (usellen + lhs.exp) - rhs.exp; 1046 /* 1047 * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot 1048 * affect answer, so we only need to pad up to a length of DIGITS+1. 1049 */ 1050 if (newlen >= ((userlen + reqdig) + 1)) 1051 if (reqdig > 0) { 1052 // LHS is sufficient 1053 res.mant = usel; 1054 res.exp = lhs.exp; 1055 res.ind = lhs.ind; 1056 if (usellen < reqdig) { // need 0 padding 1057 res.mant = extend(lhs.mant, reqdig); 1058 res.exp = res.exp - ((reqdig - usellen)); 1059 } 1060 return res.finish(set, false); 1061 } 1062 // RHS may affect result 1063 res.exp = rhs.exp; // expected final exponent 1064 if (newlen > (reqdig + 1)) 1065 if (reqdig > 0) { 1066 // LHS will be max; RHS truncated 1067 tlen = (newlen - reqdig) - 1; // truncation length 1068 userlen = userlen - tlen; 1069 res.exp = res.exp + tlen; 1070 newlen = reqdig + 1; 1071 } 1072 if (newlen > usellen) 1073 usellen = newlen; // need to pad LHS 1074 } else { // need to pad rhs and/or truncate lhs 1075 newlen = (userlen + rhs.exp) - lhs.exp; 1076 if (newlen >= ((usellen + reqdig) + 1)) 1077 if (reqdig > 0) { 1078 // RHS is sufficient 1079 res.mant = user; 1080 res.exp = rhs.exp; 1081 res.ind = rhs.ind; 1082 if (userlen < reqdig) { // need 0 padding 1083 res.mant = extend(rhs.mant, reqdig); 1084 res.exp = res.exp - ((reqdig - userlen)); 1085 } 1086 return res.finish(set, false); 1087 } 1088 // LHS may affect result 1089 res.exp = lhs.exp; // expected final exponent 1090 if (newlen > (reqdig + 1)) 1091 if (reqdig > 0) { 1092 // RHS will be max; LHS truncated 1093 tlen = (newlen - reqdig) - 1; // truncation length 1094 usellen = usellen - tlen; 1095 res.exp = res.exp + tlen; 1096 newlen = reqdig + 1; 1097 } 1098 if (newlen > userlen) 1099 userlen = newlen; // need to pad RHS 1100 } 1101 } while (false); 1102 }/* padder */ 1103 1104 /* OK, we have aligned mantissas. Now add or subtract. */ 1105 // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive 1106 // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs] 1107 // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs] 1108 if (lhs.ind == iszero) 1109 res.ind = ispos; 1110 else 1111 res.ind = lhs.ind; // likely sign, all paths 1112 if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative 1113 mult = 1; 1114 else { 1115 do { // different signs, so subtraction is needed 1116 mult = -1; // will cause subtract 1117 /* 1118 * Before we can subtract we must determine which is the larger, as our add/subtract routine only 1119 * handles non-negative results so we may need to swap the operands. 1120 */ 1121 { 1122 do {/* select */ 1123 if (rhs.ind == iszero) { 1124 // original A bigger 1125 } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger 1126 t = usel; 1127 usel = user; 1128 user = t; // swap 1129 tlen = usellen; 1130 usellen = userlen; 1131 userlen = tlen; // .. 1132 res.ind = (byte) -res.ind; // and set sign 1133 } else if (usellen > userlen) { 1134 // original A bigger 1135 } else { 1136 {/* logical lengths the same */// need compare 1137 /* may still need to swap: compare the strings */ 1138 ia = 0; 1139 ib = 0; 1140 ea = usel.length - 1; 1141 eb = user.length - 1; 1142 { 1143 compare: for (;;) { 1144 if (ia <= ea) 1145 ca = usel[ia]; 1146 else { 1147 if (ib > eb) {/* identical */ 1148 if (set.form != android.icu.math.MathContext.PLAIN) 1149 return ZERO; 1150 // [if PLAIN we must do the subtract, in case of 0.000 results] 1151 break compare; 1152 } 1153 ca = (byte) 0; 1154 } 1155 if (ib <= eb) 1156 cb = user[ib]; 1157 else 1158 cb = (byte) 0; 1159 if (ca != cb) { 1160 if (ca < cb) {/* swap needed */ 1161 t = usel; 1162 usel = user; 1163 user = t; // swap 1164 tlen = usellen; 1165 usellen = userlen; 1166 userlen = tlen; // .. 1167 res.ind = (byte) -res.ind; 1168 } 1169 break compare; 1170 } 1171 /* mantissas the same, so far */ 1172 ia++; 1173 ib++; 1174 } 1175 }/* compare */ 1176 } // lengths the same 1177 } 1178 } while (false); 1179 }/* swaptest */ 1180 } while (false); 1181 }/* signdiff */ 1182 1183 /* here, A is > B if subtracting */ 1184 // add [A+B*1] or subtract [A+(B*-1)] 1185 res.mant = byteaddsub(usel, usellen, user, userlen, mult, false); 1186 // [reuse possible only after chop; accounting makes not worthwhile] 1187 1188 // Finish() rounds before stripping leading 0's, then sets form, etc. 1189 return res.finish(set, false); 1190 } 1191 1192 /** 1193 * Compares this <code>BigDecimal</code> to another, using unlimited precision. 1194 * <p> 1195 * The same as {@link #compareTo(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, 1196 * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1197 * 1198 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1199 * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to, 1200 * or greater than <code>rhs</code>. 1201 */ 1202 1203 @Override compareTo(android.icu.math.BigDecimal rhs)1204 public int compareTo(android.icu.math.BigDecimal rhs) { 1205 return this.compareTo(rhs, plainMC); 1206 } 1207 1208 /** 1209 * Compares this <code>BigDecimal</code> to another. 1210 * <p> 1211 * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}), 1212 * and returns a result of type <code>int</code>. 1213 * <p> 1214 * The result will be: 1215 * <table cellpadding=2> 1216 * <tr> 1217 * <td align=right><b>-1</b></td> <td>if the current object is less than the first parameter</td> 1218 * </tr> 1219 * <tr> 1220 * <td align=right><b>0</b></td> <td>if the current object is equal to the first parameter</td> 1221 * </tr> 1222 * <tr> 1223 * <td align=right><b>1</b></td> <td>if the current object is greater than the first parameter.</td> 1224 * </tr> 1225 * </table> 1226 * <p> 1227 * A {@link #compareTo(BigDecimal)} method is also provided. 1228 * 1229 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1230 * @param set The <code>MathContext</code> arithmetic settings. 1231 * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to, 1232 * or greater than <code>rhs</code>. 1233 */ 1234 compareTo(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1235 public int compareTo(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1236 int thislength = 0; 1237 int i = 0; 1238 android.icu.math.BigDecimal newrhs; 1239 // rhs=null will raise NullPointerException, as per Comparable interface 1240 if (set.lostDigits) 1241 checkdigits(rhs, set.digits); 1242 // [add will recheck in slowpath cases .. but would report -rhs] 1243 if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) { 1244 /* sign & exponent the same [very common] */ 1245 thislength = this.mant.length; 1246 if (thislength < rhs.mant.length) 1247 return (byte) -this.ind; 1248 if (thislength > rhs.mant.length) 1249 return this.ind; 1250 /* 1251 * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very 1252 * unusual] 1253 */ 1254 if ((thislength <= set.digits) | (set.digits == 0)) { 1255 { 1256 int $6 = thislength; 1257 i = 0; 1258 for (; $6 > 0; $6--, i++) { 1259 if (this.mant[i] < rhs.mant[i]) 1260 return (byte) -this.ind; 1261 if (this.mant[i] > rhs.mant[i]) 1262 return this.ind; 1263 } 1264 }/* i */ 1265 return 0; // identical 1266 } 1267 /* drop through for full comparison */ 1268 } else { 1269 /* More fastpaths possible */ 1270 if (this.ind < rhs.ind) 1271 return -1; 1272 if (this.ind > rhs.ind) 1273 return 1; 1274 } 1275 /* carry out a subtract to make the comparison */ 1276 newrhs = clone(rhs); // safe copy 1277 newrhs.ind = (byte) -newrhs.ind; // prepare to subtract 1278 return this.add(newrhs, set).ind; // add, and return sign of result 1279 } 1280 1281 /** 1282 * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic. 1283 * <p> 1284 * The same as {@link #divide(BigDecimal, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1285 * rounding mode is {@link MathContext#ROUND_HALF_UP}. 1286 * 1287 * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if 1288 * the latter were formatted without exponential notation. 1289 * 1290 * @param rhs The <code>BigDecimal</code> for the right hand side of the division. 1291 * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic. 1292 * @throws ArithmeticException If <code>rhs</code> is zero. 1293 */ 1294 divide(android.icu.math.BigDecimal rhs)1295 public android.icu.math.BigDecimal divide(android.icu.math.BigDecimal rhs) { 1296 return this.dodivide('D', rhs, plainMC, -1); 1297 } 1298 1299 /** 1300 * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a 1301 * rounding mode. 1302 * <p> 1303 * The same as {@link #divide(BigDecimal, int, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1304 * second parameter is <code>this.scale()</code>, and the third is <code>round</code>. 1305 * <p> 1306 * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current 1307 * object, if the latter were formatted without exponential notation. 1308 * <p> 1309 * 1310 * @param rhs The <code>BigDecimal</code> for the right hand side of the division. 1311 * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class). 1312 * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and 1313 * the specified rounding mode. 1314 * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode. 1315 * @throws ArithmeticException if <code>rhs</code> is zero. 1316 * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>this.scale()</code> is insufficient to represent the result exactly. 1317 */ 1318 divide(android.icu.math.BigDecimal rhs, int round)1319 public android.icu.math.BigDecimal divide(android.icu.math.BigDecimal rhs, int round) { 1320 android.icu.math.MathContext set; 1321 set = new android.icu.math.MathContext(0, android.icu.math.MathContext.PLAIN, false, round); // [checks round, 1322 // too] 1323 return this.dodivide('D', rhs, set, -1); // take scale from LHS 1324 } 1325 1326 /** 1327 * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a 1328 * given scale and rounding mode. 1329 * <p> 1330 * The same as {@link #divide(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, 1331 * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>, except that the length of the decimal part (the 1332 * scale) to be used for the result is explicit rather than being taken from <code>this</code>. 1333 * <p> 1334 * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if 1335 * the latter were formatted without exponential notation. 1336 * <p> 1337 * 1338 * @param rhs The <code>BigDecimal</code> for the right hand side of the division. 1339 * @param scale The <code>int</code> scale to be used for the result. 1340 * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class). 1341 * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and 1342 * the specified rounding mode. 1343 * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode. 1344 * @throws ArithmeticException if <code>rhs</code> is zero. 1345 * @throws ArithmeticException if <code>scale</code> is negative. 1346 * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>scale</code> is insufficient 1347 * to represent the result exactly. 1348 */ 1349 divide(android.icu.math.BigDecimal rhs, int scale, int round)1350 public android.icu.math.BigDecimal divide(android.icu.math.BigDecimal rhs, int scale, int round) { 1351 android.icu.math.MathContext set; 1352 if (scale < 0) 1353 throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); 1354 set = new android.icu.math.MathContext(0, android.icu.math.MathContext.PLAIN, false, round); // [checks round] 1355 return this.dodivide('D', rhs, set, scale); 1356 } 1357 1358 /** 1359 * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>. 1360 * <p> 1361 * Implements the division (<b><code>/</code></b>) operator (as defined in the decimal documentation, see 1362 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1363 * 1364 * @param rhs The <code>BigDecimal</code> for the right hand side of the division. 1365 * @param set The <code>MathContext</code> arithmetic settings. 1366 * @return A <code>BigDecimal</code> whose value is <code>this/rhs</code>. 1367 * @throws ArithmeticException if <code>rhs</code> is zero. 1368 */ 1369 divide(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1370 public android.icu.math.BigDecimal divide(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1371 return this.dodivide('D', rhs, set, -1); 1372 } 1373 1374 /** 1375 * Returns a plain <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>. 1376 * <p> 1377 * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs 1378 * </code>, and the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1379 * 1380 * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division. 1381 * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>. 1382 * @throws ArithmeticException if <code>rhs</code> is zero. 1383 */ 1384 divideInteger(android.icu.math.BigDecimal rhs)1385 public android.icu.math.BigDecimal divideInteger(android.icu.math.BigDecimal rhs) { 1386 // scale 0 to drop .000 when plain 1387 return this.dodivide('I', rhs, plainMC, 0); 1388 } 1389 1390 /** 1391 * Returns a <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>. 1392 * <p> 1393 * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class 1394 * header}), and returns the result as a <code>BigDecimal</code> object. 1395 * 1396 * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division. 1397 * @param set The <code>MathContext</code> arithmetic settings. 1398 * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>. 1399 * @throws ArithmeticException if <code>rhs</code> is zero. 1400 * @throws ArithmeticException if the result will not fit in the number of digits specified for the context. 1401 */ 1402 divideInteger(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1403 public android.icu.math.BigDecimal divideInteger(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1404 // scale 0 to drop .000 when plain 1405 return this.dodivide('I', rhs, set, 0); 1406 } 1407 1408 /** 1409 * Returns a plain <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>. 1410 * <p> 1411 * The same as {@link #max(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1412 * context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1413 * 1414 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1415 * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>. 1416 */ 1417 max(android.icu.math.BigDecimal rhs)1418 public android.icu.math.BigDecimal max(android.icu.math.BigDecimal rhs) { 1419 return this.max(rhs, plainMC); 1420 } 1421 1422 /** 1423 * Returns a <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>. 1424 * <p> 1425 * Returns the larger of the current object and the first parameter. 1426 * <p> 1427 * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>1 1428 * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object 1429 * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the 1430 * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code> 1431 * parameter) is returned. 1432 * 1433 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1434 * @param set The <code>MathContext</code> arithmetic settings. 1435 * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>. 1436 */ 1437 max(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1438 public android.icu.math.BigDecimal max(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1439 if ((this.compareTo(rhs, set)) >= 0) 1440 return this.plus(set); 1441 else 1442 return rhs.plus(set); 1443 } 1444 1445 /** 1446 * Returns a plain <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>. 1447 * <p> 1448 * The same as {@link #min(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1449 * context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1450 * 1451 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1452 * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>. 1453 */ 1454 min(android.icu.math.BigDecimal rhs)1455 public android.icu.math.BigDecimal min(android.icu.math.BigDecimal rhs) { 1456 return this.min(rhs, plainMC); 1457 } 1458 1459 /** 1460 * Returns a <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>. 1461 * <p> 1462 * Returns the smaller of the current object and the first parameter. 1463 * <p> 1464 * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>-1 1465 * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object 1466 * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the 1467 * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code> 1468 * parameter) is returned. 1469 * 1470 * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison. 1471 * @param set The <code>MathContext</code> arithmetic settings. 1472 * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>. 1473 */ 1474 min(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1475 public android.icu.math.BigDecimal min(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1476 if ((this.compareTo(rhs, set)) <= 0) 1477 return this.plus(set); 1478 else 1479 return rhs.plus(set); 1480 } 1481 1482 /** 1483 * Returns a plain <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic. 1484 * <p> 1485 * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1486 * context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1487 * <p> 1488 * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they 1489 * were formatted without exponential notation. 1490 * 1491 * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication. 1492 * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic. 1493 */ 1494 multiply(android.icu.math.BigDecimal rhs)1495 public android.icu.math.BigDecimal multiply(android.icu.math.BigDecimal rhs) { 1496 return this.multiply(rhs, plainMC); 1497 } 1498 1499 /** 1500 * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>. 1501 * <p> 1502 * Implements the multiplication (<b><code>*</code></b>) operator (as defined in the decimal documentation, see 1503 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1504 * 1505 * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication. 1506 * @param set The <code>MathContext</code> arithmetic settings. 1507 * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>. 1508 */ 1509 multiply(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1510 public android.icu.math.BigDecimal multiply(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1511 android.icu.math.BigDecimal lhs; 1512 int padding; 1513 int reqdig; 1514 byte multer[] = null; 1515 byte multand[] = null; 1516 int multandlen; 1517 int acclen = 0; 1518 android.icu.math.BigDecimal res; 1519 byte acc[]; 1520 int n = 0; 1521 byte mult = 0; 1522 if (set.lostDigits) 1523 checkdigits(rhs, set.digits); 1524 lhs = this; // name for clarity and proxy 1525 1526 /* Prepare numbers (truncate, unless unlimited precision) */ 1527 padding = 0; // trailing 0's to add 1528 reqdig = set.digits; // local copy 1529 if (reqdig > 0) { 1530 if (lhs.mant.length > reqdig) 1531 lhs = clone(lhs).round(set); 1532 if (rhs.mant.length > reqdig) 1533 rhs = clone(rhs).round(set); 1534 // [we could reuse the new LHS for result in this case] 1535 } else {/* unlimited */ 1536 // fixed point arithmetic will want every trailing 0; we add these 1537 // after the calculation rather than before, for speed. 1538 if (lhs.exp > 0) 1539 padding = padding + lhs.exp; 1540 if (rhs.exp > 0) 1541 padding = padding + rhs.exp; 1542 } 1543 1544 // For best speed, as in DMSRCN, we use the shorter number as the 1545 // multiplier and the longer as the multiplicand. 1546 // 1999.12.22: We used to special case when the result would fit in 1547 // a long, but with Java 1.3 this gave no advantage. 1548 if (lhs.mant.length < rhs.mant.length) { 1549 multer = lhs.mant; 1550 multand = rhs.mant; 1551 } else { 1552 multer = rhs.mant; 1553 multand = lhs.mant; 1554 } 1555 1556 /* Calculate how long result byte array will be */ 1557 multandlen = (multer.length + multand.length) - 1; // effective length 1558 // optimize for 75% of the cases where a carry is expected... 1559 if ((multer[0] * multand[0]) > 9) 1560 acclen = multandlen + 1; 1561 else 1562 acclen = multandlen; 1563 1564 /* Now the main long multiplication loop */ 1565 res = new android.icu.math.BigDecimal(); // where we'll build result 1566 acc = new byte[acclen]; // accumulator, all zeros 1567 // 1998.07.01: calculate from left to right so that accumulator goes 1568 // to likely final length on first addition; this avoids a one-digit 1569 // extension (and object allocation) each time around the loop. 1570 // Initial number therefore has virtual zeros added to right. 1571 { 1572 int $7 = multer.length; 1573 n = 0; 1574 for (; $7 > 0; $7--, n++) { 1575 mult = multer[n]; 1576 if (mult != 0) { // [optimization] 1577 // accumulate [accumulator is reusable array] 1578 acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true); 1579 } 1580 // divide multiplicand by 10 for next digit to right 1581 multandlen--; // 'virtual length' 1582 } 1583 }/* n */ 1584 1585 res.ind = (byte) (lhs.ind * rhs.ind); // final sign 1586 res.exp = (lhs.exp + rhs.exp) - padding; // final exponent 1587 // [overflow is checked by finish] 1588 1589 /* add trailing zeros to the result, if necessary */ 1590 if (padding == 0) 1591 res.mant = acc; 1592 else 1593 res.mant = extend(acc, acc.length + padding); // add trailing 0s 1594 return res.finish(set, false); 1595 } 1596 1597 /** 1598 * Returns a plain <code>BigDecimal</code> whose value is <code>-this</code>. 1599 * <p> 1600 * The same as {@link #negate(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code> 1601 * . 1602 * <p> 1603 * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code> 1604 * 1605 * 1606 * @return A <code>BigDecimal</code> whose value is <code>-this</code>. 1607 */ 1608 negate()1609 public android.icu.math.BigDecimal negate() { 1610 return this.negate(plainMC); 1611 } 1612 1613 /** 1614 * Returns a <code>BigDecimal</code> whose value is <code>-this</code>. 1615 * <p> 1616 * Implements the negation (Prefix <b><code>-</code></b>) operator (as defined in the decimal documentation, see 1617 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1618 * 1619 * @param set The <code>MathContext</code> arithmetic settings. 1620 * @return A <code>BigDecimal</code> whose value is <code>-this</code>. 1621 */ 1622 negate(android.icu.math.MathContext set)1623 public android.icu.math.BigDecimal negate(android.icu.math.MathContext set) { 1624 android.icu.math.BigDecimal res; 1625 // Originally called minus(), changed to matched Java precedents 1626 // This simply clones, flips the sign, and possibly rounds 1627 if (set.lostDigits) 1628 checkdigits((android.icu.math.BigDecimal) null, set.digits); 1629 res = clone(this); // safe copy 1630 res.ind = (byte) -res.ind; 1631 return res.finish(set, false); 1632 } 1633 1634 /** 1635 * Returns a plain <code>BigDecimal</code> whose value is <code>+this</code>. Note that <code>this</code> is not 1636 * necessarily a plain <code>BigDecimal</code>, but the result will always be. 1637 * <p> 1638 * The same as {@link #plus(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1639 * <p> 1640 * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code> 1641 * 1642 * @return A <code>BigDecimal</code> whose value is <code>+this</code>. 1643 */ 1644 plus()1645 public android.icu.math.BigDecimal plus() { 1646 return this.plus(plainMC); 1647 } 1648 1649 /** 1650 * Returns a <code>BigDecimal</code> whose value is <code>+this</code>. 1651 * <p> 1652 * Implements the plus (Prefix <b><code>+</code></b>) operator (as defined in the decimal documentation, see 1653 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1654 * <p> 1655 * This method is useful for rounding or otherwise applying a context to a decimal value. 1656 * 1657 * @param set The <code>MathContext</code> arithmetic settings. 1658 * @return A <code>BigDecimal</code> whose value is <code>+this</code>. 1659 */ 1660 plus(android.icu.math.MathContext set)1661 public android.icu.math.BigDecimal plus(android.icu.math.MathContext set) { 1662 // This clones and forces the result to the new settings 1663 // May return same object 1664 if (set.lostDigits) 1665 checkdigits((android.icu.math.BigDecimal) null, set.digits); 1666 // Optimization: returns same object for some common cases 1667 if (set.form == android.icu.math.MathContext.PLAIN) 1668 if (this.form == android.icu.math.MathContext.PLAIN) { 1669 if (this.mant.length <= set.digits) 1670 return this; 1671 if (set.digits == 0) 1672 return this; 1673 } 1674 return clone(this).finish(set, false); 1675 } 1676 1677 /** 1678 * Returns a plain <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic. 1679 * <p> 1680 * The same as {@link #pow(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the 1681 * context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1682 * <p> 1683 * The parameter is the power to which the <code>this</code> will be raised; it must be in the range 0 through 1684 * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so 1685 * they should not be used as a test for a whole number. 1686 * <p> 1687 * In addition, the power must not be negative, as no <code>MathContext</code> is used and so the result would then 1688 * always be 0. 1689 * 1690 * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power). 1691 * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic. 1692 * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number. 1693 */ 1694 pow(android.icu.math.BigDecimal rhs)1695 public android.icu.math.BigDecimal pow(android.icu.math.BigDecimal rhs) { 1696 return this.pow(rhs, plainMC); 1697 } 1698 1699 // The name for this method is inherited from the precedent set by the 1700 // BigInteger and Math classes. 1701 1702 /** 1703 * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>. 1704 * <p> 1705 * Implements the power (<b><code>^</code></b>) operator (as defined in the decimal documentation, see 1706 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1707 * <p> 1708 * The first parameter is the power to which the <code>this</code> will be raised; it must be in the range 1709 * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed 1710 * in the future, so they should not be used as a test for a whole number. 1711 * <p> 1712 * If the <code>digits</code> setting of the <code>MathContext</code> parameter is 0, the power must be zero or 1713 * positive. 1714 * 1715 * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power). 1716 * @param set The <code>MathContext</code> arithmetic settings. 1717 * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>. 1718 * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number. 1719 */ 1720 pow(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1721 public android.icu.math.BigDecimal pow(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1722 int n; 1723 android.icu.math.BigDecimal lhs; 1724 int reqdig; 1725 int workdigits = 0; 1726 int L = 0; 1727 android.icu.math.MathContext workset; 1728 android.icu.math.BigDecimal res; 1729 boolean seenbit; 1730 int i = 0; 1731 if (set.lostDigits) 1732 checkdigits(rhs, set.digits); 1733 n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules 1734 lhs = this; // clarified name 1735 1736 reqdig = set.digits; // local copy (heavily used) 1737 if (reqdig == 0) { 1738 if (rhs.ind == isneg) 1739 throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString()); 1740 workdigits = 0; 1741 } else {/* non-0 digits */ 1742 if ((rhs.mant.length + rhs.exp) > reqdig) 1743 throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); 1744 1745 /* Round the lhs to DIGITS if need be */ 1746 if (lhs.mant.length > reqdig) 1747 lhs = clone(lhs).round(set); 1748 1749 /* L for precision calculation [see ANSI X3.274-1996] */ 1750 L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp 1751 workdigits = (reqdig + L) + 1; // calculate the working DIGITS 1752 } 1753 1754 /* Create a copy of set for working settings */ 1755 // Note: no need to check for lostDigits again. 1756 // 1999.07.17 Note: this construction must follow RHS check 1757 workset = new android.icu.math.MathContext(workdigits, set.form, false, set.roundingMode); 1758 1759 res = ONE; // accumulator 1760 if (n == 0) 1761 return res; // x**0 == 1 1762 if (n < 0) 1763 n = -n; // [rhs.ind records the sign] 1764 seenbit = false; // set once we've seen a 1-bit 1765 { 1766 i = 1; 1767 i: for (;; i++) { // for each bit [top bit ignored] 1768 n = n + n; // shift left 1 bit 1769 if (n < 0) { // top bit is set 1770 seenbit = true; // OK, we're off 1771 res = res.multiply(lhs, workset); // acc=acc*x 1772 } 1773 if (i == 31) 1774 break i; // that was the last bit 1775 if ((!seenbit)) 1776 continue i; // we don't have to square 1 1777 res = res.multiply(res, workset); // acc=acc*acc [square] 1778 } 1779 }/* i */// 32 bits 1780 if (rhs.ind < 0) // was a **-n [hence digits>0] 1781 res = ONE.divide(res, workset); // .. so acc=1/acc 1782 return res.finish(set, true); // round and strip [original digits] 1783 } 1784 1785 /** 1786 * Returns a plain <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point 1787 * arithmetic. 1788 * <p> 1789 * The same as {@link #remainder(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, 1790 * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1791 * <p> 1792 * This is not the modulo operator -- the result may be negative. 1793 * 1794 * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation. 1795 * @return A <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point 1796 * arithmetic. 1797 * @throws ArithmeticException if <code>rhs</code> is zero. 1798 */ 1799 remainder(android.icu.math.BigDecimal rhs)1800 public android.icu.math.BigDecimal remainder(android.icu.math.BigDecimal rhs) { 1801 return this.dodivide('R', rhs, plainMC, -1); 1802 } 1803 1804 /** 1805 * Returns a <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>. 1806 * <p> 1807 * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}), 1808 * and returns the result as a <code>BigDecimal</code> object. 1809 * <p> 1810 * This is not the modulo operator -- the result may be negative. 1811 * 1812 * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation. 1813 * @param set The <code>MathContext</code> arithmetic settings. 1814 * @return A <code>BigDecimal</code> whose value is the remainder of <code>this+rhs</code>. 1815 * @throws ArithmeticException if <code>rhs</code> is zero. 1816 * @throws ArithmeticException if the integer part of the result will not fit in the number of digits specified for the context. 1817 */ 1818 remainder(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1819 public android.icu.math.BigDecimal remainder(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1820 return this.dodivide('R', rhs, set, -1); 1821 } 1822 1823 /** 1824 * Returns a plain <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic. 1825 * <p> 1826 * The same as {@link #subtract(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, 1827 * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>. 1828 * <p> 1829 * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. 1830 * 1831 * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction. 1832 * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic. 1833 */ 1834 subtract(android.icu.math.BigDecimal rhs)1835 public android.icu.math.BigDecimal subtract(android.icu.math.BigDecimal rhs) { 1836 return this.subtract(rhs, plainMC); 1837 } 1838 1839 /** 1840 * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>. 1841 * <p> 1842 * Implements the subtraction (<b><code>-</code></b>) operator (as defined in the decimal documentation, see 1843 * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object. 1844 * 1845 * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction. 1846 * @param set The <code>MathContext</code> arithmetic settings. 1847 * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>. 1848 */ 1849 subtract(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)1850 public android.icu.math.BigDecimal subtract(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set) { 1851 android.icu.math.BigDecimal newrhs; 1852 if (set.lostDigits) 1853 checkdigits(rhs, set.digits); 1854 // [add will recheck .. but would report -rhs] 1855 /* carry out the subtraction */ 1856 // we could fastpath -0, but it is too rare. 1857 newrhs = clone(rhs); // safe copy 1858 newrhs.ind = (byte) -newrhs.ind; // prepare to subtract 1859 return this.add(newrhs, set); // arithmetic 1860 } 1861 1862 /* ---------------------------------------------------------------- */ 1863 /* Other methods */ 1864 /* ---------------------------------------------------------------- */ 1865 1866 /** 1867 * Converts this <code>BigDecimal</code> to a <code>byte</code>. If the <code>BigDecimal</code> has a non-zero 1868 * decimal part or is out of the possible range for a <code>byte</code> (8-bit signed integer) result then an <code> 1869 * ArithmeticException</code> is thrown. 1870 * 1871 * @return A <code>byte</code> equal in value to <code>this</code>. 1872 * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>byte</code>. 1873 */ 1874 byteValueExact()1875 public byte byteValueExact() { 1876 int num; 1877 num = this.intValueExact(); // will check decimal part too 1878 if ((num > 127) | (num < (-128))) 1879 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 1880 return (byte) num; 1881 } 1882 1883 /** 1884 * Converts this <code>BigDecimal</code> to a <code>double</code>. If the <code>BigDecimal</code> is out of the 1885 * possible range for a <code>double</code> (64-bit signed floating point) result then an <code>ArithmeticException 1886 * </code> is thrown. 1887 * <p> 1888 * The double produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and 1889 * then converting it using the <code>Double(String)</code> constructor; this can result in values of <code> 1890 * Double.NEGATIVE_INFINITY</code> or <code>Double.POSITIVE_INFINITY</code>. 1891 * 1892 * @return A <code>double</code> corresponding to <code>this</code>. 1893 */ 1894 1895 @Override doubleValue()1896 public double doubleValue() { 1897 // We go via a String [as does BigDecimal in JDK 1.2] 1898 // Next line could possibly raise NumberFormatException 1899 return java.lang.Double.valueOf(this.toString()).doubleValue(); 1900 } 1901 1902 /** 1903 * Compares this <code>BigDecimal</code> with <code>rhs</code> for equality. 1904 * <p> 1905 * If the parameter is <code>null</code>, or is not an instance of the BigDecimal type, or is not exactly equal to 1906 * the current <code>BigDecimal</code> object, then <i>false</i> is returned. Otherwise, <i>true</i> is returned. 1907 * <p> 1908 * "Exactly equal", here, means that the <code>String</code> representations of the <code>BigDecimal</code> numbers 1909 * are identical (they have the same characters in the same sequence). 1910 * <p> 1911 * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons. 1912 * 1913 * @param obj The <code>Object</code> for the right hand side of the comparison. 1914 * @return A <code>boolean</code> whose value <i>true</i> if and only if the operands have identical string 1915 * representations. 1916 * @throws ClassCastException if <code>rhs</code> cannot be cast to a <code>BigDecimal</code> object. 1917 * @see #compareTo(BigDecimal) 1918 * @see #compareTo(BigDecimal, MathContext) 1919 */ 1920 1921 @Override equals(java.lang.Object obj)1922 public boolean equals(java.lang.Object obj) { 1923 android.icu.math.BigDecimal rhs; 1924 int i = 0; 1925 char lca[] = null; 1926 char rca[] = null; 1927 // We are equal iff toString of both are exactly the same 1928 if (obj == null) 1929 return false; // not equal 1930 if ((!(((obj instanceof android.icu.math.BigDecimal))))) 1931 return false; // not a decimal 1932 rhs = (android.icu.math.BigDecimal) obj; // cast; we know it will work 1933 if (this.ind != rhs.ind) 1934 return false; // different signs never match 1935 if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form)) 1936 1937 { // mantissas say all 1938 // here with equal-length byte arrays to compare 1939 { 1940 int $8 = this.mant.length; 1941 i = 0; 1942 for (; $8 > 0; $8--, i++) { 1943 if (this.mant[i] != rhs.mant[i]) 1944 return false; 1945 } 1946 }/* i */ 1947 } else { // need proper layout 1948 lca = this.layout(); // layout to character array 1949 rca = rhs.layout(); 1950 if (lca.length != rca.length) 1951 return false; // mismatch 1952 // here with equal-length character arrays to compare 1953 { 1954 int $9 = lca.length; 1955 i = 0; 1956 for (; $9 > 0; $9--, i++) { 1957 if (lca[i] != rca[i]) 1958 return false; 1959 } 1960 }/* i */ 1961 } 1962 return true; // arrays have identical content 1963 } 1964 1965 /** 1966 * Converts this <code>BigDecimal</code> to a <code>float</code>. If the <code>BigDecimal</code> is out of the 1967 * possible range for a <code>float</code> (32-bit signed floating point) result then an <code>ArithmeticException 1968 * </code> is thrown. 1969 * <p> 1970 * The float produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and 1971 * then converting it using the <code>Float(String)</code> constructor; this can result in values of <code> 1972 * Float.NEGATIVE_INFINITY</code> or <code>Float.POSITIVE_INFINITY</code>. 1973 * 1974 * @return A <code>float</code> corresponding to <code>this</code>. 1975 */ 1976 1977 @Override floatValue()1978 public float floatValue() { 1979 return java.lang.Float.valueOf(this.toString()).floatValue(); 1980 } 1981 1982 /** 1983 * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters. 1984 * <p> 1985 * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat 1986 * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a 1987 * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules 1988 * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. 1989 * </i> 1990 * <p> 1991 * The parameters, for both forms of the <code>format</code> method are all of type <code>int</code>. A value of -1 1992 * for any parameter indicates that the default action or value for that parameter should be used. 1993 * <p> 1994 * The parameters, <code>before</code> and <code>after</code>, specify the number of characters to be used for the 1995 * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter 1996 * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed 1997 * for that part. 1998 * <p> 1999 * <code>before</code> must be a positive number; if it is larger than is needed to contain the integer part, that 2000 * part is padded on the left with blanks to the requested length. If <code>before</code> is not large enough to 2001 * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown. 2002 * <p> 2003 * <code>after</code> must be a non-negative number; if it is not the same size as the decimal part of the number, 2004 * the number will be rounded (or extended with zeros) to fit. Specifying 0 for <code>after</code> will cause the 2005 * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method 2006 * will be the default, <code>MathContext.ROUND_HALF_UP</code>. 2007 * <p> 2008 * Other rounding methods, and the use of exponential notation, can be selected by using 2009 * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect 2010 * as using the six-parameter form with the final four parameters all being -1. 2011 * 2012 * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as are needed'. 2013 * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as are needed'. 2014 * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified parameters 2015 * @throws ArithmeticException if the number cannot be laid out as requested. 2016 * @throws IllegalArgumentException if a parameter is out of range. 2017 * @see #toString 2018 * @see #toCharArray 2019 */ 2020 format(int before, int after)2021 public java.lang.String format(int before, int after) { 2022 return format(before, after, -1, -1, android.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP); 2023 } 2024 2025 /** 2026 * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters and 2027 * allowing exponential notation. 2028 * <p> 2029 * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat 2030 * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a 2031 * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules 2032 * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. 2033 * </i> 2034 * <p> 2035 * The parameters are all of type <code>int</code>. A value of -1 for any parameter indicates that the default 2036 * action or value for that parameter should be used. 2037 * <p> 2038 * The first two parameters (<code>before</code> and <code>after</code>) specify the number of characters to be used 2039 * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If 2040 * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many 2041 * as are needed for that part. 2042 * <p> 2043 * The remaining parameters control the use of exponential notation and rounding. Three (<code>explaces</code>, 2044 * <code>exdigits</code>, and <code>exform</code>) control the exponent part of the result. As before, the default 2045 * action for any of these parameters may be selected by using the value -1. 2046 * <p> 2047 * <code>explaces</code> must be a positive number; it sets the number of places (digits after the sign of the 2048 * exponent) to be used for any exponent part, the default (when <code>explaces</code> is -1) being to use as many 2049 * as are needed. If <code>explaces</code> is not -1, space is always reserved for an exponent; if one is not needed 2050 * (for example, if the exponent will be 0) then <code>explaces</code>+2 blanks are appended to the result. 2051 * (This preserves vertical alignment of similarly formatted numbers in a monospace font.) If <code>explaces 2052 * </code> is not -1 and is not large enough to contain the exponent, an exception is thrown. 2053 * <p> 2054 * <code>exdigits</code> sets the trigger point for use of exponential notation. If, before any rounding, the number 2055 * of places needed before the decimal point exceeds <code>exdigits</code>, or if the absolute value of the result 2056 * is less than <code>0.000001</code>, then exponential form will be used, provided that <code>exdigits</code> was 2057 * specified. When <code>exdigits</code> is -1, exponential notation will never be used. If 0 is specified for 2058 * <code>exdigits</code>, exponential notation is always used unless the exponent would be 0. 2059 * <p> 2060 * <code>exform</code> sets the form for exponential notation (if needed). It may be either 2061 * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested, 2062 * up to three digits (plus sign, if negative) may be needed for the integer part of the result (<code>before</code> 2063 * ). Otherwise, only one digit (plus sign, if negative) is needed. 2064 * <p> 2065 * Finally, the sixth argument, <code>exround</code>, selects the rounding algorithm to be used, and must be one of 2066 * the values indicated by a public constant in the {@link MathContext} class whose name starts with <code>ROUND_ 2067 * </code>. The default (<code>ROUND_HALF_UP</code>) may also be selected by using the value -1, as before. 2068 * <p> 2069 * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be used to detect whether non-zero digits are 2070 * discarded -- if <code>exround</code> has this value than if non-zero digits would be discarded (rounded) during 2071 * formatting then an <code>ArithmeticException</code> is thrown. 2072 * 2073 * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as 2074 * are needed'. 2075 * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as 2076 * are needed'. 2077 * @param explaces The <code>int</code> specifying the number of places to be used for any exponent. Use -1 for 'as many 2078 * as are needed'. 2079 * @param exdigits The <code>int</code> specifying the trigger (digits before the decimal point) which if exceeded causes 2080 * exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation 2081 * (no exponential notation). 2082 * @param exformint The <code>int</code> specifying the form of exponential notation to be used ( 2083 * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}). 2084 * @param exround The <code>int</code> specifying the rounding mode to use. Use -1 for the default, 2085 * {@link MathContext#ROUND_HALF_UP}. 2086 * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified 2087 * parameters 2088 * @throws ArithmeticException if the number cannot be laid out as requested. 2089 * @throws IllegalArgumentException if a parameter is out of range. 2090 * @see #toString 2091 * @see #toCharArray 2092 */ 2093 format(int before, int after, int explaces, int exdigits, int exformint, int exround)2094 public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) { 2095 android.icu.math.BigDecimal num; 2096 int mag = 0; 2097 int thisafter = 0; 2098 int lead = 0; 2099 byte newmant[] = null; 2100 int chop = 0; 2101 int need = 0; 2102 int oldexp = 0; 2103 char a[]; 2104 int p = 0; 2105 char newa[] = null; 2106 int i = 0; 2107 int places = 0; 2108 2109 /* Check arguments */ 2110 if ((before < (-1)) | (before == 0)) 2111 badarg("format", 1, java.lang.String.valueOf(before)); 2112 if (after < (-1)) 2113 badarg("format", 2, java.lang.String.valueOf(after)); 2114 if ((explaces < (-1)) | (explaces == 0)) 2115 badarg("format", 3, java.lang.String.valueOf(explaces)); 2116 if (exdigits < (-1)) 2117 badarg("format", 4, java.lang.String.valueOf(explaces)); 2118 {/* select */ 2119 if (exformint == android.icu.math.MathContext.SCIENTIFIC) { 2120 } else if (exformint == android.icu.math.MathContext.ENGINEERING) { 2121 } else if (exformint == (-1)) 2122 exformint = android.icu.math.MathContext.SCIENTIFIC; 2123 // note PLAIN isn't allowed 2124 else { 2125 badarg("format", 5, java.lang.String.valueOf(exformint)); 2126 } 2127 } 2128 // checking the rounding mode is done by trying to construct a 2129 // MathContext object with that mode; it will fail if bad 2130 if (exround != ROUND_HALF_UP) { 2131 try { // if non-default... 2132 if (exround == (-1)) 2133 exround = ROUND_HALF_UP; 2134 else 2135 new android.icu.math.MathContext(9, android.icu.math.MathContext.SCIENTIFIC, false, exround); 2136 } catch (java.lang.IllegalArgumentException $10) { 2137 badarg("format", 6, java.lang.String.valueOf(exround)); 2138 } 2139 } 2140 2141 num = clone(this); // make private copy 2142 2143 /* 2144 * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0] 2145 * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two] 2146 * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified 2147 */ 2148 2149 /* determine form */ 2150 { 2151 do {/* select */ 2152 if (exdigits == (-1)) 2153 num.form = (byte) android.icu.math.MathContext.PLAIN; 2154 else if (num.ind == iszero) 2155 num.form = (byte) android.icu.math.MathContext.PLAIN; 2156 else { 2157 // determine whether triggers 2158 mag = num.exp + num.mant.length; 2159 if (mag > exdigits) 2160 num.form = (byte) exformint; 2161 else if (mag < (-5)) 2162 num.form = (byte) exformint; 2163 else 2164 num.form = (byte) android.icu.math.MathContext.PLAIN; 2165 } 2166 } while (false); 2167 }/* setform */ 2168 2169 /* 2170 * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform 2171 * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific). 2172 */ 2173 if (after >= 0) { 2174 setafter: for (;;) { 2175 // calculate the current after-length 2176 {/* select */ 2177 if (num.form == android.icu.math.MathContext.PLAIN) 2178 thisafter = -num.exp; // has decimal part 2179 else if (num.form == android.icu.math.MathContext.SCIENTIFIC) 2180 thisafter = num.mant.length - 1; 2181 else { // engineering 2182 lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use 2183 if (lead < 0) 2184 lead = 3 + lead; // negative exponent case 2185 lead++; // number of leading digits 2186 if (lead >= num.mant.length) 2187 thisafter = 0; 2188 else 2189 thisafter = num.mant.length - lead; 2190 } 2191 } 2192 if (thisafter == after) 2193 break setafter; // we're in luck 2194 if (thisafter < after) { // need added trailing zeros 2195 // [thisafter can be negative] 2196 newmant = extend(num.mant, (num.mant.length + after) - thisafter); 2197 num.mant = newmant; 2198 num.exp = num.exp - ((after - thisafter)); // adjust exponent 2199 if (num.exp < MinExp) 2200 throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp); 2201 break setafter; 2202 } 2203 // We have too many digits after the decimal point; this could 2204 // cause a carry, which could change the mantissa... 2205 // Watch out for implied leading zeros in PLAIN case 2206 chop = thisafter - after; // digits to lop [is >0] 2207 if (chop > num.mant.length) { // all digits go, no chance of carry 2208 // carry on with zero 2209 num.mant = ZERO.mant; 2210 num.ind = iszero; 2211 num.exp = 0; 2212 continue setafter; // recheck: we may need trailing zeros 2213 } 2214 // we have a digit to inspect from existing mantissa 2215 // round the number as required 2216 need = num.mant.length - chop; // digits to end up with [may be 0] 2217 oldexp = num.exp; // save old exponent 2218 num.round(need, exround); 2219 // if the exponent grew by more than the digits we chopped, then 2220 // we must have had a carry, so will need to recheck the layout 2221 if ((num.exp - oldexp) == chop) 2222 break setafter; // number did not have carry 2223 // mantissa got extended .. so go around and check again 2224 } 2225 }/* setafter */ 2226 2227 a = num.layout(); // lay out, with exponent if required, etc. 2228 2229 /* Here we have laid-out number in 'a' */ 2230 // now apply 'before' and 'explaces' as needed 2231 if (before > 0) { 2232 // look for '.' or 'E' 2233 { 2234 int $11 = a.length; 2235 p = 0; 2236 p: for (; $11 > 0; $11--, p++) { 2237 if (a[p] == '.') 2238 break p; 2239 if (a[p] == 'E') 2240 break p; 2241 } 2242 }/* p */ 2243 // p is now offset of '.', 'E', or character after end of array 2244 // that is, the current length of before part 2245 if (p > before) 2246 badarg("format", 1, java.lang.String.valueOf(before)); // won't fit 2247 if (p < before) { // need leading blanks 2248 newa = new char[(a.length + before) - p]; 2249 { 2250 int $12 = before - p; 2251 i = 0; 2252 for (; $12 > 0; $12--, i++) { 2253 newa[i] = ' '; 2254 } 2255 }/* i */ 2256 java.lang.System.arraycopy(a, 0, newa, i, a.length); 2257 a = newa; 2258 } 2259 // [if p=before then it's just the right length] 2260 } 2261 2262 if (explaces > 0) { 2263 // look for 'E' [cannot be at offset 0] 2264 { 2265 int $13 = a.length - 1; 2266 p = a.length - 1; 2267 p: for (; $13 > 0; $13--, p--) { 2268 if (a[p] == 'E') 2269 break p; 2270 } 2271 }/* p */ 2272 // p is now offset of 'E', or 0 2273 if (p == 0) { // no E part; add trailing blanks 2274 newa = new char[(a.length + explaces) + 2]; 2275 java.lang.System.arraycopy(a, 0, newa, 0, a.length); 2276 { 2277 int $14 = explaces + 2; 2278 i = a.length; 2279 for (; $14 > 0; $14--, i++) { 2280 newa[i] = ' '; 2281 } 2282 }/* i */ 2283 a = newa; 2284 } else {/* found E */// may need to insert zeros 2285 places = (a.length - p) - 2; // number so far 2286 if (places > explaces) 2287 badarg("format", 3, java.lang.String.valueOf(explaces)); 2288 if (places < explaces) { // need to insert zeros 2289 newa = new char[(a.length + explaces) - places]; 2290 java.lang.System.arraycopy(a, 0, newa, 0, p + 2); // through E 2291 // and sign 2292 { 2293 int $15 = explaces - places; 2294 i = p + 2; 2295 for (; $15 > 0; $15--, i++) { 2296 newa[i] = '0'; 2297 } 2298 }/* i */ 2299 java.lang.System.arraycopy(a, p + 2, newa, i, places); // remainder 2300 // of 2301 // exponent 2302 a = newa; 2303 } 2304 // [if places=explaces then it's just the right length] 2305 } 2306 } 2307 return new java.lang.String(a); 2308 } 2309 2310 /** 2311 * Returns the hashcode for this <code>BigDecimal</code>. This hashcode is suitable for use by the <code> 2312 * java.util.Hashtable</code> class. 2313 * <p> 2314 * Note that two <code>BigDecimal</code> objects are only guaranteed to produce the same hashcode if they are 2315 * exactly equal (that is, the <code>String</code> representations of the <code>BigDecimal</code> numbers are 2316 * identical -- they have the same characters in the same sequence). 2317 * 2318 * @return An <code>int</code> that is the hashcode for <code>this</code>. 2319 */ 2320 2321 @Override hashCode()2322 public int hashCode() { 2323 // Maybe calculate ourselves, later. If so, note that there can be 2324 // more than one internal representation for a given toString() result. 2325 return this.toString().hashCode(); 2326 } 2327 2328 /** 2329 * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero 2330 * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for an <code>int</code> 2331 * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be 2332 * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact} 2333 * method. 2334 * 2335 * @return An <code>int</code> converted from <code>this</code>, truncated and decapitated if necessary. 2336 */ 2337 2338 @Override intValue()2339 public int intValue() { 2340 return toBigInteger().intValue(); 2341 } 2342 2343 /** 2344 * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero 2345 * decimal part or is out of the possible range for an <code>int</code> (32-bit signed integer) result then an 2346 * <code>ArithmeticException</code> is thrown. 2347 * 2348 * @return An <code>int</code> equal in value to <code>this</code>. 2349 * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in an <code>int</code>. 2350 */ 2351 intValueExact()2352 public int intValueExact() { 2353 int lodigit; 2354 int useexp = 0; 2355 int result; 2356 int i = 0; 2357 int topdig = 0; 2358 // This does not use longValueExact() as the latter can be much 2359 // slower. 2360 // intcheck (from pow) relies on this to check decimal part 2361 if (ind == iszero) 2362 return 0; // easy, and quite common 2363 /* test and drop any trailing decimal part */ 2364 lodigit = mant.length - 1; 2365 if (exp < 0) { 2366 lodigit = lodigit + exp; // reduces by -(-exp) 2367 /* all decimal places must be 0 */ 2368 if ((!(allzero(mant, lodigit + 1)))) 2369 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); 2370 if (lodigit < 0) 2371 return 0; // -1<this<1 2372 useexp = 0; 2373 } else {/* >=0 */ 2374 if ((exp + lodigit) > 9) // early exit 2375 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 2376 useexp = exp; 2377 } 2378 /* convert the mantissa to binary, inline for speed */ 2379 result = 0; 2380 { 2381 int $16 = lodigit + useexp; 2382 i = 0; 2383 for (; i <= $16; i++) { 2384 result = result * 10; 2385 if (i <= lodigit) 2386 result = result + mant[i]; 2387 } 2388 }/* i */ 2389 2390 /* Now, if the risky length, check for overflow */ 2391 if ((lodigit + useexp) == 9) { 2392 // note we cannot just test for -ve result, as overflow can move a 2393 // zero into the top bit [consider 5555555555] 2394 topdig = result / 1000000000; // get top digit, preserving sign 2395 if (topdig != mant[0]) { // digit must match and be positive 2396 // except in the special case ... 2397 if (result == java.lang.Integer.MIN_VALUE) // looks like the special 2398 if (ind == isneg) // really was negative 2399 if (mant[0] == 2) 2400 return result; // really had top digit 2 2401 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 2402 } 2403 } 2404 2405 /* Looks good */ 2406 if (ind == ispos) 2407 return result; 2408 return -result; 2409 } 2410 2411 /** 2412 * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero 2413 * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for a <code>long</code> 2414 * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be 2415 * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact} 2416 * method. 2417 * 2418 * @return A <code>long</code> converted from <code>this</code>, truncated and decapitated if necessary. 2419 */ 2420 2421 @Override longValue()2422 public long longValue() { 2423 return toBigInteger().longValue(); 2424 } 2425 2426 /** 2427 * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero 2428 * decimal part or is out of the possible range for a <code>long</code> (64-bit signed integer) result then an 2429 * <code>ArithmeticException</code> is thrown. 2430 * 2431 * @return A <code>long</code> equal in value to <code>this</code>. 2432 * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>long</code>. 2433 */ 2434 longValueExact()2435 public long longValueExact() { 2436 int lodigit; 2437 int cstart = 0; 2438 int useexp = 0; 2439 long result; 2440 int i = 0; 2441 long topdig = 0; 2442 // Identical to intValueExact except for result=long, and exp>=20 test 2443 if (ind == 0) 2444 return 0; // easy, and quite common 2445 lodigit = mant.length - 1; // last included digit 2446 if (exp < 0) { 2447 lodigit = lodigit + exp; // -(-exp) 2448 /* all decimal places must be 0 */ 2449 if (lodigit < 0) 2450 cstart = 0; 2451 else 2452 cstart = lodigit + 1; 2453 if ((!(allzero(mant, cstart)))) 2454 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); 2455 if (lodigit < 0) 2456 return 0; // -1<this<1 2457 useexp = 0; 2458 } else {/* >=0 */ 2459 if ((exp + mant.length) > 18) // early exit 2460 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 2461 useexp = exp; 2462 } 2463 2464 /* convert the mantissa to binary, inline for speed */ 2465 // note that we could safely use the 'test for wrap to negative' 2466 // algorithm here, but instead we parallel the intValueExact 2467 // algorithm for ease of checking and maintenance. 2468 result = 0; 2469 { 2470 int $17 = lodigit + useexp; 2471 i = 0; 2472 for (; i <= $17; i++) { 2473 result = result * 10; 2474 if (i <= lodigit) 2475 result = result + mant[i]; 2476 } 2477 }/* i */ 2478 2479 /* Now, if the risky length, check for overflow */ 2480 if ((lodigit + useexp) == 18) { 2481 topdig = result / 1000000000000000000L; // get top digit, preserving sign 2482 if (topdig != mant[0]) { // digit must match and be positive 2483 // except in the special case ... 2484 if (result == java.lang.Long.MIN_VALUE) // looks like the special 2485 if (ind == isneg) // really was negative 2486 if (mant[0] == 9) 2487 return result; // really had top digit 9 2488 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 2489 } 2490 } 2491 2492 /* Looks good */ 2493 if (ind == ispos) 2494 return result; 2495 return -result; 2496 } 2497 2498 /** 2499 * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the left by a specified number of 2500 * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is, 2501 * if <code>n</code> is 0 or positive, the number returned is given by: 2502 * <p> 2503 * <code> this.multiply(TEN.pow(new BigDecimal(-n))) </code> 2504 * <p> 2505 * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointRight(-n) 2506 * </code>. 2507 * 2508 * @param n The <code>int</code> specifying the number of places to move the decimal point leftwards. 2509 * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code> 2510 * places to the left. 2511 */ 2512 movePointLeft(int n)2513 public android.icu.math.BigDecimal movePointLeft(int n) { 2514 android.icu.math.BigDecimal res; 2515 // very little point in optimizing for shift of 0 2516 res = clone(this); 2517 res.exp = res.exp - n; 2518 return res.finish(plainMC, false); // finish sets form and checks exponent 2519 } 2520 2521 /** 2522 * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the right by a specified number of 2523 * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is, 2524 * if <code>n</code> is 0 or positive, the number returned is given by: 2525 * <p> 2526 * <code> this.multiply(TEN.pow(new BigDecimal(n))) </code> 2527 * <p> 2528 * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointLeft(-n) 2529 * </code>. 2530 * 2531 * @param n The <code>int</code> specifying the number of places to move the decimal point rightwards. 2532 * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code> 2533 * places to the right. 2534 */ 2535 movePointRight(int n)2536 public android.icu.math.BigDecimal movePointRight(int n) { 2537 android.icu.math.BigDecimal res; 2538 res = clone(this); 2539 res.exp = res.exp + n; 2540 return res.finish(plainMC, false); 2541 } 2542 2543 /** 2544 * Returns the scale of this <code>BigDecimal</code>. Returns a non-negative <code>int</code> which is the scale of 2545 * the number. The scale is the number of digits in the decimal part of the number if the number were formatted 2546 * without exponential notation. 2547 * 2548 * @return An <code>int</code> whose value is the scale of this <code>BigDecimal</code>. 2549 */ 2550 scale()2551 public int scale() { 2552 if (exp >= 0) 2553 return 0; // scale can never be negative 2554 return -exp; 2555 } 2556 2557 /** 2558 * Returns a plain <code>BigDecimal</code> with a given scale. 2559 * <p> 2560 * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part 2561 * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary. 2562 * <p> 2563 * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then 2564 * trailing digits will be removed, and in this case an <code>ArithmeticException</code> is thrown if any discarded 2565 * digits are non-zero. 2566 * <p> 2567 * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is <code> 2568 * MathContext.ROUND_UNNECESSARY</code>. 2569 * 2570 * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>. 2571 * @return A plain <code>BigDecimal</code> with the given scale. 2572 * @throws ArithmeticException if <code>scale</code> is negative. 2573 * @throws ArithmeticException if reducing scale would discard non-zero digits. 2574 */ 2575 setScale(int scale)2576 public android.icu.math.BigDecimal setScale(int scale) { 2577 return setScale(scale, ROUND_UNNECESSARY); 2578 } 2579 2580 /** 2581 * Returns a plain <code>BigDecimal</code> with a given scale. 2582 * <p> 2583 * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part 2584 * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary. 2585 * <p> 2586 * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then 2587 * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the 2588 * remaining digits are affected by a carry. In this case, an <code>IllegalArgumentException</code> is thrown if 2589 * <code>round</code> is not a valid rounding mode. 2590 * <p> 2591 * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, an <code>ArithmeticException</code> is 2592 * thrown if any discarded digits are non-zero. 2593 * 2594 * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>. 2595 * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class). 2596 * @return A plain <code>BigDecimal</code> with the given scale. 2597 * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode. 2598 * @throws ArithmeticException if <code>scale</code> is negative. 2599 * @throws ArithmeticException if <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, and reducing scale would discard 2600 * non-zero digits. 2601 */ 2602 setScale(int scale, int round)2603 public android.icu.math.BigDecimal setScale(int scale, int round) { 2604 int ourscale; 2605 android.icu.math.BigDecimal res; 2606 int padding = 0; 2607 int newlen = 0; 2608 // at present this naughtily only checks the round value if it is 2609 // needed (used), for speed 2610 ourscale = this.scale(); 2611 if (ourscale == scale) // already correct scale 2612 if (this.form == android.icu.math.MathContext.PLAIN) // .. and form 2613 return this; 2614 res = clone(this); // need copy 2615 if (ourscale <= scale) { // simply zero-padding/changing form 2616 // if ourscale is 0 we may have lots of 0s to add 2617 if (ourscale == 0) 2618 padding = res.exp + scale; 2619 else 2620 padding = scale - ourscale; 2621 res.mant = extend(res.mant, res.mant.length + padding); 2622 res.exp = -scale; // as requested 2623 } else {/* ourscale>scale: shortening, probably */ 2624 if (scale < 0) 2625 throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); 2626 // [round() will raise exception if invalid round] 2627 newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK] 2628 res = res.round(newlen, round); // round to required length 2629 // This could have shifted left if round (say) 0.9->1[.0] 2630 // Repair if so by adding a zero and reducing exponent 2631 if (res.exp != -scale) { 2632 res.mant = extend(res.mant, res.mant.length + 1); 2633 res.exp = res.exp - 1; 2634 } 2635 } 2636 res.form = (byte) android.icu.math.MathContext.PLAIN; // by definition 2637 return res; 2638 } 2639 2640 /** 2641 * Converts this <code>BigDecimal</code> to a <code>short</code>. If the <code>BigDecimal</code> has a non-zero 2642 * decimal part or is out of the possible range for a <code>short</code> (16-bit signed integer) result then an 2643 * <code>ArithmeticException</code> is thrown. 2644 * 2645 * @return A <code>short</code> equal in value to <code>this</code>. 2646 * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>short</code>. 2647 */ 2648 shortValueExact()2649 public short shortValueExact() { 2650 int num; 2651 num = this.intValueExact(); // will check decimal part too 2652 if ((num > 32767) | (num < (-32768))) 2653 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); 2654 return (short) num; 2655 } 2656 2657 /** 2658 * Returns the sign of this <code>BigDecimal</code>, as an <code>int</code>. This returns the <i>signum</i> function 2659 * value that represents the sign of this <code>BigDecimal</code>. That is, -1 if the <code>BigDecimal</code> is 2660 * negative, 0 if it is numerically equal to zero, or 1 if it is positive. 2661 * 2662 * @return An <code>int</code> which is -1 if the <code>BigDecimal</code> is negative, 0 if it is numerically equal 2663 * to zero, or 1 if it is positive. 2664 */ 2665 signum()2666 public int signum() { 2667 return this.ind; // [note this assumes values for ind.] 2668 } 2669 2670 /** 2671 * Converts this <code>BigDecimal</code> to a <code>java.math.BigDecimal</code>. 2672 * <p> 2673 * This is an exact conversion; the result is the same as if the <code>BigDecimal</code> were formatted as a plain 2674 * number without any rounding or exponent and then the <code>java.math.BigDecimal(java.lang.String)</code> 2675 * constructor were used to construct the result. 2676 * <p> 2677 * <i>(Note: this method is provided only in the <code>android.icu.math</code> version of the BigDecimal class. It 2678 * would not be present in a <code>java.math</code> version.)</i> 2679 * 2680 * @return The <code>java.math.BigDecimal</code> equal in value to this <code>BigDecimal</code>. 2681 */ 2682 toBigDecimal()2683 public java.math.BigDecimal toBigDecimal() { 2684 return new java.math.BigDecimal(this.unscaledValue(), this.scale()); 2685 } 2686 2687 /** 2688 * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>. 2689 * <p> 2690 * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use 2691 * {@link #toBigIntegerExact()}. 2692 * 2693 * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>. 2694 */ 2695 toBigInteger()2696 public java.math.BigInteger toBigInteger() { 2697 android.icu.math.BigDecimal res = null; 2698 int newlen = 0; 2699 byte newmant[] = null; 2700 {/* select */ 2701 if ((exp >= 0) & (form == android.icu.math.MathContext.PLAIN)) 2702 res = this; // can layout simply 2703 else if (exp >= 0) { 2704 res = clone(this); // safe copy 2705 res.form = (byte) android.icu.math.MathContext.PLAIN; // .. and request PLAIN 2706 } else { 2707 { // exp<0; scale to be truncated 2708 // we could use divideInteger, but we may as well be quicker 2709 if (-this.exp >= this.mant.length) 2710 res = ZERO; // all blows away 2711 else { 2712 res = clone(this); // safe copy 2713 newlen = res.mant.length + res.exp; 2714 newmant = new byte[newlen]; // [shorter] 2715 java.lang.System.arraycopy(res.mant, 0, newmant, 0, 2716 newlen); 2717 res.mant = newmant; 2718 res.form = (byte) android.icu.math.MathContext.PLAIN; 2719 res.exp = 0; 2720 } 2721 } 2722 } 2723 } 2724 return new BigInteger(new java.lang.String(res.layout())); 2725 } 2726 2727 /** 2728 * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>. 2729 * <p> 2730 * An exception is thrown if the decimal part (if any) is non-zero. 2731 * 2732 * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>. 2733 * @throws ArithmeticException if <code>this</code> has a non-zero decimal part. 2734 */ 2735 toBigIntegerExact()2736 public java.math.BigInteger toBigIntegerExact() { 2737 /* test any trailing decimal part */ 2738 if (exp < 0) { // possible decimal part 2739 /* all decimal places must be 0; note exp<0 */ 2740 if ((!(allzero(mant, mant.length + exp)))) 2741 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); 2742 } 2743 return toBigInteger(); 2744 } 2745 2746 /** 2747 * Returns the <code>BigDecimal</code> as a character array. The result of this method is the same as using the 2748 * sequence <code>toString().toCharArray()</code>, but avoids creating the intermediate <code>String</code> and 2749 * <code>char[]</code> objects. 2750 * 2751 * @return The <code>char[]</code> array corresponding to this <code>BigDecimal</code>. 2752 */ 2753 toCharArray()2754 public char[] toCharArray() { 2755 return layout(); 2756 } 2757 2758 /** 2759 * Returns the <code>BigDecimal</code> as a <code>String</code>. This returns a <code>String</code> that exactly 2760 * represents this <code>BigDecimal</code>, as defined in the decimal documentation (see {@link BigDecimal class 2761 * header}). 2762 * <p> 2763 * By definition, using the {@link #BigDecimal(String)} constructor on the result <code>String</code> will create a 2764 * <code>BigDecimal</code> that is exactly equal to the original <code>BigDecimal</code>. 2765 * 2766 * @return The <code>String</code> exactly corresponding to this <code>BigDecimal</code>. 2767 * @see #format(int, int) 2768 * @see #format(int, int, int, int, int, int) 2769 * @see #toCharArray() 2770 */ 2771 2772 @Override toString()2773 public java.lang.String toString() { 2774 return new java.lang.String(layout()); 2775 } 2776 2777 /** 2778 * Returns the number as a <code>BigInteger</code> after removing the scale. That is, the number is expressed as a 2779 * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is 2780 * then converted to a <code>BigInteger</code>. 2781 * 2782 * @return The <code>java.math.BigInteger</code> equal in value to this <code>BigDecimal</code> multiplied by ten to 2783 * the power of <code>this.scale()</code>. 2784 */ 2785 unscaledValue()2786 public java.math.BigInteger unscaledValue() { 2787 android.icu.math.BigDecimal res = null; 2788 if (exp >= 0) 2789 res = this; 2790 else { 2791 res = clone(this); // safe copy 2792 res.exp = 0; // drop scale 2793 } 2794 return res.toBigInteger(); 2795 } 2796 2797 /** 2798 * Translates a <code>double</code> to a <code>BigDecimal</code>. 2799 * <p> 2800 * Returns a <code>BigDecimal</code> which is the decimal representation of the 64-bit signed binary floating point 2801 * parameter. If the parameter is infinite, or is not a number (NaN), a <code>NumberFormatException</code> is 2802 * thrown. 2803 * <p> 2804 * The number is constructed as though <code>num</code> had been converted to a <code>String</code> using the <code> 2805 * Double.toString()</code> method and the {@link #BigDecimal(java.lang.String)} constructor had then been used. 2806 * This is typically not an exact conversion. 2807 * 2808 * @param dub The <code>double</code> to be translated. 2809 * @return The <code>BigDecimal</code> equal in value to <code>dub</code>. 2810 * @throws NumberFormatException if the parameter is infinite or not a number. 2811 */ 2812 valueOf(double dub)2813 public static android.icu.math.BigDecimal valueOf(double dub) { 2814 // Reminder: a zero double returns '0.0', so we cannot fastpath to 2815 // use the constant ZERO. This might be important enough to justify 2816 // a factory approach, a cache, or a few private constants, later. 2817 return new android.icu.math.BigDecimal((new java.lang.Double(dub)).toString()); 2818 } 2819 2820 /** 2821 * Translates a <code>long</code> to a <code>BigDecimal</code>. That is, returns a plain <code>BigDecimal</code> 2822 * whose value is equal to the given <code>long</code>. 2823 * 2824 * @param lint The <code>long</code> to be translated. 2825 * @return The <code>BigDecimal</code> equal in value to <code>lint</code>. 2826 */ 2827 valueOf(long lint)2828 public static android.icu.math.BigDecimal valueOf(long lint) { 2829 return valueOf(lint, 0); 2830 } 2831 2832 /** 2833 * Translates a <code>long</code> to a <code>BigDecimal</code> with a given scale. That is, returns a plain <code> 2834 * BigDecimal</code> whose unscaled value is equal to the given <code>long</code>, adjusted by the second parameter, 2835 * <code>scale</code>. 2836 * <p> 2837 * The result is given by: 2838 * <p> 2839 * <code> (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) </code> 2840 * <p> 2841 * A <code>NumberFormatException</code> is thrown if <code>scale</code> is negative. 2842 * 2843 * @param lint The <code>long</code> to be translated. 2844 * @param scale The <code>int</code> scale to be applied. 2845 * @return The <code>BigDecimal</code> equal in value to <code>lint</code>. 2846 * @throws NumberFormatException if the scale is negative. 2847 */ 2848 valueOf(long lint, int scale)2849 public static android.icu.math.BigDecimal valueOf(long lint, int scale) { 2850 android.icu.math.BigDecimal res = null; 2851 {/* select */ 2852 if (lint == 0) 2853 res = ZERO; 2854 else if (lint == 1) 2855 res = ONE; 2856 else if (lint == 10) 2857 res = TEN; 2858 else { 2859 res = new android.icu.math.BigDecimal(lint); 2860 } 2861 } 2862 if (scale == 0) 2863 return res; 2864 if (scale < 0) 2865 throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); 2866 res = clone(res); // safe copy [do not mutate] 2867 res.exp = -scale; // exponent is -scale 2868 return res; 2869 } 2870 2871 /* ---------------------------------------------------------------- */ 2872 /* Private methods */ 2873 /* ---------------------------------------------------------------- */ 2874 2875 /* 2876 * <sgml> Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array). 2877 * <p>The mantissa will either already have been rounded (following an operation) or will be of length appropriate 2878 * (in the case of construction from an int, for example). <p>We must not alter the mantissa, here. <p>'form' 2879 * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure 2880 * numeric. </sgml> 2881 */ 2882 layout()2883 private char[] layout() { 2884 char cmant[]; 2885 int i = 0; 2886 StringBuilder sb = null; 2887 int euse = 0; 2888 int sig = 0; 2889 char csign = 0; 2890 char rec[] = null; 2891 int needsign; 2892 int mag; 2893 int len = 0; 2894 cmant = new char[mant.length]; // copy byte[] to a char[] 2895 { 2896 int $18 = mant.length; 2897 i = 0; 2898 for (; $18 > 0; $18--, i++) { 2899 cmant[i] = (char) (mant[i] + (('0'))); 2900 } 2901 }/* i */ 2902 2903 if (form != android.icu.math.MathContext.PLAIN) {/* exponential notation needed */ 2904 sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999 2905 if (ind == isneg) 2906 sb.append('-'); 2907 euse = (exp + cmant.length) - 1; // exponent to use 2908 /* setup sig=significant digits and copy to result */ 2909 if (form == android.icu.math.MathContext.SCIENTIFIC) { // [default] 2910 sb.append(cmant[0]); // significant character 2911 if (cmant.length > 1) // have decimal part 2912 sb.append('.').append(cmant, 1, cmant.length - 1); 2913 } else { 2914 do { 2915 sig = euse % 3; // common 2916 if (sig < 0) 2917 sig = 3 + sig; // negative exponent 2918 euse = euse - sig; 2919 sig++; 2920 if (sig >= cmant.length) { // zero padding may be needed 2921 sb.append(cmant, 0, cmant.length); 2922 { 2923 int $19 = sig - cmant.length; 2924 for (; $19 > 0; $19--) { 2925 sb.append('0'); 2926 } 2927 } 2928 } else { // decimal point needed 2929 sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig); 2930 } 2931 } while (false); 2932 }/* engineering */ 2933 if (euse != 0) { 2934 if (euse < 0) { 2935 csign = '-'; 2936 euse = -euse; 2937 } else 2938 csign = '+'; 2939 sb.append('E').append(csign).append(euse); 2940 } 2941 rec = new char[sb.length()]; 2942 int srcEnd = sb.length(); 2943 if (0 != srcEnd) { 2944 sb.getChars(0, srcEnd, rec, 0); 2945 } 2946 return rec; 2947 } 2948 2949 /* Here for non-exponential (plain) notation */ 2950 if (exp == 0) {/* easy */ 2951 if (ind >= 0) 2952 return cmant; // non-negative integer 2953 rec = new char[cmant.length + 1]; 2954 rec[0] = '-'; 2955 java.lang.System.arraycopy(cmant, 0, rec, 1, cmant.length); 2956 return rec; 2957 } 2958 2959 /* Need a '.' and/or some zeros */ 2960 needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1 2961 2962 /* 2963 * MAG is the position of the point in the mantissa (index of the character it follows) 2964 */ 2965 mag = exp + cmant.length; 2966 2967 if (mag < 1) {/* 0.00xxxx form */ 2968 len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length 2969 rec = new char[len]; 2970 if (needsign != 0) 2971 rec[0] = '-'; 2972 rec[needsign] = '0'; 2973 rec[needsign + 1] = '.'; 2974 { 2975 int $20 = -mag; 2976 i = needsign + 2; 2977 for (; $20 > 0; $20--, i++) { // maybe none 2978 rec[i] = '0'; 2979 } 2980 }/* i */ 2981 java.lang.System.arraycopy(cmant, 0, rec, (needsign + 2) - mag, 2982 cmant.length); 2983 return rec; 2984 } 2985 2986 if (mag > cmant.length) {/* xxxx0000 form */ 2987 len = needsign + mag; 2988 rec = new char[len]; 2989 if (needsign != 0) 2990 rec[0] = '-'; 2991 java.lang.System.arraycopy(cmant, 0, rec, needsign, cmant.length); 2992 { 2993 int $21 = mag - cmant.length; 2994 i = needsign + cmant.length; 2995 for (; $21 > 0; $21--, i++) { // never 0 2996 rec[i] = '0'; 2997 } 2998 }/* i */ 2999 return rec; 3000 } 3001 3002 /* decimal point is in the middle of the mantissa */ 3003 len = (needsign + 1) + cmant.length; 3004 rec = new char[len]; 3005 if (needsign != 0) 3006 rec[0] = '-'; 3007 java.lang.System.arraycopy(cmant, 0, rec, needsign, mag); 3008 rec[needsign + mag] = '.'; 3009 java.lang.System.arraycopy(cmant, mag, rec, (needsign + mag) + 1, 3010 cmant.length - mag); 3011 return rec; 3012 } 3013 3014 /* 3015 * <sgml> Checks a BigDecimal argument to ensure it's a true integer in a given range. <p>If OK, returns it as an 3016 * int. </sgml> 3017 */ 3018 // [currently only used by pow] intcheck(int min, int max)3019 private int intcheck(int min, int max) { 3020 int i; 3021 i = this.intValueExact(); // [checks for non-0 decimal part] 3022 // Use same message as though intValueExact failed due to size 3023 if ((i < min) | (i > max)) 3024 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i); 3025 return i; 3026 } 3027 3028 /* <sgml> Carry out division operations. </sgml> */ 3029 /* 3030 * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is 3031 * explicit scale iff code='D' or 'I' (-1 if none). 3032 * 3033 * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity): 3034 * 3035 * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1) 3036 * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for 3037 * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave 3038 * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -) 3039 * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If 3040 * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor 3041 * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do 3042 * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if 3043 * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1 3044 * 3045 * For extended commentary, see DMSRCN. 3046 */ 3047 dodivide(char code, android.icu.math.BigDecimal rhs, android.icu.math.MathContext set, int scale)3048 private android.icu.math.BigDecimal dodivide(char code, android.icu.math.BigDecimal rhs, 3049 android.icu.math.MathContext set, int scale) { 3050 android.icu.math.BigDecimal lhs; 3051 int reqdig; 3052 int newexp; 3053 android.icu.math.BigDecimal res; 3054 int newlen; 3055 byte var1[]; 3056 int var1len; 3057 byte var2[]; 3058 int var2len; 3059 int b2b; 3060 int have; 3061 int thisdigit = 0; 3062 int i = 0; 3063 byte v2 = 0; 3064 int ba = 0; 3065 int mult = 0; 3066 int start = 0; 3067 int padding = 0; 3068 int d = 0; 3069 byte newvar1[] = null; 3070 byte lasthave = 0; 3071 int actdig = 0; 3072 byte newmant[] = null; 3073 3074 if (set.lostDigits) 3075 checkdigits(rhs, set.digits); 3076 lhs = this; // name for clarity 3077 3078 // [note we must have checked lostDigits before the following checks] 3079 if (rhs.ind == 0) 3080 throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0 3081 if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s] 3082 if (set.form != android.icu.math.MathContext.PLAIN) 3083 return ZERO; 3084 if (scale == (-1)) 3085 return lhs; 3086 return lhs.setScale(scale); 3087 } 3088 3089 /* Prepare numbers according to BigDecimal rules */ 3090 reqdig = set.digits; // local copy (heavily used) 3091 if (reqdig > 0) { 3092 if (lhs.mant.length > reqdig) 3093 lhs = clone(lhs).round(set); 3094 if (rhs.mant.length > reqdig) 3095 rhs = clone(rhs).round(set); 3096 } else {/* scaled divide */ 3097 if (scale == (-1)) 3098 scale = lhs.scale(); 3099 // set reqdig to be at least large enough for the computation 3100 reqdig = lhs.mant.length; // base length 3101 // next line handles both positive lhs.exp and also scale mismatch 3102 if (scale != -lhs.exp) 3103 reqdig = (reqdig + scale) + lhs.exp; 3104 reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect 3105 if (reqdig < lhs.mant.length) 3106 reqdig = lhs.mant.length; // clamp 3107 if (reqdig < rhs.mant.length) 3108 reqdig = rhs.mant.length; // .. 3109 } 3110 3111 /* precalculate exponent */ 3112 newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length; 3113 /* If new exponent -ve, then some quick exits are possible */ 3114 if (newexp < 0) 3115 if (code != 'D') { 3116 if (code == 'I') 3117 return ZERO; // easy - no integer part 3118 /* Must be 'R'; remainder is [finished clone of] input value */ 3119 return clone(lhs).finish(set, false); 3120 } 3121 3122 /* We need slow division */ 3123 res = new android.icu.math.BigDecimal(); // where we'll build result 3124 res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I) 3125 res.exp = newexp; // initial exponent (for D/I) 3126 res.mant = new byte[reqdig + 1]; // where build the result 3127 3128 /* Now [virtually pad the mantissae with trailing zeros */ 3129 // Also copy the LHS, which will be our working array 3130 newlen = (reqdig + reqdig) + 1; 3131 var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array 3132 var1len = newlen; // [remaining digits are 0] 3133 3134 var2 = rhs.mant; 3135 var2len = newlen; 3136 3137 /* Calculate first two digits of rhs (var2), +1 for later estimations */ 3138 b2b = (var2[0] * 10) + 1; 3139 if (var2.length > 1) 3140 b2b = b2b + var2[1]; 3141 3142 /* start the long-division loops */ 3143 have = 0; 3144 { 3145 outer: for (;;) { 3146 thisdigit = 0; 3147 /* find the next digit */ 3148 { 3149 inner: for (;;) { 3150 if (var1len < var2len) 3151 break inner; // V1 too low 3152 if (var1len == var2len) { // compare needed 3153 { 3154 compare: do { // comparison 3155 { 3156 int $22 = var1len; 3157 i = 0; 3158 for (; $22 > 0; $22--, i++) { 3159 // var1len is always <= var1.length 3160 if (i < var2.length) 3161 v2 = var2[i]; 3162 else 3163 v2 = (byte) 0; 3164 if (var1[i] < v2) 3165 break inner; // V1 too low 3166 if (var1[i] > v2) 3167 break compare; // OK to subtract 3168 } 3169 }/* i */ 3170 /* 3171 * reach here if lhs and rhs are identical; subtraction will increase digit by one, 3172 * and the residue will be 0 so we are done; leave the loop with residue set to 0 3173 * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked) 3174 */ 3175 thisdigit++; 3176 res.mant[have] = (byte) thisdigit; 3177 have++; 3178 var1[0] = (byte) 0; // residue to 0 [this is all we'll test] 3179 // var1len=1 -- [optimized out] 3180 break outer; 3181 } while (false); 3182 }/* compare */ 3183 /* prepare for subtraction. Estimate BA (lengths the same) */ 3184 ba = var1[0]; // use only first digit 3185 } // lengths the same 3186 else {/* lhs longer than rhs */ 3187 /* use first two digits for estimate */ 3188 ba = var1[0] * 10; 3189 if (var1len > 1) 3190 ba = ba + var1[1]; 3191 } 3192 /* subtraction needed; V1>=V2 */ 3193 mult = (ba * 10) / b2b; 3194 if (mult == 0) 3195 mult = 1; 3196 thisdigit = thisdigit + mult; 3197 // subtract; var1 reusable 3198 var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true); 3199 if (var1[0] != 0) 3200 continue inner; // maybe another subtract needed 3201 /* 3202 * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than 3203 * V2) 3204 */ 3205 { 3206 int $23 = var1len - 2; 3207 start = 0; 3208 start: for (; start <= $23; start++) { 3209 if (var1[start] != 0) 3210 break start; 3211 var1len--; 3212 } 3213 }/* start */ 3214 if (start == 0) 3215 continue inner; 3216 // shift left 3217 java.lang.System.arraycopy(var1, start, var1, 0, var1len); 3218 } 3219 }/* inner */ 3220 3221 /* We have the next digit */ 3222 if ((have != 0) | (thisdigit != 0)) { // put the digit we got 3223 res.mant[have] = (byte) thisdigit; 3224 have++; 3225 if (have == (reqdig + 1)) 3226 break outer; // we have all we need 3227 if (var1[0] == 0) 3228 break outer; // residue now 0 3229 } 3230 /* can leave now if a scaled divide and exponent is small enough */ 3231 if (scale >= 0) 3232 if (-res.exp > scale) 3233 break outer; 3234 /* can leave now if not Divide and no integer part left */ 3235 if (code != 'D') 3236 if (res.exp <= 0) 3237 break outer; 3238 res.exp = res.exp - 1; // reduce the exponent 3239 /* 3240 * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit 3241 */ 3242 var2len--; 3243 } 3244 }/* outer */ 3245 3246 /* here when we have finished dividing, for some reason */ 3247 // have is the number of digits we collected in res.mant 3248 if (have == 0) 3249 have = 1; // res.mant[0] is 0; we always want a digit 3250 3251 if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */ 3252 if ((have + res.exp) > reqdig) 3253 throw new java.lang.ArithmeticException("Integer overflow"); 3254 3255 if (code == 'R') { 3256 do { 3257 /* We were doing Remainder -- return the residue */ 3258 if (res.mant[0] == 0) // no integer part was found 3259 return clone(lhs).finish(set, false); // .. so return lhs, canonical 3260 if (var1[0] == 0) 3261 return ZERO; // simple 0 residue 3262 res.ind = lhs.ind; // sign is always as LHS 3263 /* 3264 * Calculate the exponent by subtracting the number of padding zeros we added and adding the 3265 * original exponent 3266 */ 3267 padding = ((reqdig + reqdig) + 1) - lhs.mant.length; 3268 res.exp = (res.exp - padding) + lhs.exp; 3269 3270 /* 3271 * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be 3272 */ 3273 d = var1len; 3274 { 3275 i = d - 1; 3276 i: for (; i >= 1; i--) { 3277 if (!((res.exp < lhs.exp) & (res.exp < rhs.exp))) 3278 break; 3279 if (var1[i] != 0) 3280 break i; 3281 d--; 3282 res.exp = res.exp + 1; 3283 } 3284 }/* i */ 3285 if (d < var1.length) {/* need to reduce */ 3286 newvar1 = new byte[d]; 3287 java.lang.System.arraycopy(var1, 0, newvar1, 0, d); // shorten 3288 var1 = newvar1; 3289 } 3290 res.mant = var1; 3291 return res.finish(set, false); 3292 } while (false); 3293 }/* remainder */ 3294 } 3295 3296 else {/* 'D' -- no overflow check needed */ 3297 // If there was a residue then bump the final digit (iff 0 or 5) 3298 // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and 3299 // ROUND_UNNECESSARY checks (etc.) later. 3300 // [if we finished early, the residue will be 0] 3301 if (var1[0] != 0) { // residue not 0 3302 lasthave = res.mant[have - 1]; 3303 if (((lasthave % 5)) == 0) 3304 res.mant[have - 1] = (byte) (lasthave + 1); 3305 } 3306 } 3307 3308 /* Here for Divide or Integer Divide */ 3309 // handle scaled results first ['I' always scale 0, optional for 'D'] 3310 if (scale >= 0) { 3311 do { 3312 // say 'scale have res.exp len' scale have res.exp res.mant.length 3313 if (have != res.mant.length) 3314 // already padded with 0's, so just adjust exponent 3315 res.exp = res.exp - ((res.mant.length - have)); 3316 // calculate number of digits we really want [may be 0] 3317 actdig = res.mant.length - (-res.exp - scale); 3318 res.round(actdig, set.roundingMode); // round to desired length 3319 // This could have shifted left if round (say) 0.9->1[.0] 3320 // Repair if so by adding a zero and reducing exponent 3321 if (res.exp != -scale) { 3322 res.mant = extend(res.mant, res.mant.length + 1); 3323 res.exp = res.exp - 1; 3324 } 3325 return res.finish(set, true); // [strip if not PLAIN] 3326 } while (false); 3327 }/* scaled */ 3328 3329 // reach here only if a non-scaled 3330 if (have == res.mant.length) { // got digits+1 digits 3331 res.round(set); 3332 have = reqdig; 3333 } else {/* have<=reqdig */ 3334 if (res.mant[0] == 0) 3335 return ZERO; // fastpath 3336 // make the mantissa truly just 'have' long 3337 // [we could let finish do this, during strip, if we adjusted 3338 // the exponent; however, truncation avoids the strip loop] 3339 newmant = new byte[have]; // shorten 3340 java.lang.System.arraycopy(res.mant, 0, newmant, 0, have); 3341 res.mant = newmant; 3342 } 3343 return res.finish(set, true); 3344 } 3345 3346 /* <sgml> Report a conversion exception. </sgml> */ 3347 bad(char s[])3348 private void bad(char s[]) { 3349 throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s)); 3350 } 3351 3352 /* 3353 * <sgml> Report a bad argument to a method. </sgml> Arg1 is method name Arg2 is argument position Arg3 is what was 3354 * found 3355 */ 3356 badarg(java.lang.String name, int pos, java.lang.String value)3357 private void badarg(java.lang.String name, int pos, java.lang.String value) { 3358 throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " " 3359 + value); 3360 } 3361 3362 /* 3363 * <sgml> Extend byte array to given length, padding with 0s. If no extension is required then return the same 3364 * array. </sgml> 3365 * 3366 * Arg1 is the source byte array Arg2 is the new length (longer) 3367 */ 3368 extend(byte inarr[], int newlen)3369 private static final byte[] extend(byte inarr[], int newlen) { 3370 byte newarr[]; 3371 if (inarr.length == newlen) 3372 return inarr; 3373 newarr = new byte[newlen]; 3374 java.lang.System.arraycopy(inarr, 0, newarr, 0, inarr.length); 3375 // 0 padding is carried out by the JVM on allocation initialization 3376 return newarr; 3377 } 3378 3379 /* 3380 * <sgml> Add or subtract two >=0 integers in byte arrays <p>This routine performs the calculation: <pre> C=A+(BM) 3381 * </pre> Where M is in the range -9 through +9 <p> If M<0 then A>=B must be true, so the result is always 3382 * non-negative. 3383 * 3384 * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B, 3385 * or 1 longer than that (if a carry occurred). 3386 * 3387 * A is not altered unless Arg6 is 1. B is never altered. 3388 * 3389 * Arg1 is A Arg2 is A length to use (if longer than A, pad with 0's) Arg3 is B Arg4 is B length to use (if longer 3390 * than B, pad with 0's) Arg5 is M, the multiplier Arg6 is 1 if A can be used to build the result (if it fits) 3391 * 3392 * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance 3393 * degradation. 3394 */ 3395 // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981) 3396 // 1997.10.05 -- changed to byte arrays (from char arrays) 3397 // 1998.07.01 -- changed to allow destructive reuse of LHS 3398 // 1998.07.01 -- changed to allow virtual lengths for the arrays 3399 // 1998.12.29 -- use lookaside for digit/carry calculation 3400 // 1999.08.07 -- avoid multiply when mult=1, and make db an int 3401 // 1999.12.22 -- special case m=-1, also drop 0 special case byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse)3402 private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) { 3403 int alength; 3404 int blength; 3405 int ap; 3406 int bp; 3407 int maxarr; 3408 byte reb[]; 3409 boolean quickm; 3410 int digit; 3411 int op = 0; 3412 int dp90 = 0; 3413 byte newarr[]; 3414 int i = 0; 3415 3416 // We'll usually be right if we assume no carry 3417 alength = a.length; // physical lengths 3418 blength = b.length; // .. 3419 ap = avlen - 1; // -> final (rightmost) digit 3420 bp = bvlen - 1; // .. 3421 maxarr = bp; 3422 if (maxarr < ap) 3423 maxarr = ap; 3424 reb = null; // result byte array 3425 if (reuse) 3426 if ((maxarr + 1) == alength) 3427 reb = a; // OK to reuse A 3428 if (reb == null) 3429 reb = new byte[maxarr + 1]; // need new array 3430 3431 quickm = false; // 1 if no multiply needed 3432 if (m == 1) 3433 quickm = true; // most common 3434 else if (m == (-1)) 3435 quickm = true; // also common 3436 3437 digit = 0; // digit, with carry or borrow 3438 { 3439 op = maxarr; 3440 op: for (; op >= 0; op--) { 3441 if (ap >= 0) { 3442 if (ap < alength) 3443 digit = digit + a[ap]; // within A 3444 ap--; 3445 } 3446 if (bp >= 0) { 3447 if (bp < blength) { // within B 3448 if (quickm) { 3449 if (m > 0) 3450 digit = digit + b[bp]; // most common 3451 else 3452 digit = digit - b[bp]; // also common 3453 } else 3454 digit = digit + (b[bp] * m); 3455 } 3456 bp--; 3457 } 3458 /* result so far (digit) could be -90 through 99 */ 3459 if (digit < 10) 3460 if (digit >= 0) { 3461 do { // 0-9 3462 reb[op] = (byte) digit; 3463 digit = 0; // no carry 3464 continue op; 3465 } while (false); 3466 }/* quick */ 3467 dp90 = digit + 90; 3468 reb[op] = bytedig[dp90]; // this digit 3469 digit = bytecar[dp90]; // carry or borrow 3470 } 3471 }/* op */ 3472 3473 if (digit == 0) 3474 return reb; // no carry 3475 // following line will become an Assert, later 3476 // if digit<0 then signal ArithmeticException("internal.error ["digit"]") 3477 3478 /* We have carry -- need to make space for the extra digit */ 3479 newarr = null; 3480 if (reuse) 3481 if ((maxarr + 2) == a.length) 3482 newarr = a; // OK to reuse A 3483 if (newarr == null) 3484 newarr = new byte[maxarr + 2]; 3485 newarr[0] = (byte) digit; // the carried digit .. 3486 // .. and all the rest [use local loop for short numbers] 3487 if (maxarr < 10) { 3488 int $24 = maxarr + 1; 3489 i = 0; 3490 for (; $24 > 0; $24--, i++) { 3491 newarr[i + 1] = reb[i]; 3492 } 3493 }/* i */ 3494 else 3495 java.lang.System.arraycopy(reb, 0, newarr, 1, maxarr + 1); 3496 return newarr; 3497 } 3498 3499 /* 3500 * <sgml> Initializer for digit array properties (lookaside). </sgml> Returns the digit array, and initializes the 3501 * carry array. 3502 */ 3503 diginit()3504 private static final byte[] diginit() { 3505 byte work[]; 3506 int op = 0; 3507 int digit = 0; 3508 work = new byte[(90 + 99) + 1]; 3509 { 3510 op = 0; 3511 op: for (; op <= (90 + 99); op++) { 3512 digit = op - 90; 3513 if (digit >= 0) { 3514 work[op] = (byte) (digit % 10); 3515 bytecar[op] = (byte) (digit / 10); // calculate carry 3516 continue op; 3517 } 3518 // borrowing... 3519 digit = digit + 100; // yes, this is right [consider -50] 3520 work[op] = (byte) (digit % 10); 3521 bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %] 3522 } 3523 }/* op */ 3524 return work; 3525 } 3526 3527 /* 3528 * <sgml> Create a copy of BigDecimal object for local use. <p>This does NOT make a copy of the mantissa array. 3529 * </sgml> Arg1 is the BigDecimal to clone (non-null) 3530 */ 3531 clone(android.icu.math.BigDecimal dec)3532 private static final android.icu.math.BigDecimal clone(android.icu.math.BigDecimal dec) { 3533 android.icu.math.BigDecimal copy; 3534 copy = new android.icu.math.BigDecimal(); 3535 copy.ind = dec.ind; 3536 copy.exp = dec.exp; 3537 copy.form = dec.form; 3538 copy.mant = dec.mant; 3539 return copy; 3540 } 3541 3542 /* 3543 * <sgml> Check one or two numbers for lost digits. </sgml> Arg1 is RHS (or null, if none) Arg2 is current DIGITS 3544 * setting returns quietly or throws an exception 3545 */ 3546 checkdigits(android.icu.math.BigDecimal rhs, int dig)3547 private void checkdigits(android.icu.math.BigDecimal rhs, int dig) { 3548 if (dig == 0) 3549 return; // don't check if digits=0 3550 // first check lhs... 3551 if (this.mant.length > dig) 3552 if ((!(allzero(this.mant, dig)))) 3553 throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString()); 3554 if (rhs == null) 3555 return; // monadic 3556 if (rhs.mant.length > dig) 3557 if ((!(allzero(rhs.mant, dig)))) 3558 throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); 3559 } 3560 3561 /* 3562 * <sgml> Round to specified digits, if necessary. </sgml> Arg1 is requested MathContext [with length and rounding 3563 * mode] returns this, for convenience 3564 */ 3565 round(android.icu.math.MathContext set)3566 private android.icu.math.BigDecimal round(android.icu.math.MathContext set) { 3567 return round(set.digits, set.roundingMode); 3568 } 3569 3570 /* 3571 * <sgml> Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when 3572 * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience 3573 * 3574 * ind and exp are adjusted, but not cleared for a mantissa of zero 3575 * 3576 * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa 3577 * length will be 1. </sgml> 3578 */ 3579 round(int len, int mode)3580 private android.icu.math.BigDecimal round(int len, int mode) { 3581 int adjust; 3582 int sign; 3583 byte oldmant[]; 3584 boolean reuse = false; 3585 byte first = 0; 3586 int increment; 3587 byte newmant[] = null; 3588 adjust = mant.length - len; 3589 if (adjust <= 0) 3590 return this; // nowt to do 3591 3592 exp = exp + adjust; // exponent of result 3593 sign = ind; // save [assumes -1, 0, 1] 3594 oldmant = mant; // save 3595 if (len > 0) { 3596 // remove the unwanted digits 3597 mant = new byte[len]; 3598 java.lang.System.arraycopy(oldmant, 0, mant, 0, len); 3599 reuse = true; // can reuse mantissa 3600 first = oldmant[len]; // first of discarded digits 3601 } else {/* len<=0 */ 3602 mant = ZERO.mant; 3603 ind = iszero; 3604 reuse = false; // cannot reuse mantissa 3605 if (len == 0) 3606 first = oldmant[0]; 3607 else 3608 first = (byte) 0; // [virtual digit] 3609 } 3610 3611 // decide rounding adjustment depending on mode, sign, and discarded digits 3612 increment = 0; // bumper 3613 { 3614 do {/* select */ 3615 if (mode == ROUND_HALF_UP) { // default first [most common] 3616 if (first >= 5) 3617 increment = sign; 3618 } else if (mode == ROUND_UNNECESSARY) { // default for setScale() 3619 // discarding any non-zero digits is an error 3620 if ((!(allzero(oldmant, len)))) 3621 throw new java.lang.ArithmeticException("Rounding necessary"); 3622 } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down 3623 if (first > 5) 3624 increment = sign; 3625 else if (first == 5) 3626 if ((!(allzero(oldmant, len + 1)))) 3627 increment = sign; 3628 } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even 3629 if (first > 5) 3630 increment = sign; 3631 else if (first == 5) { 3632 if ((!(allzero(oldmant, len + 1)))) 3633 increment = sign; 3634 else /* 0.5000 */ 3635 if ((((mant[mant.length - 1]) % 2)) != 0) 3636 increment = sign; 3637 } 3638 } else if (mode == ROUND_DOWN) { 3639 // never increment 3640 } else if (mode == ROUND_UP) { // increment if discarded non-zero 3641 if ((!(allzero(oldmant, len)))) 3642 increment = sign; 3643 } else if (mode == ROUND_CEILING) { // more positive 3644 if (sign > 0) 3645 if ((!(allzero(oldmant, len)))) 3646 increment = sign; 3647 } else if (mode == ROUND_FLOOR) { // more negative 3648 if (sign < 0) 3649 if ((!(allzero(oldmant, len)))) 3650 increment = sign; 3651 } else { 3652 throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode); 3653 } 3654 } while (false); 3655 }/* modes */ 3656 3657 if (increment != 0) { 3658 do { 3659 if (ind == iszero) { 3660 // we must not subtract from 0, but result is trivial anyway 3661 mant = ONE.mant; 3662 ind = (byte) increment; 3663 } else { 3664 // mantissa is non-0; we can safely add or subtract 1 3665 if (ind == isneg) 3666 increment = -increment; 3667 newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse); 3668 if (newmant.length > mant.length) { // had a carry 3669 // drop rightmost digit and raise exponent 3670 exp++; 3671 // mant is already the correct length 3672 java.lang.System.arraycopy(newmant, 0, mant, 0, 3673 mant.length); 3674 } else 3675 mant = newmant; 3676 } 3677 } while (false); 3678 }/* bump */ 3679 // rounding can increase exponent significantly 3680 if (exp > MaxExp) 3681 throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); 3682 return this; 3683 } 3684 3685 /* 3686 * <sgml> Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to 3687 * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0 3688 * 3689 * Arg2 may be beyond array bounds, in which case 1 is returned </sgml> 3690 */ 3691 allzero(byte array[], int start)3692 private static final boolean allzero(byte array[], int start) { 3693 int i = 0; 3694 if (start < 0) 3695 start = 0; 3696 { 3697 int $25 = array.length - 1; 3698 i = start; 3699 for (; i <= $25; i++) { 3700 if (array[i] != 0) 3701 return false; 3702 } 3703 }/* i */ 3704 return true; 3705 } 3706 3707 /* 3708 * <sgml> Carry out final checks and canonicalization <p> This finishes off the current number by: 1. Rounding if 3709 * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping 3710 * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0' 3711 * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. </sgml> Arg1 is requested 3712 * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed 3713 * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience 3714 */ 3715 finish(android.icu.math.MathContext set, boolean strip)3716 private android.icu.math.BigDecimal finish(android.icu.math.MathContext set, boolean strip) { 3717 int d = 0; 3718 int i = 0; 3719 byte newmant[] = null; 3720 int mag = 0; 3721 int sig = 0; 3722 /* Round if mantissa too long and digits requested */ 3723 if (set.digits != 0) 3724 if (this.mant.length > set.digits) 3725 this.round(set); 3726 3727 /* 3728 * If strip requested (and standard formatting), remove insignificant trailing zeros. 3729 */ 3730 if (strip) 3731 if (set.form != android.icu.math.MathContext.PLAIN) { 3732 d = this.mant.length; 3733 /* see if we need to drop any trailing zeros */ 3734 { 3735 i = d - 1; 3736 i: for (; i >= 1; i--) { 3737 if (this.mant[i] != 0) 3738 break i; 3739 d--; 3740 exp++; 3741 } 3742 }/* i */ 3743 if (d < this.mant.length) {/* need to reduce */ 3744 newmant = new byte[d]; 3745 java.lang.System.arraycopy(this.mant, 0, newmant, 0, d); 3746 this.mant = newmant; 3747 } 3748 } 3749 3750 form = (byte) android.icu.math.MathContext.PLAIN; // preset 3751 3752 /* Now check for leading- and all- zeros in mantissa */ 3753 { 3754 int $26 = this.mant.length; 3755 i = 0; 3756 for (; $26 > 0; $26--, i++) { 3757 if (this.mant[i] != 0) { 3758 // non-0 result; ind will be correct 3759 // remove leading zeros [e.g., after subtract] 3760 if (i > 0) { 3761 do { 3762 newmant = new byte[this.mant.length - i]; 3763 java.lang.System.arraycopy(this.mant, i, newmant, 0, 3764 this.mant.length - i); 3765 this.mant = newmant; 3766 } while (false); 3767 }/* delead */ 3768 // now determine form if not PLAIN 3769 mag = exp + mant.length; 3770 if (mag > 0) { // most common path 3771 if (mag > set.digits) 3772 if (set.digits != 0) 3773 form = (byte) set.form; 3774 if ((mag - 1) <= MaxExp) 3775 return this; // no overflow; quick return 3776 } else if (mag < (-5)) 3777 form = (byte) set.form; 3778 /* check for overflow */ 3779 mag--; 3780 if ((mag < MinExp) | (mag > MaxExp)) { 3781 overflow: do { 3782 // possible reprieve if form is engineering 3783 if (form == android.icu.math.MathContext.ENGINEERING) { 3784 sig = mag % 3; // leftover 3785 if (sig < 0) 3786 sig = 3 + sig; // negative exponent 3787 mag = mag - sig; // exponent to use 3788 // 1999.06.29: second test here must be MaxExp 3789 if (mag >= MinExp) 3790 if (mag <= MaxExp) 3791 break overflow; 3792 } 3793 throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag); 3794 } while (false); 3795 }/* overflow */ 3796 return this; 3797 } 3798 } 3799 }/* i */ 3800 3801 // Drop through to here only if mantissa is all zeros 3802 ind = iszero; 3803 {/* select */ 3804 if (set.form != android.icu.math.MathContext.PLAIN) 3805 exp = 0; // standard result; go to '0' 3806 else if (exp > 0) 3807 exp = 0; // +ve exponent also goes to '0' 3808 else { 3809 // a plain number with -ve exponent; preserve and check exponent 3810 if (exp < MinExp) 3811 throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); 3812 } 3813 } 3814 mant = ZERO.mant; // canonical mantissa 3815 return this; 3816 } 3817 } 3818