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/* 5 ******************************************************************************* 6 * Copyright (C) 1996-2015, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10package android.icu.text; 11 12import java.math.BigInteger; 13 14/** 15 * <code>DigitList</code> handles the transcoding between numeric values and 16 * strings of characters. It only represents non-negative numbers. The 17 * division of labor between <code>DigitList</code> and 18 * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix 19 * 10 representation issues and numeric conversion, including rounding; 20 * <code>DecimalFormat</code> handles the locale-specific issues such as 21 * positive and negative representation, digit grouping, decimal point, 22 * currency, and so on. 23 * 24 * <p>A <code>DigitList</code> is a representation of a finite numeric value. 25 * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite 26 * values. A <code>DigitList</code> value can be converted to a 27 * <code>BigDecimal</code> without loss of precision. Conversion to other 28 * numeric formats may involve loss of precision, depending on the specific 29 * value. 30 * 31 * <p>The <code>DigitList</code> representation consists of a string of 32 * characters, which are the digits radix 10, from '0' to '9'. It also has a 33 * base 10 exponent associated with it. The value represented by a 34 * <code>DigitList</code> object can be computed by mulitplying the fraction 35 * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of 36 * the list to the right of the decimal point, by 10^exponent. 37 * 38 * @see java.util.Locale 39 * @see java.text.Format 40 * @see NumberFormat 41 * @see DecimalFormat 42 * @see java.text.ChoiceFormat 43 * @see java.text.MessageFormat 44 * @version 1.18 08/12/98 45 * @author Mark Davis, Alan Liu 46 * @hide Made public for testing 47 * */ 48public final class DigitList { 49 /** 50 * The maximum number of significant digits in an IEEE 754 double, that 51 * is, in a Java double. This must not be increased, or garbage digits 52 * will be generated, and should not be decreased, or accuracy will be lost. 53 */ 54 public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length() 55 public static final int DBL_DIG = 17; 56 57 /** 58 * These data members are intentionally public and can be set directly. 59 * 60 * The value represented is given by placing the decimal point before 61 * digits[decimalAt]. If decimalAt is < 0, then leading zeros between 62 * the decimal point and the first nonzero digit are implied. If decimalAt 63 * is > count, then trailing zeros between the digits[count-1] and the 64 * decimal point are implied. 65 * 66 * Equivalently, the represented value is given by f * 10^decimalAt. Here 67 * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to 68 * the right of the decimal. 69 * 70 * DigitList is normalized, so if it is non-zero, figits[0] is non-zero. We 71 * don't allow denormalized numbers because our exponent is effectively of 72 * unlimited magnitude. The count value contains the number of significant 73 * digits present in digits[]. 74 * 75 * Zero is represented by any DigitList with count == 0 or with each digits[i] 76 * for all i <= count == '0'. 77 */ 78 public int decimalAt = 0; 79 public int count = 0; 80 public byte[] digits = new byte[MAX_LONG_DIGITS]; 81 82 private final void ensureCapacity(int digitCapacity, int digitsToCopy) { 83 if (digitCapacity > digits.length) { 84 byte[] newDigits = new byte[digitCapacity * 2]; 85 System.arraycopy(digits, 0, newDigits, 0, digitsToCopy); 86 digits = newDigits; 87 } 88 } 89 90 /** 91 * Return true if the represented number is zero. 92 */ 93 boolean isZero() 94 { 95 for (int i=0; i<count; ++i) if (digits[i] != '0') return false; 96 return true; 97 } 98 99// Unused as of ICU 2.6 - alan 100// /** 101// * Clears out the digits. 102// * Use before appending them. 103// * Typically, you set a series of digits with append, then at the point 104// * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count; 105// * then go on appending digits. 106// */ 107// public void clear () { 108// decimalAt = 0; 109// count = 0; 110// } 111 112 /** 113 * Appends digits to the list. 114 */ 115 public void append (int digit) { 116 ensureCapacity(count+1, count); 117 digits[count++] = (byte) digit; 118 } 119 120 public byte getDigitValue(int i) { 121 return (byte) (digits[i] - '0'); 122 } 123 124 /** 125 * Utility routine to get the value of the digit list 126 * If (count == 0) this throws a NumberFormatException, which 127 * mimics Long.parseLong(). 128 */ 129 public final double getDouble() { 130 if (count == 0) return 0.0; 131 StringBuilder temp = new StringBuilder(count); 132 temp.append('.'); 133 for (int i = 0; i < count; ++i) temp.append((char)(digits[i])); 134 temp.append('E'); 135 temp.append(Integer.toString(decimalAt)); 136 return Double.valueOf(temp.toString()).doubleValue(); 137 // long value = Long.parseLong(temp.toString()); 138 // return (value * Math.pow(10, decimalAt - count)); 139 } 140 141 /** 142 * Utility routine to get the value of the digit list. 143 * If (count == 0) this returns 0, unlike Long.parseLong(). 144 */ 145 public final long getLong() { 146 // for now, simple implementation; later, do proper IEEE native stuff 147 148 if (count == 0) return 0; 149 150 // We have to check for this, because this is the one NEGATIVE value 151 // we represent. If we tried to just pass the digits off to parseLong, 152 // we'd get a parse failure. 153 if (isLongMIN_VALUE()) return Long.MIN_VALUE; 154 155 StringBuilder temp = new StringBuilder(count); 156 for (int i = 0; i < decimalAt; ++i) 157 { 158 temp.append((i < count) ? (char)(digits[i]) : '0'); 159 } 160 return Long.parseLong(temp.toString()); 161 } 162 163 /** 164 * Return a <code>BigInteger</code> representing the value stored in this 165 * <code>DigitList</code>. This method assumes that this object contains 166 * an integral value; if not, it will return an incorrect value. 167 * [bnf] 168 * @param isPositive determines the sign of the returned result 169 * @return the value of this object as a <code>BigInteger</code> 170 */ 171 public BigInteger getBigInteger(boolean isPositive) { 172 if (isZero()) return BigInteger.valueOf(0); 173 //Eclipse stated the following is "dead code" 174 /*if (false) { 175 StringBuilder stringRep = new StringBuilder(count); 176 if (!isPositive) { 177 stringRep.append('-'); 178 } 179 for (int i=0; i<count; ++i) { 180 stringRep.append((char) digits[i]); 181 } 182 int d = decimalAt; 183 while (d-- > count) { 184 stringRep.append('0'); 185 } 186 return new BigInteger(stringRep.toString()); 187 } else*/ { 188 int len = decimalAt > count ? decimalAt : count; 189 if (!isPositive) { 190 len += 1; 191 } 192 char[] text = new char[len]; 193 int n = 0; 194 if (!isPositive) { 195 text[0] = '-'; 196 for (int i = 0; i < count; ++i) { 197 text[i+1] = (char)digits[i]; 198 } 199 n = count+1; 200 } else { 201 for (int i = 0; i < count; ++i) { 202 text[i] = (char)digits[i]; 203 } 204 n = count; 205 } 206 for (int i = n; i < text.length; ++i) { 207 text[i] = '0'; 208 } 209 return new BigInteger(new String(text)); 210 } 211 } 212 213 private String getStringRep(boolean isPositive) { 214 if (isZero()) return "0"; 215 StringBuilder stringRep = new StringBuilder(count+1); 216 if (!isPositive) { 217 stringRep.append('-'); 218 } 219 int d = decimalAt; 220 if (d < 0) { 221 stringRep.append('.'); 222 while (d < 0) { 223 stringRep.append('0'); 224 ++d; 225 } 226 d = -1; 227 } 228 for (int i=0; i<count; ++i) { 229 if (d == i) { 230 stringRep.append('.'); 231 } 232 stringRep.append((char) digits[i]); 233 } 234 while (d-- > count) { 235 stringRep.append('0'); 236 } 237 return stringRep.toString(); 238 } 239 240 /** 241 * Return an <code>ICU BigDecimal</code> representing the value stored in this 242 * <code>DigitList</code>. 243 * [bnf] 244 * @param isPositive determines the sign of the returned result 245 * @return the value of this object as a <code>BigDecimal</code> 246 */ 247 public android.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) { 248 if (isZero()) { 249 return android.icu.math.BigDecimal.valueOf(0); 250 } 251 // if exponential notion is negative, 252 // we prefer to use BigDecimal constructor with scale, 253 // because it works better when extremely small value 254 // is used. See #5698. 255 long scale = (long)count - (long)decimalAt; 256 if (scale > 0) { 257 int numDigits = count; 258 if (scale > (long)Integer.MAX_VALUE) { 259 // try to reduce the scale 260 long numShift = scale - (long)Integer.MAX_VALUE; 261 if (numShift < count) { 262 numDigits -= numShift; 263 } else { 264 // fallback to 0 265 return new android.icu.math.BigDecimal(0); 266 } 267 } 268 StringBuilder significantDigits = new StringBuilder(numDigits + 1); 269 if (!isPositive) { 270 significantDigits.append('-'); 271 } 272 for (int i = 0; i < numDigits; i++) { 273 significantDigits.append((char)digits[i]); 274 } 275 BigInteger unscaledVal = new BigInteger(significantDigits.toString()); 276 return new android.icu.math.BigDecimal(unscaledVal, (int)scale); 277 } else { 278 return new android.icu.math.BigDecimal(getStringRep(isPositive)); 279 } 280 } 281 282 /** 283 * Return whether or not this objects represented value is an integer. 284 * [bnf] 285 * @return true if the represented value of this object is an integer 286 */ 287 boolean isIntegral() { 288 // Trim trailing zeros. This does not change the represented value. 289 while (count > 0 && digits[count - 1] == (byte)'0') --count; 290 return count == 0 || decimalAt >= count; 291 } 292 293// Unused as of ICU 2.6 - alan 294// /** 295// * Return true if the number represented by this object can fit into 296// * a long. 297// */ 298// boolean fitsIntoLong(boolean isPositive) 299// { 300// // Figure out if the result will fit in a long. We have to 301// // first look for nonzero digits after the decimal point; 302// // then check the size. If the digit count is 18 or less, then 303// // the value can definitely be represented as a long. If it is 19 304// // then it may be too large. 305// 306// // Trim trailing zeros. This does not change the represented value. 307// while (count > 0 && digits[count - 1] == (byte)'0') --count; 308// 309// if (count == 0) { 310// // Positive zero fits into a long, but negative zero can only 311// // be represented as a double. - bug 4162852 312// return isPositive; 313// } 314// 315// if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false; 316// 317// if (decimalAt < MAX_LONG_DIGITS) return true; 318// 319// // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS. 320// // The number will overflow if it is larger than 9223372036854775807 321// // or smaller than -9223372036854775808. 322// for (int i=0; i<count; ++i) 323// { 324// byte dig = digits[i], max = LONG_MIN_REP[i]; 325// if (dig > max) return false; 326// if (dig < max) return true; 327// } 328// 329// // At this point the first count digits match. If decimalAt is less 330// // than count, then the remaining digits are zero, and we return true. 331// if (count < decimalAt) return true; 332// 333// // Now we have a representation of Long.MIN_VALUE, without the leading 334// // negative sign. If this represents a positive value, then it does 335// // not fit; otherwise it fits. 336// return !isPositive; 337// } 338 339// Unused as of ICU 2.6 - alan 340// /** 341// * Set the digit list to a representation of the given double value. 342// * This method supports fixed-point notation. 343// * @param source Value to be converted; must not be Inf, -Inf, Nan, 344// * or a value <= 0. 345// * @param maximumFractionDigits The most fractional digits which should 346// * be converted. 347// */ 348// public final void set(double source, int maximumFractionDigits) 349// { 350// set(source, maximumFractionDigits, true); 351// } 352 353 /** 354 * Set the digit list to a representation of the given double value. 355 * This method supports both fixed-point and exponential notation. 356 * @param source Value to be converted; must not be Inf, -Inf, Nan, 357 * or a value <= 0. 358 * @param maximumDigits The most fractional or total digits which should 359 * be converted. 360 * @param fixedPoint If true, then maximumDigits is the maximum 361 * fractional digits to be converted. If false, total digits. 362 */ 363 final void set(double source, int maximumDigits, boolean fixedPoint) 364 { 365 if (source == 0) source = 0; 366 // Generate a representation of the form DDDDD, DDDDD.DDDDD, or 367 // DDDDDE+/-DDDDD. 368 String rep = Double.toString(source); 369 370 didRound = false; 371 372 set(rep, MAX_LONG_DIGITS); 373 374 if (fixedPoint) { 375 // The negative of the exponent represents the number of leading 376 // zeros between the decimal and the first non-zero digit, for 377 // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this 378 // is more than the maximum fraction digits, then we have an underflow 379 // for the printed representation. 380 if (-decimalAt > maximumDigits) { 381 count = 0; 382 return; 383 } else if (-decimalAt == maximumDigits) { 384 if (shouldRoundUp(0)) { 385 count = 1; 386 ++decimalAt; 387 digits[0] = (byte)'1'; 388 } else { 389 count = 0; 390 } 391 return; 392 } 393 // else fall through 394 } 395 396 // Eliminate trailing zeros. 397 while (count > 1 && digits[count - 1] == '0') 398 --count; 399 400 // Eliminate digits beyond maximum digits to be displayed. 401 // Round up if appropriate. 402 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 403 } 404 405 /** 406 * Given a string representation of the form DDDDD, DDDDD.DDDDD, 407 * or DDDDDE+/-DDDDD, set this object's value to it. Ignore 408 * any leading '-'. 409 */ 410 private void set(String rep, int maxCount) { 411 decimalAt = -1; 412 count = 0; 413 int exponent = 0; 414 // Number of zeros between decimal point and first non-zero digit after 415 // decimal point, for numbers < 1. 416 int leadingZerosAfterDecimal = 0; 417 boolean nonZeroDigitSeen = false; 418 // Skip over leading '-' 419 int i=0; 420 if (rep.charAt(i) == '-') { 421 ++i; 422 } 423 for (; i < rep.length(); ++i) { 424 char c = rep.charAt(i); 425 if (c == '.') { 426 decimalAt = count; 427 } else if (c == 'e' || c == 'E') { 428 ++i; 429 // Integer.parseInt doesn't handle leading '+' signs 430 if (rep.charAt(i) == '+') { 431 ++i; 432 } 433 exponent = Integer.valueOf(rep.substring(i)).intValue(); 434 break; 435 } else if (count < maxCount) { 436 if (!nonZeroDigitSeen) { 437 nonZeroDigitSeen = (c != '0'); 438 if (!nonZeroDigitSeen && decimalAt != -1) { 439 ++leadingZerosAfterDecimal; 440 } 441 } 442 443 if (nonZeroDigitSeen) { 444 ensureCapacity(count+1, count); 445 digits[count++] = (byte)c; 446 } 447 } 448 } 449 if (decimalAt == -1) { 450 decimalAt = count; 451 } 452 decimalAt += exponent - leadingZerosAfterDecimal; 453 } 454 455 /** 456 * Return true if truncating the representation to the given number 457 * of digits will result in an increment to the last digit. This 458 * method implements half-even rounding, the default rounding mode. 459 * [bnf] 460 * @param maximumDigits the number of digits to keep, from 0 to 461 * <code>count-1</code>. If 0, then all digits are rounded away, and 462 * this method returns true if a one should be generated (e.g., formatting 463 * 0.09 with "#.#"). 464 * @return true if digit <code>maximumDigits-1</code> should be 465 * incremented 466 */ 467 private boolean shouldRoundUp(int maximumDigits) { 468 // variable not used boolean increment = false; 469 // Implement IEEE half-even rounding 470 /*Bug 4243108 471 format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL] 472 */ 473 if (maximumDigits < count) { 474 if (digits[maximumDigits] > '5') { 475 return true; 476 } else if (digits[maximumDigits] == '5' ) { 477 for (int i=maximumDigits+1; i<count; ++i) { 478 if (digits[i] != '0') { 479 return true; 480 } 481 } 482 return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); 483 } 484 } 485 return false; 486 } 487 488 /** 489 * Round the representation to the given number of digits. 490 * @param maximumDigits The maximum number of digits to be shown. 491 * Upon return, count will be less than or equal to maximumDigits. 492 * This now performs rounding when maximumDigits is 0, formerly it did not. 493 */ 494 public final void round(int maximumDigits) { 495 // Eliminate digits beyond maximum digits to be displayed. 496 // Round up if appropriate. 497 // [bnf] rewritten to fix 4179818 498 if (maximumDigits >= 0 && maximumDigits < count) { 499 if (shouldRoundUp(maximumDigits)) { 500 // Rounding up involves incrementing digits from LSD to MSD. 501 // In most cases this is simple, but in a worst case situation 502 // (9999..99) we have to adjust the decimalAt value. 503 for (;;) 504 { 505 --maximumDigits; 506 if (maximumDigits < 0) 507 { 508 // We have all 9's, so we increment to a single digit 509 // of one and adjust the exponent. 510 digits[0] = (byte) '1'; 511 ++decimalAt; 512 maximumDigits = 0; // Adjust the count 513 didRound = true; 514 break; 515 } 516 517 ++digits[maximumDigits]; 518 didRound = true; 519 if (digits[maximumDigits] <= '9') break; 520 // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this 521 } 522 ++maximumDigits; // Increment for use as count 523 } 524 count = maximumDigits; 525 } 526 // Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1" 527 // Eliminate trailing zeros. [Richard/GCL] 528 // [dlf] moved outside if block, see ticket #6408 529 while (count > 1 && digits[count-1] == '0') { 530 --count; 531 } 532 } 533 534 // Value to indicate that rounding was done. 535 private boolean didRound = false; 536 537 /** 538 * Indicates if last digit set was rounded or not. 539 * true indicates it was rounded. 540 * false indicates rounding has not been done. 541 */ 542 public boolean wasRounded() { 543 return didRound; 544 } 545 546 /** 547 * Utility routine to set the value of the digit list from a long 548 */ 549 public final void set(long source) 550 { 551 set(source, 0); 552 } 553 554 /** 555 * Set the digit list to a representation of the given long value. 556 * @param source Value to be converted; must be >= 0 or == 557 * Long.MIN_VALUE. 558 * @param maximumDigits The most digits which should be converted. 559 * If maximumDigits is lower than the number of significant digits 560 * in source, the representation will be rounded. Ignored if <= 0. 561 */ 562 public final void set(long source, int maximumDigits) 563 { 564 // This method does not expect a negative number. However, 565 // "source" can be a Long.MIN_VALUE (-9223372036854775808), 566 // if the number being formatted is a Long.MIN_VALUE. In that 567 // case, it will be formatted as -Long.MIN_VALUE, a number 568 // which is outside the legal range of a long, but which can 569 // be represented by DigitList. 570 // [NEW] Faster implementation 571 didRound = false; 572 573 if (source <= 0) { 574 if (source == Long.MIN_VALUE) { 575 decimalAt = count = MAX_LONG_DIGITS; 576 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 577 } else { 578 count = 0; 579 decimalAt = 0; 580 } 581 } else { 582 int left = MAX_LONG_DIGITS; 583 int right; 584 while (source > 0) { 585 digits[--left] = (byte) (((long) '0') + (source % 10)); 586 source /= 10; 587 } 588 decimalAt = MAX_LONG_DIGITS-left; 589 // Don't copy trailing zeros 590 // we are guaranteed that there is at least one non-zero digit, 591 // so we don't have to check lower bounds 592 for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {} 593 count = right - left + 1; 594 System.arraycopy(digits, left, digits, 0, count); 595 } 596 if (maximumDigits > 0) round(maximumDigits); 597 } 598 599 /** 600 * Set the digit list to a representation of the given BigInteger value. 601 * [bnf] 602 * @param source Value to be converted 603 * @param maximumDigits The most digits which should be converted. 604 * If maximumDigits is lower than the number of significant digits 605 * in source, the representation will be rounded. Ignored if <= 0. 606 */ 607 public final void set(BigInteger source, int maximumDigits) { 608 String stringDigits = source.toString(); 609 610 count = decimalAt = stringDigits.length(); 611 didRound = false; 612 613 // Don't copy trailing zeros 614 while (count > 1 && stringDigits.charAt(count - 1) == '0') --count; 615 616 int offset = 0; 617 if (stringDigits.charAt(0) == '-') { 618 ++offset; 619 --count; 620 --decimalAt; 621 } 622 623 ensureCapacity(count, 0); 624 for (int i = 0; i < count; ++i) { 625 digits[i] = (byte) stringDigits.charAt(i + offset); 626 } 627 628 if (maximumDigits > 0) round(maximumDigits); 629 } 630 631 /** 632 * Internal method that sets this digit list to represent the 633 * given value. The value is given as a String of the format 634 * returned by BigDecimal. 635 * @param stringDigits value to be represented with the following 636 * syntax, expressed as a regular expression: -?\d*.?\d* 637 * Must not be an empty string. 638 * @param maximumDigits The most digits which should be converted. 639 * If maximumDigits is lower than the number of significant digits 640 * in source, the representation will be rounded. Ignored if <= 0. 641 * @param fixedPoint If true, then maximumDigits is the maximum 642 * fractional digits to be converted. If false, total digits. 643 */ 644 private void setBigDecimalDigits(String stringDigits, 645 int maximumDigits, boolean fixedPoint) { 646//| // Find the first non-zero digit, the decimal, and the last non-zero digit. 647//| int first=-1, last=stringDigits.length()-1, decimal=-1; 648//| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) { 649//| char c = stringDigits.charAt(i); 650//| if (c == '.') { 651//| decimal = i; 652//| } else if (first < 0 && (c >= '1' && c <= '9')) { 653//| first = i; 654//| } 655//| } 656//| 657//| if (first < 0) { 658//| clear(); 659//| return; 660//| } 661//| 662//| // At this point we know there is at least one non-zero digit, so the 663//| // following loop is safe. 664//| for (;;) { 665//| char c = stringDigits.charAt(last); 666//| if (c != '0' && c != '.') { 667//| break; 668//| } 669//| --last; 670//| } 671//| 672//| if (decimal < 0) { 673//| decimal = stringDigits.length(); 674//| } 675//| 676//| count = last - first; 677//| if (decimal < first || decimal > last) { 678//| ++count; 679//| } 680//| decimalAt = decimal - first; 681//| if (decimalAt < 0) { 682//| ++decimalAt; 683//| } 684//| 685//| ensureCapacity(count, 0); 686//| for (int i = 0; i < count; ++i) { 687//| digits[i] = (byte) stringDigits.charAt(first++); 688//| if (first == decimal) { 689//| ++first; 690//| } 691//| } 692 693 didRound = false; 694 695 // The maxDigits here could also be Integer.MAX_VALUE 696 set(stringDigits, stringDigits.length()); 697 698 // Eliminate digits beyond maximum digits to be displayed. 699 // Round up if appropriate. 700 // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but 701 // rather than pass that information explicitly, we rely on some magic with maximumDigits 702 // and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits 703 // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round 704 // changed to perform rounding when the argument is 0, we now force the argument 705 // to -1 in the situations where it matters. 706 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 707 } 708 709 /** 710 * Set the digit list to a representation of the given BigDecimal value. 711 * [bnf] 712 * @param source Value to be converted 713 * @param maximumDigits The most digits which should be converted. 714 * If maximumDigits is lower than the number of significant digits 715 * in source, the representation will be rounded. Ignored if <= 0. 716 * @param fixedPoint If true, then maximumDigits is the maximum 717 * fractional digits to be converted. If false, total digits. 718 */ 719 public final void set(java.math.BigDecimal source, 720 int maximumDigits, boolean fixedPoint) { 721 setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 722 } 723 724 /* 725 * Set the digit list to a representation of the given BigDecimal value. 726 * [bnf] 727 * @param source Value to be converted 728 * @param maximumDigits The most digits which should be converted. 729 * If maximumDigits is lower than the number of significant digits 730 * in source, the representation will be rounded. Ignored if <= 0. 731 * @param fixedPoint If true, then maximumDigits is the maximum 732 * fractional digits to be converted. If false, total digits. 733 */ 734 public final void set(android.icu.math.BigDecimal source, 735 int maximumDigits, boolean fixedPoint) { 736 setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 737 } 738 739 /** 740 * Returns true if this DigitList represents Long.MIN_VALUE; 741 * false, otherwise. This is required so that getLong() works. 742 */ 743 private boolean isLongMIN_VALUE() 744 { 745 if (decimalAt != count || count != MAX_LONG_DIGITS) 746 return false; 747 748 for (int i = 0; i < count; ++i) 749 { 750 if (digits[i] != LONG_MIN_REP[i]) return false; 751 } 752 753 return true; 754 } 755 756 private static byte[] LONG_MIN_REP; 757 758 static 759 { 760 // Store the representation of LONG_MIN without the leading '-' 761 String s = Long.toString(Long.MIN_VALUE); 762 LONG_MIN_REP = new byte[MAX_LONG_DIGITS]; 763 for (int i=0; i < MAX_LONG_DIGITS; ++i) 764 { 765 LONG_MIN_REP[i] = (byte)s.charAt(i + 1); 766 } 767 } 768 769// Unused -- Alan 2003-05 770// /** 771// * Return the floor of the log base 10 of a given double. 772// * This method compensates for inaccuracies which arise naturally when 773// * computing logs, and always give the correct value. The parameter 774// * must be positive and finite. 775// */ 776// private static final int log10(double d) 777// { 778// // The reason this routine is needed is that simply taking the 779// // log and dividing by log10 yields a result which may be off 780// // by 1 due to rounding errors. For example, the naive log10 781// // of 1.0e300 taken this way is 299, rather than 300. 782// double log10 = Math.log(d) / LOG10; 783// int ilog10 = (int)Math.floor(log10); 784// // Positive logs could be too small, e.g. 0.99 instead of 1.0 785// if (log10 > 0 && d >= Math.pow(10, ilog10 + 1)) 786// { 787// ++ilog10; 788// } 789// // Negative logs could be too big, e.g. -0.99 instead of -1.0 790// else if (log10 < 0 && d < Math.pow(10, ilog10)) 791// { 792// --ilog10; 793// } 794// return ilog10; 795// } 796// 797// private static final double LOG10 = Math.log(10.0); 798 799 /** 800 * equality test between two digit lists. 801 */ 802 public boolean equals(Object obj) { 803 if (this == obj) // quick check 804 return true; 805 if (!(obj instanceof DigitList)) // (1) same object? 806 return false; 807 DigitList other = (DigitList) obj; 808 if (count != other.count || 809 decimalAt != other.decimalAt) 810 return false; 811 for (int i = 0; i < count; i++) 812 if (digits[i] != other.digits[i]) 813 return false; 814 return true; 815 } 816 817 /** 818 * Generates the hash code for the digit list. 819 */ 820 public int hashCode() { 821 int hashcode = decimalAt; 822 823 for (int i = 0; i < count; i++) 824 hashcode = hashcode * 37 + digits[i]; 825 826 return hashcode; 827 } 828 829 public String toString() 830 { 831 if (isZero()) return "0"; 832 StringBuilder buf = new StringBuilder("0."); 833 for (int i=0; i<count; ++i) buf.append((char)digits[i]); 834 buf.append("x10^"); 835 buf.append(decimalAt); 836 return buf.toString(); 837 } 838} 839