1 7 8 20 21 package java.text; 22 23 import java.math.BigDecimal ; 24 import java.math.BigInteger ; 25 26 55 final class DigitList implements Cloneable { 56 61 public static final int MAX_COUNT = 19; 63 84 public int decimalAt = 0; 85 public int count = 0; 86 public char[] digits = new char[MAX_COUNT]; 87 88 private char[] data; 89 90 93 boolean isZero() { 94 for (int i=0; i < count; ++i) { 95 if (digits[i] != '0') { 96 return false; 97 } 98 } 99 return true; 100 } 101 102 109 public void clear () { 110 decimalAt = 0; 111 count = 0; 112 } 113 114 117 public void append(char digit) { 118 if (count == digits.length) { 119 char[] data = new char[count + 100]; 120 System.arraycopy(digits, 0, data, 0, count); 121 digits = data; 122 } 123 digits[count++] = digit; 124 } 125 126 131 public final double getDouble() { 132 if (count == 0) { 133 return 0.0; 134 } 135 136 StringBuffer temp = getStringBuffer(); 137 temp.append('.'); 138 temp.append(digits, 0, count); 139 temp.append('E'); 140 temp.append(decimalAt); 141 return Double.parseDouble(temp.toString()); 142 } 143 144 148 public final long getLong() { 149 151 if (count == 0) { 152 return 0; 153 } 154 155 if (isLongMIN_VALUE()) { 159 return Long.MIN_VALUE; 160 } 161 162 StringBuffer temp = getStringBuffer(); 163 temp.append(digits, 0, count); 164 for (int i = count; i < decimalAt; ++i) { 165 temp.append('0'); 166 } 167 return Long.parseLong(temp.toString()); 168 } 169 170 public final BigDecimal getBigDecimal() { 171 if (count == 0) { 172 if (decimalAt == 0) { 173 return BigDecimal.ZERO; 174 } else { 175 return new BigDecimal ("0E" + decimalAt); 176 } 177 } 178 179 StringBuffer temp = new StringBuffer (count + 12); 180 temp.append('.'); 181 temp.append(digits, 0, count); 182 temp.append('E'); 183 temp.append(decimalAt); 184 return new BigDecimal (temp.toString()); 185 } 186 187 195 boolean fitsIntoLong(boolean isPositive, boolean ignoreNegativeZero) { 196 202 while (count > 0 && digits[count - 1] == '0') { 204 --count; 205 } 206 207 if (count == 0) { 208 return isPositive || ignoreNegativeZero; 211 } 212 213 if (decimalAt < count || decimalAt > MAX_COUNT) { 214 return false; 215 } 216 217 if (decimalAt < MAX_COUNT) return true; 218 219 for (int i=0; i<count; ++i) { 223 char dig = digits[i], max = LONG_MIN_REP[i]; 224 if (dig > max) return false; 225 if (dig < max) return true; 226 } 227 228 if (count < decimalAt) return true; 231 232 return !isPositive; 236 } 237 238 246 public final void set(double source, int maximumFractionDigits) { 247 set(source, maximumFractionDigits, true); 248 } 249 250 260 final void set(double source, int maximumDigits, boolean fixedPoint) { 261 set(Double.toString(source), maximumDigits, fixedPoint); 262 } 263 264 268 final void set(String s, int maximumDigits, boolean fixedPoint) { 269 int len = s.length(); 270 char[] source = getDataChars(len); 271 s.getChars(0, len, source, 0); 272 273 decimalAt = -1; 274 count = 0; 275 int exponent = 0; 276 int leadingZerosAfterDecimal = 0; 279 boolean nonZeroDigitSeen = false; 280 281 for (int i = 0; i < len; ) { 282 char c = source[i++]; 283 if (c == '.') { 284 decimalAt = count; 285 } else if (c == 'e' || c == 'E') { 286 exponent = parseInt(source, i, len); 287 break; 288 } else { 289 if (!nonZeroDigitSeen) { 290 nonZeroDigitSeen = (c != '0'); 291 if (!nonZeroDigitSeen && decimalAt != -1) 292 ++leadingZerosAfterDecimal; 293 } 294 if (nonZeroDigitSeen) { 295 digits[count++] = c; 296 } 297 } 298 } 299 if (decimalAt == -1) { 300 decimalAt = count; 301 } 302 if (nonZeroDigitSeen) { 303 decimalAt += exponent - leadingZerosAfterDecimal; 304 } 305 306 if (fixedPoint) { 307 if (-decimalAt > maximumDigits) { 313 count = 0; 316 return; 317 } else if (-decimalAt == maximumDigits) { 318 if (shouldRoundUp(0)) { 321 count = 1; 322 ++decimalAt; 323 digits[0] = '1'; 324 } else { 325 count = 0; 326 } 327 return; 328 } 329 } 331 332 while (count > 1 && digits[count - 1] == '0') { 334 --count; 335 } 336 337 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits); 340 } 341 342 347 private final void round(int maximumDigits) { 348 if (maximumDigits >= 0 && maximumDigits < count) { 351 if (shouldRoundUp(maximumDigits)) { 352 for (;;) { 356 --maximumDigits; 357 if (maximumDigits < 0) { 358 digits[0] = '1'; 361 ++decimalAt; 362 maximumDigits = 0; break; 364 } 365 366 ++digits[maximumDigits]; 367 if (digits[maximumDigits] <= '9') break; 368 } 370 ++maximumDigits; } 372 count = maximumDigits; 373 374 while (count > 1 && digits[count-1] == '0') { 376 --count; 377 } 378 } 379 } 380 381 382 394 private boolean shouldRoundUp(int maximumDigits) { 395 boolean increment = false; 396 if (maximumDigits < count) { 398 if (digits[maximumDigits] > '5') { 399 return true; 400 } else if (digits[maximumDigits] == '5' ) { 401 for (int i=maximumDigits+1; i<count; ++i) { 402 if (digits[i] != '0') { 403 return true; 404 } 405 } 406 return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); 407 } 408 } 409 return false; 410 } 411 412 415 public final void set(long source) { 416 set(source, 0); 417 } 418 419 427 public final void set(long source, int maximumDigits) { 428 if (source <= 0) { 435 if (source == Long.MIN_VALUE) { 436 decimalAt = count = MAX_COUNT; 437 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 438 } else { 439 decimalAt = count = 0; } 441 } else { 442 int left = MAX_COUNT; 445 int right; 446 while (source > 0) { 447 digits[--left] = (char)('0' + (source % 10)); 448 source /= 10; 449 } 450 decimalAt = MAX_COUNT - left; 451 for (right = MAX_COUNT - 1; digits[right] == '0'; --right) 454 ; 455 count = right - left + 1; 456 System.arraycopy(digits, left, digits, 0, count); 457 } 458 if (maximumDigits > 0) round(maximumDigits); 459 } 460 461 470 final void set(BigDecimal source, int maximumDigits, boolean fixedPoint) { 471 String s = source.toString(); 472 extendDigits(s.length()); 473 474 set(s, maximumDigits, fixedPoint); 475 } 476 477 484 final void set(BigInteger source, int maximumDigits) { 485 String s = source.toString(); 486 int len = s.length(); 487 extendDigits(len); 488 s.getChars(0, len, digits, 0); 489 490 decimalAt = len; 491 int right; 492 for (right = len - 1; right >= 0 && digits[right] == '0'; --right) 493 ; 494 count = right + 1; 495 496 if (maximumDigits > 0) { 497 round(maximumDigits); 498 } 499 } 500 501 504 public boolean equals(Object obj) { 505 if (this == obj) return true; 507 if (!(obj instanceof DigitList )) return false; 509 DigitList other = (DigitList ) obj; 510 if (count != other.count || 511 decimalAt != other.decimalAt) 512 return false; 513 for (int i = 0; i < count; i++) 514 if (digits[i] != other.digits[i]) 515 return false; 516 return true; 517 } 518 519 522 public int hashCode() { 523 int hashcode = decimalAt; 524 525 for (int i = 0; i < count; i++) { 526 hashcode = hashcode * 37 + digits[i]; 527 } 528 529 return hashcode; 530 } 531 532 536 public Object clone() { 537 try { 538 DigitList other = (DigitList ) super.clone(); 539 char[] newDigits = new char[digits.length]; 540 System.arraycopy(digits, 0, newDigits, 0, digits.length); 541 other.digits = newDigits; 542 return other; 543 } catch (CloneNotSupportedException e) { 544 throw new InternalError (); 545 } 546 } 547 548 552 private boolean isLongMIN_VALUE() { 553 if (decimalAt != count || count != MAX_COUNT) { 554 return false; 555 } 556 557 for (int i = 0; i < count; ++i) { 558 if (digits[i] != LONG_MIN_REP[i]) return false; 559 } 560 561 return true; 562 } 563 564 private static final int parseInt(char[] str, int offset, int strLen) { 565 char c; 566 boolean positive = true; 567 if ((c = str[offset]) == '-') { 568 positive = false; 569 offset++; 570 } else if (c == '+') { 571 offset++; 572 } 573 574 int value = 0; 575 while (offset < strLen) { 576 c = str[offset++]; 577 if (c >= '0' && c <= '9') { 578 value = value * 10 + (c - '0'); 579 } else { 580 break; 581 } 582 } 583 return positive ? value : -value; 584 } 585 586 private static final char[] LONG_MIN_REP = "9223372036854775808".toCharArray(); 588 589 public String toString() { 590 if (isZero()) { 591 return "0"; 592 } 593 StringBuffer buf = getStringBuffer(); 594 buf.append("0."); 595 buf.append(digits, 0, count); 596 buf.append("x10^"); 597 buf.append(decimalAt); 598 return buf.toString(); 599 } 600 601 private StringBuffer tempBuffer; 602 603 private StringBuffer getStringBuffer() { 604 if (tempBuffer == null) { 605 tempBuffer = new StringBuffer (MAX_COUNT); 606 } else { 607 tempBuffer.setLength(0); 608 } 609 return tempBuffer; 610 } 611 612 private void extendDigits(int len) { 613 if (len > digits.length) { 614 digits = new char[len]; 615 } 616 } 617 618 private final char[] getDataChars(int length) { 619 if (data == null || data.length < length) { 620 data = new char[length]; 621 } 622 return data; 623 } 624 } 625 | Popular Tags |