📄 decimalformat.java
字号:
&& minimumFractionDigits == dup.minimumFractionDigits && maximumFractionDigits == dup.maximumFractionDigits && equals(negativePrefix, dup.negativePrefix) && equals(negativeSuffix, dup.negativeSuffix) && equals(positivePrefix, dup.positivePrefix) && equals(positiveSuffix, dup.positiveSuffix) && symbols.equals(dup.symbols)); } private void formatInternal (double number, FormatBuffer dest, FieldPosition fieldPos) { // A very special case. if (Double.isNaN(number)) { dest.append(symbols.getNaN()); if (fieldPos != null && (fieldPos.getField() == INTEGER_FIELD || fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER)) { int index = dest.length(); fieldPos.setBeginIndex(index - symbols.getNaN().length()); fieldPos.setEndIndex(index); } return; } boolean is_neg = number < 0; if (is_neg) { if (negativePrefix != null) { dest.append(substituteCurrency(negativePrefix, number), negativePrefixRanges, negativePrefixAttrs); } else { dest.append(symbols.getMinusSign(), NumberFormat.Field.SIGN); dest.append(substituteCurrency(positivePrefix, number), positivePrefixRanges, positivePrefixAttrs); } number = - number; } else { dest.append(substituteCurrency(positivePrefix, number), positivePrefixRanges, positivePrefixAttrs); } int integerBeginIndex = dest.length(); int integerEndIndex = 0; int zeroStart = symbols.getZeroDigit() - '0'; if (Double.isInfinite (number)) { dest.append(symbols.getInfinity()); integerEndIndex = dest.length(); } else { number *= multiplier; // Compute exponent. long exponent = 0; double baseNumber; if (useExponentialNotation) { exponent = (long) Math.floor (Math.log(number) / Math.log(10)); exponent = exponent - (exponent % exponentRound); if (minimumIntegerDigits > 0) exponent -= minimumIntegerDigits - 1; baseNumber = (number / Math.pow(10.0, exponent)); } else baseNumber = number; // Round to the correct number of digits. baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1); int index = dest.length(); //double intPart = Math.floor(baseNumber); String intPart = Long.toString((long)Math.floor(baseNumber)); int count, groupPosition = intPart.length(); dest.setDefaultAttribute(NumberFormat.Field.INTEGER); for (count = 0; count < minimumIntegerDigits-intPart.length(); count++) dest.append(symbols.getZeroDigit()); for (count = 0; count < maximumIntegerDigits && count < intPart.length(); count++) { int dig = intPart.charAt(count); // Append group separator if required. if (groupingUsed && count > 0 && groupingSize != 0 && groupPosition % groupingSize == 0) { dest.append(symbols.getGroupingSeparator(), NumberFormat.Field.GROUPING_SEPARATOR); dest.setDefaultAttribute(NumberFormat.Field.INTEGER); } dest.append((char) (zeroStart + dig)); groupPosition--; } dest.setDefaultAttribute(null); integerEndIndex = dest.length(); int decimal_index = integerEndIndex; int consecutive_zeros = 0; int total_digits = 0; int localMaximumFractionDigits = maximumFractionDigits; if (useExponentialNotation) localMaximumFractionDigits += minimumIntegerDigits - count; // Strip integer part from NUMBER. double fracPart = baseNumber - Math.floor(baseNumber); if ( ((fracPart != 0 || minimumFractionDigits > 0) && localMaximumFractionDigits > 0) || decimalSeparatorAlwaysShown) { dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR); } int fraction_begin = dest.length(); dest.setDefaultAttribute(NumberFormat.Field.FRACTION); for (count = 0; count < localMaximumFractionDigits && (fracPart != 0 || count < minimumFractionDigits); ++count) { ++total_digits; fracPart *= 10; long dig = (long) fracPart; if (dig == 0) ++consecutive_zeros; else consecutive_zeros = 0; dest.append((char) (symbols.getZeroDigit() + dig)); // Strip integer part from FRACPART. fracPart = fracPart - Math.floor (fracPart); } // Strip extraneous trailing `0's. We can't always detect // these in the loop. int extra_zeros = Math.min (consecutive_zeros, total_digits - minimumFractionDigits); if (extra_zeros > 0) { dest.cutTail(extra_zeros); total_digits -= extra_zeros; if (total_digits == 0 && !decimalSeparatorAlwaysShown) dest.cutTail(1); } if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) { fieldPos.setBeginIndex(fraction_begin); fieldPos.setEndIndex(dest.length()); } // Finally, print the exponent. if (useExponentialNotation) { dest.append(symbols.getExponential(), NumberFormat.Field.EXPONENT_SYMBOL); if (exponent < 0) { dest.append (symbols.getMinusSign (), NumberFormat.Field.EXPONENT_SIGN); exponent = - exponent; } index = dest.length(); dest.setDefaultAttribute(NumberFormat.Field.EXPONENT); String exponentString = Long.toString ((long) exponent); for (count = 0; count < minExponentDigits-exponentString.length(); count++) dest.append((char) symbols.getZeroDigit()); for (count = 0; count < exponentString.length(); ++count) { int dig = exponentString.charAt(count); dest.append((char) (zeroStart + dig)); } } } if (fieldPos != null && (fieldPos.getField() == INTEGER_FIELD || fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER)) { fieldPos.setBeginIndex(integerBeginIndex); fieldPos.setEndIndex(integerEndIndex); } if (is_neg && negativeSuffix != null) { dest.append(substituteCurrency(negativeSuffix, number), negativeSuffixRanges, negativeSuffixAttrs); } else { dest.append(substituteCurrency(positiveSuffix, number), positiveSuffixRanges, positiveSuffixAttrs); } } public StringBuffer format (double number, StringBuffer dest, FieldPosition fieldPos) { formatInternal (number, new StringFormatBuffer(dest), fieldPos); return dest; } public AttributedCharacterIterator formatToCharacterIterator (Object value) { AttributedFormatBuffer sbuf = new AttributedFormatBuffer(); if (value instanceof Number) formatInternal(((Number) value).doubleValue(), sbuf, null); else throw new IllegalArgumentException ("Cannot format given Object as a Number"); sbuf.sync(); return new FormatCharacterIterator(sbuf.getBuffer().toString(), sbuf.getRanges(), sbuf.getAttributes()); } public StringBuffer format (long number, StringBuffer dest, FieldPosition fieldPos) { // If using exponential notation, we just format as a double. if (useExponentialNotation) return format ((double) number, dest, fieldPos); boolean is_neg = number < 0; if (is_neg) { if (negativePrefix != null) dest.append(substituteCurrency(negativePrefix, number)); else { dest.append(symbols.getMinusSign()); dest.append(substituteCurrency(positivePrefix, number)); } number = - number; } else dest.append(substituteCurrency(positivePrefix, number)); int integerBeginIndex = dest.length(); int index = dest.length(); int count = 0; /* Handle percentages, etc. */ number *= multiplier; while (count < maximumIntegerDigits && (number > 0 || count < minimumIntegerDigits)) { long dig = number % 10; number /= 10; // NUMBER and DIG will be less than 0 if the original number // was the most negative long. if (dig < 0) { dig = - dig; number = - number; } // Append group separator if required. if (groupingUsed && count > 0 && groupingSize != 0 && count % groupingSize == 0) dest.insert(index, symbols.getGroupingSeparator()); dest.insert(index, (char) (symbols.getZeroDigit() + dig)); ++count; } if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) { fieldPos.setBeginIndex(integerBeginIndex); fieldPos.setEndIndex(dest.length()); } if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0) { dest.append(symbols.getDecimalSeparator()); if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) { fieldPos.setBeginIndex(dest.length()); fieldPos.setEndIndex(dest.length() + minimumFractionDigits); } } for (count = 0; count < minimumFractionDigits; ++count) dest.append(symbols.getZeroDigit()); dest.append((is_neg && negativeSuffix != null) ? substituteCurrency(negativeSuffix, number) : substituteCurrency(positiveSuffix, number)); return dest; } /** * Returns the currency corresponding to the currency symbol stored * in the instance of <code>DecimalFormatSymbols</code> used by this * <code>DecimalFormat</code>. * * @return A new instance of <code>Currency</code> if * the currency code matches a known one, null otherwise. */ public Currency getCurrency() { return symbols.getCurrency(); } /** * Returns a copy of the symbols used by this instance. * * @return A copy of the symbols. */ public DecimalFormatSymbols getDecimalFormatSymbols() { return (DecimalFormatSymbols) symbols.clone(); } public int getGroupingSize () { return groupingSize; } public int getMultiplier () { return multiplier; } public String getNegativePrefix () { return negativePrefix; } public String getNegativeSuffix () { return negativeSuffix; } public String getPositivePrefix () { return positivePrefix; } public String getPositiveSuffix () { return positiveSuffix; } /** * Returns a hash code for this object. * * @return A hash code. */ public int hashCode() { return toPattern().hashCode(); } public boolean isDecimalSeparatorAlwaysShown () { return decimalSeparatorAlwaysShown; } public Number parse (String str, ParsePosition pos) { /* * Our strategy is simple: copy the text into separate buffers: one for the int part, * one for the fraction part and for the exponential part. * We translate or omit locale-specific information. * If exponential is sufficiently big we merge the fraction and int part and * remove the '.' and then we use Long to convert the number. In the other * case, we use Double to convert the full number. */ boolean is_neg = false; int index = pos.getIndex(); StringBuffer int_buf = new StringBuffer (); // We have to check both prefixes, because one might be empty. We // want to pick the longest prefix that matches. boolean got_pos = str.startsWith(positivePrefix, index); String np = (negativePrefix != null ? negativePrefix : positivePrefix + symbols.getMinusSign()); boolean got_neg = str.startsWith(np, index); if (got_pos && got_neg) { // By checking this way, we preserve ambiguity in the case // where the negative format differs only in suffix. We // check this again later. if (np.length() > positivePrefix.length()) { is_neg = true; index += np.length(); } else index += positivePrefix.length(); } else if (got_neg) { is_neg = true; index += np.length(); } else if (got_pos) index += positivePrefix.length(); else { pos.setErrorIndex (index); return null; } // FIXME: handle Inf and NaN. // FIXME: do we have to respect minimum digits? // What about multiplier? StringBuffer buf = int_buf; StringBuffer frac_buf = null; StringBuffer exp_buf = null; int start_index = index; int max = str.length(); int exp_index = -1; int last = index + maximumIntegerDigits; if (maximumFractionDigits > 0) last += maximumFractionDigits + 1; if (useExponentialNotation) last += minExponentDigits + 1; if (last > 0 && max > last) max = last; char zero = symbols.getZeroDigit(); int last_group = -1; boolean int_part = true; boolean exp_part = false; for (; index < max; ++index) { char c = str.charAt(index); // FIXME: what about grouping size? if (groupingUsed && c == symbols.getGroupingSeparator()) { if (last_group != -1 && groupingSize != 0 && (index - last_group) % groupingSize != 0) { pos.setErrorIndex(index); return null; } last_group = index+1; } else if (c >= zero && c <= zero + 9) { buf.append((char) (c - zero + '0')); } else if (parseIntegerOnly) break; else if (c == symbols.getDecimalSeparator()) { if (last_group != -1 && groupingSize != 0 && (index - last_group) % groupingSize != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -