📄 digitlist.java
字号:
// is more than the maximum fraction digits, then we have an underflow // for the printed representation. if (-decimalAt > maximumDigits) { // Handle an underflow to zero when we round something like // 0.0009 to 2 fractional digits. count = 0; return; } else if (-decimalAt == maximumDigits) { // If we round 0.0009 to 3 fractional digits, then we have to // create a new one digit in the least significant location. if (shouldRoundUp(0)) { count = 1; ++decimalAt; digits[0] = '1'; } else { count = 0; } return; } // else fall through } // Eliminate trailing zeros. while (count > 1 && digits[count - 1] == '0') --count; // Eliminate digits beyond maximum digits to be displayed. // Round up if appropriate. round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits); } /** * Round the representation to the given number of digits. * @param maximumDigits The maximum number of digits to be shown. * Upon return, count will be less than or equal to maximumDigits. */ private final void round(int maximumDigits) { // Eliminate digits beyond maximum digits to be displayed. // Round up if appropriate. if (maximumDigits >= 0 && maximumDigits < count) { if (shouldRoundUp(maximumDigits)) { // Rounding up involved incrementing digits from LSD to MSD. // In most cases this is simple, but in a worst case situation // (9999..99) we have to adjust the decimalAt value. for (;;) { --maximumDigits; if (maximumDigits < 0) { // We have all 9's, so we increment to a single digit // of one and adjust the exponent. digits[0] = '1'; ++decimalAt; maximumDigits = 0; // Adjust the count break; } ++digits[maximumDigits]; if (digits[maximumDigits] <= '9') break; // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this } ++maximumDigits; // Increment for use as count } count = maximumDigits; // Eliminate trailing zeros. while (count > 1 && digits[count-1] == '0') { --count; } } } /** * Return true if truncating the representation to the given number * of digits will result in an increment to the last digit. This * method implements half-even rounding, the default rounding mode. * [bnf] * @param maximumDigits the number of digits to keep, from 0 to * <code>count-1</code>. If 0, then all digits are rounded away, and * this method returns true if a one should be generated (e.g., formatting * 0.09 with "#.#"). * @return true if digit <code>maximumDigits-1</code> should be * incremented */ private boolean shouldRoundUp(int maximumDigits) { boolean increment = false; // Implement IEEE half-even rounding if (maximumDigits < count) { if (digits[maximumDigits] > '5') { return true; } else if (digits[maximumDigits] == '5' ) { for (int i=maximumDigits+1; i<count; ++i) { if (digits[i] != '0') { return true; } } return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); } } return false; } /** * Utility routine to set the value of the digit list from a long */ public final void set(long source) { set(source, 0); } /** * Set the digit list to a representation of the given long value. * @param source Value to be converted; must be >= 0 or == * Long.MIN_VALUE. * @param maximumDigits The most digits which should be converted. * If maximumDigits is lower than the number of significant digits * in source, the representation will be rounded. Ignored if <= 0. */ public final void set(long source, int maximumDigits) { // This method does not expect a negative number. However, // "source" can be a Long.MIN_VALUE (-9223372036854775808), // if the number being formatted is a Long.MIN_VALUE. In that // case, it will be formatted as -Long.MIN_VALUE, a number // which is outside the legal range of a long, but which can // be represented by DigitList. if (source <= 0) { if (source == Long.MIN_VALUE) { decimalAt = count = MAX_COUNT; System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); } else { decimalAt = count = 0; // Values <= 0 format as zero } } else { // Rewritten to improve performance. I used to call // Long.toString(), which was about 4x slower than this code. int left = MAX_COUNT; int right; while (source > 0) { digits[--left] = (char)('0' + (source % 10)); source /= 10; } decimalAt = MAX_COUNT - left; // Don't copy trailing zeros. We are guaranteed that there is at // least one non-zero digit, so we don't have to check lower bounds. for (right = MAX_COUNT - 1; digits[right] == '0'; --right) ; count = right - left + 1; System.arraycopy(digits, left, digits, 0, count); } if (maximumDigits > 0) round(maximumDigits); } /** * equality test between two digit lists. */ public boolean equals(Object obj) { if (this == obj) // quick check return true; if (!(obj instanceof DigitList)) // (1) same object? return false; DigitList other = (DigitList) obj; if (count != other.count || decimalAt != other.decimalAt) return false; for (int i = 0; i < count; i++) if (digits[i] != other.digits[i]) return false; return true; } /** * Generates the hash code for the digit list. */ public int hashCode() { int hashcode = decimalAt; for (int i = 0; i < count; i++) hashcode = hashcode * 37 + digits[i]; return hashcode; } /** * Creates a copy of this object. * @return a clone of this instance. */ public Object clone() { try { DigitList other = (DigitList) super.clone(); char[] newDigits = new char[digits.length]; System.arraycopy(digits, 0, newDigits, 0, digits.length); other.digits = newDigits; return other; } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * Returns true if this DigitList represents Long.MIN_VALUE; * false, otherwise. This is required so that getLong() works. */ private boolean isLongMIN_VALUE() { if (decimalAt != count || count != MAX_COUNT) return false; for (int i = 0; i < count; ++i) { if (digits[i] != LONG_MIN_REP[i]) return false; } return true; } private static final int parseInt(char[] str, int offset) { char c; boolean positive = true; if ((c = str[offset]) == '-') { positive = false; offset++; } else if (c == '+') { offset++; } int value = 0; while (offset < str.length) { c = str[offset++]; if (c >= '0' && c <= '9') { value = value * 10 + (c - '0'); } else { break; } } return positive ? value : -value; } // The digit part of -9223372036854775808L private static final char[] LONG_MIN_REP = "9223372036854775808".toCharArray(); public String toString() { if (isZero()) return "0"; StringBuffer buf = getStringBuffer(); buf.append("0.").append(digits, 0, count); buf.append("x10^"); buf.append(decimalAt); return buf.toString(); } private StringBuffer tempBuffer; private StringBuffer getStringBuffer() { if (tempBuffer == null) { tempBuffer = new StringBuffer(MAX_COUNT); } else { tempBuffer.setLength(0); } return tempBuffer; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -