1 8 package com.ibm.icu.text; 9 10 import java.math.BigInteger ; 11 12 45 final class DigitList { 46 51 public static final int MAX_LONG_DIGITS = 19; public static final int DBL_DIG = 17; 53 54 75 public int decimalAt = 0; 76 public int count = 0; 77 public byte[] digits = new byte[MAX_LONG_DIGITS]; 78 79 private final void ensureCapacity(int digitCapacity, int digitsToCopy) { 80 if (digitCapacity > digits.length) { 81 byte[] newDigits = new byte[digitCapacity * 2]; 82 System.arraycopy(digits, 0, newDigits, 0, digitsToCopy); 83 digits = newDigits; 84 } 85 } 86 87 90 boolean isZero() 91 { 92 for (int i=0; i<count; ++i) if (digits[i] != '0') return false; 93 return true; 94 } 95 96 109 112 public void append (int digit) { 113 ensureCapacity(count+1, count); 114 digits[count++] = (byte) digit; 115 } 116 121 public final double getDouble() { 122 if (count == 0) return 0.0; 123 StringBuffer temp = new StringBuffer (count); 124 temp.append('.'); 125 for (int i = 0; i < count; ++i) temp.append((char)(digits[i])); 126 temp.append('E'); 127 temp.append(Integer.toString(decimalAt)); 128 return Double.valueOf(temp.toString()).doubleValue(); 129 } 132 133 137 public final long getLong() { 138 140 if (count == 0) return 0; 141 142 if (isLongMIN_VALUE()) return Long.MIN_VALUE; 146 147 StringBuffer temp = new StringBuffer (count); 148 for (int i = 0; i < decimalAt; ++i) 149 { 150 temp.append((i < count) ? (char)(digits[i]) : '0'); 151 } 152 return Long.parseLong(temp.toString()); 153 } 154 155 163 public BigInteger getBigInteger(boolean isPositive) { 164 if (isZero()) return BigInteger.valueOf(0); 165 if (false) { 166 StringBuffer stringRep = new StringBuffer (count); 167 if (!isPositive) { 168 stringRep.append('-'); 169 } 170 for (int i=0; i<count; ++i) { 171 stringRep.append((char) digits[i]); 172 } 173 int d = decimalAt; 174 while (d-- > count) { 175 stringRep.append('0'); 176 } 177 return new BigInteger (stringRep.toString()); 178 } else { 179 int len = decimalAt > count ? decimalAt : count; 180 if (!isPositive) { 181 len += 1; 182 } 183 char[] text = new char[len]; 184 int n = 0; 185 if (!isPositive) { 186 text[0] = '-'; 187 for (int i = 0; i < count; ++i) { 188 text[i+1] = (char)digits[i]; 189 } 190 n = count+1; 191 } else { 192 for (int i = 0; i < count; ++i) { 193 text[i] = (char)digits[i]; 194 } 195 n = count; 196 } 197 for (int i = n; i < text.length; ++i) { 198 text[i] = '0'; 199 } 200 return new BigInteger (new String (text)); 201 } 202 } 203 204 private String getStringRep(boolean isPositive) { 205 if (isZero()) return "0"; 206 StringBuffer stringRep = new StringBuffer (count+1); 207 if (!isPositive) { 208 stringRep.append('-'); 209 } 210 int d = decimalAt; 211 if (d < 0) { 212 stringRep.append('.'); 213 while (d < 0) { 214 stringRep.append('0'); 215 ++d; 216 } 217 d = -1; 218 } 219 for (int i=0; i<count; ++i) { 220 if (d == i) { 221 stringRep.append('.'); 222 } 223 stringRep.append((char) digits[i]); 224 } 225 while (d-- > count) { 226 stringRep.append('0'); 227 } 228 return stringRep.toString(); 229 } 230 231 245 252 public com.ibm.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) { 253 if (isZero()) return com.ibm.icu.math.BigDecimal.valueOf(0); 254 return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive)); 255 } 256 257 262 boolean isIntegral() { 263 while (count > 0 && digits[count - 1] == (byte)'0') --count; 265 return count == 0 || decimalAt >= count; 266 } 267 268 314 328 338 final void set(double source, int maximumDigits, boolean fixedPoint) 339 { 340 if (source == 0) source = 0; 341 String rep = Double.toString(source); 344 345 set(rep, MAX_LONG_DIGITS); 346 347 if (fixedPoint) { 348 if (-decimalAt > maximumDigits) { 354 count = 0; 355 return; 356 } else if (-decimalAt == maximumDigits) { 357 if (shouldRoundUp(0)) { 358 count = 1; 359 ++decimalAt; 360 digits[0] = (byte)'1'; 361 } else { 362 count = 0; 363 } 364 return; 365 } 366 } 368 369 while (count > 1 && digits[count - 1] == '0') 371 --count; 372 373 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 376 } 377 378 383 private void set(String rep, int maxCount) { 384 decimalAt = -1; 385 count = 0; 386 int exponent = 0; 387 int leadingZerosAfterDecimal = 0; 390 boolean nonZeroDigitSeen = false; 391 int i=0; 393 if (rep.charAt(i) == '-') { 394 ++i; 395 } 396 for (; i < rep.length(); ++i) { 397 char c = rep.charAt(i); 398 if (c == '.') { 399 decimalAt = count; 400 } else if (c == 'e' || c == 'E') { 401 ++i; 402 if (rep.charAt(i) == '+') { 404 ++i; 405 } 406 exponent = Integer.valueOf(rep.substring(i)).intValue(); 407 break; 408 } else if (count < maxCount) { 409 if (!nonZeroDigitSeen) { 410 nonZeroDigitSeen = (c != '0'); 411 if (!nonZeroDigitSeen && decimalAt != -1) { 412 ++leadingZerosAfterDecimal; 413 } 414 } 415 416 if (nonZeroDigitSeen) { 417 ensureCapacity(count+1, count); 418 digits[count++] = (byte)c; 419 } 420 } 421 } 422 if (decimalAt == -1) { 423 decimalAt = count; 424 } 425 decimalAt += exponent - leadingZerosAfterDecimal; 426 } 427 428 440 private boolean shouldRoundUp(int maximumDigits) { 441 446 if (maximumDigits < count) { 447 if (digits[maximumDigits] > '5') { 448 return true; 449 } else if (digits[maximumDigits] == '5' ) { 450 for (int i=maximumDigits+1; i<count; ++i) { 451 if (digits[i] != '0') { 452 return true; 453 } 454 } 455 return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); 456 } 457 } 458 return false; 459 } 460 461 467 public final void round(int maximumDigits) { 468 if (maximumDigits >= 0 && maximumDigits < count) { 472 if (shouldRoundUp(maximumDigits)) { 473 for (;;) 477 { 478 --maximumDigits; 479 if (maximumDigits < 0) 480 { 481 digits[0] = (byte) '1'; 484 ++decimalAt; 485 maximumDigits = 0; break; 487 } 488 489 ++digits[maximumDigits]; 490 if (digits[maximumDigits] <= '9') break; 491 } 493 ++maximumDigits; } 495 count = maximumDigits; 496 499 while (count > 1 && digits[count-1] == '0') { 500 --count; 501 } } 503 } 504 505 508 public final void set(long source) 509 { 510 set(source, 0); 511 } 512 513 521 public final void set(long source, int maximumDigits) 522 { 523 if (source <= 0) { 531 if (source == Long.MIN_VALUE) { 532 decimalAt = count = MAX_LONG_DIGITS; 533 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 534 } else { 535 count = 0; 536 decimalAt = 0; 537 } 538 } else { 539 int left = MAX_LONG_DIGITS; 540 int right; 541 while (source > 0) { 542 digits[--left] = (byte) (((long) '0') + (source % 10)); 543 source /= 10; 544 } 545 decimalAt = MAX_LONG_DIGITS-left; 546 for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {} 550 count = right - left + 1; 551 System.arraycopy(digits, left, digits, 0, count); 552 } 553 if (maximumDigits > 0) round(maximumDigits); 554 } 555 556 564 public final void set(BigInteger source, int maximumDigits) { 565 String stringDigits = source.toString(); 566 567 count = decimalAt = stringDigits.length(); 568 569 while (count > 1 && stringDigits.charAt(count - 1) == '0') --count; 571 572 int offset = 0; 573 if (stringDigits.charAt(0) == '-') { 574 ++offset; 575 --count; 576 --decimalAt; 577 } 578 579 ensureCapacity(count, 0); 580 for (int i = 0; i < count; ++i) { 581 digits[i] = (byte) stringDigits.charAt(i + offset); 582 } 583 584 if (maximumDigits > 0) round(maximumDigits); 585 } 586 587 600 private void setBigDecimalDigits(String stringDigits, 601 int maximumDigits, boolean fixedPoint) { 602 649 set(stringDigits, stringDigits.length()); 651 652 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 661 } 662 663 680 690 public final void set(com.ibm.icu.math.BigDecimal source, 691 int maximumDigits, boolean fixedPoint) { 692 setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 693 } 694 695 699 private boolean isLongMIN_VALUE() 700 { 701 if (decimalAt != count || count != MAX_LONG_DIGITS) 702 return false; 703 704 for (int i = 0; i < count; ++i) 705 { 706 if (digits[i] != LONG_MIN_REP[i]) return false; 707 } 708 709 return true; 710 } 711 712 private static byte[] LONG_MIN_REP; 713 714 static 715 { 716 String s = Long.toString(Long.MIN_VALUE); 718 LONG_MIN_REP = new byte[MAX_LONG_DIGITS]; 719 for (int i=0; i < MAX_LONG_DIGITS; ++i) 720 { 721 LONG_MIN_REP[i] = (byte)s.charAt(i + 1); 722 } 723 } 724 725 755 763 public boolean equals(Object obj) { 764 if (this == obj) return true; 766 if (!(obj instanceof DigitList)) return false; 768 DigitList other = (DigitList) obj; 769 if (count != other.count || 770 decimalAt != other.decimalAt) 771 return false; 772 for (int i = 0; i < count; i++) 773 if (digits[i] != other.digits[i]) 774 return false; 775 return true; 776 } 777 778 781 public int hashCode() { 782 int hashcode = decimalAt; 783 784 for (int i = 0; i < count; i++) 785 hashcode = hashcode * 37 + digits[i]; 786 787 return hashcode; 788 } 789 790 public String toString() 791 { 792 if (isZero()) return "0"; 793 StringBuffer buf = new StringBuffer ("0."); 794 for (int i=0; i<count; ++i) buf.append((char)digits[i]); 795 buf.append("x10^"); 796 buf.append(decimalAt); 797 return buf.toString(); 798 } 799 } 801 | Popular Tags |