📄 decimalformat.java
字号:
pos.setErrorIndex(index); return null; } buf = frac_buf = new StringBuffer(); frac_buf.append('.'); int_part = false; } else if (c == symbols.getExponential()) { buf = exp_buf = new StringBuffer(); int_part = false; exp_part = true; exp_index = index+1; } else if (exp_part && (c == '+' || c == '-' || c == symbols.getMinusSign())) { // For exponential notation. buf.append(c); } else break; } if (index == start_index) { // Didn't see any digits. pos.setErrorIndex(index); return null; } // Check the suffix. We must do this before converting the // buffer to a number to handle the case of a number which is // the most negative Long. boolean got_pos_suf = str.startsWith(positiveSuffix, index); String ns = (negativePrefix == null ? positiveSuffix : negativeSuffix); boolean got_neg_suf = str.startsWith(ns, index); if (is_neg) { if (! got_neg_suf) { pos.setErrorIndex(index); return null; } } else if (got_pos && got_neg && got_neg_suf) { is_neg = true; } else if (got_pos != got_pos_suf && got_neg != got_neg_suf) { pos.setErrorIndex(index); return null; } else if (! got_pos_suf) { pos.setErrorIndex(index); return null; } String suffix = is_neg ? ns : positiveSuffix; long parsedMultiplier = 1; boolean use_long; if (is_neg) int_buf.insert(0, '-'); // Now handle the exponential part if there is one. if (exp_buf != null) { int exponent_value; try { exponent_value = Integer.parseInt(exp_buf.toString()); } catch (NumberFormatException x1) { pos.setErrorIndex(exp_index); return null; } if (frac_buf == null) { // We only have to add some zeros to the int part. // Build a multiplier. for (int i = 0; i < exponent_value; i++) int_buf.append('0'); use_long = true; } else { boolean long_sufficient; if (exponent_value < frac_buf.length()-1) { int lastNonNull = -1; /* We have to check the fraction buffer: it may only be full of '0' * or be sufficiently filled with it to convert the number into Long. */ for (int i = 1; i < frac_buf.length(); i++) if (frac_buf.charAt(i) != '0') lastNonNull = i; long_sufficient = (lastNonNull < 0 || lastNonNull <= exponent_value); } else long_sufficient = true; if (long_sufficient) { for (int i = 1; i < frac_buf.length() && i < exponent_value; i++) int_buf.append(frac_buf.charAt(i)); for (int i = frac_buf.length()-1; i < exponent_value; i++) int_buf.append('0'); use_long = true; } else { /* * A long type is not sufficient, we build the full buffer to * be parsed by Double. */ int_buf.append(frac_buf); int_buf.append('E'); int_buf.append(exp_buf); use_long = false; } } } else { if (frac_buf != null) { /* Check whether the fraction buffer contains only '0' */ int i; for (i = 1; i < frac_buf.length(); i++) if (frac_buf.charAt(i) != '0') break; if (i != frac_buf.length()) { use_long = false; int_buf.append(frac_buf); } else use_long = true; } else use_long = true; } String t = int_buf.toString(); Number result = null; if (use_long) { try { result = new Long (t); } catch (NumberFormatException x1) { } } else { try { result = new Double (t); } catch (NumberFormatException x2) { } } if (result == null) { pos.setErrorIndex(index); return null; } pos.setIndex(index + suffix.length()); return result; } /** * Sets the <code>Currency</code> on the * <code>DecimalFormatSymbols</code> used, which also sets the * currency symbols on those symbols. */ public void setCurrency(Currency currency) { symbols.setCurrency(currency); } /** * Sets the symbols used by this instance. This method makes a copy of * the supplied symbols. * * @param newSymbols the symbols (<code>null</code> not permitted). */ public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { symbols = (DecimalFormatSymbols) newSymbols.clone(); } public void setDecimalSeparatorAlwaysShown (boolean newValue) { decimalSeparatorAlwaysShown = newValue; } public void setGroupingSize (int groupSize) { groupingSize = (byte) groupSize; } public void setMaximumFractionDigits (int newValue) { super.setMaximumFractionDigits(Math.min(newValue, 340)); } public void setMaximumIntegerDigits (int newValue) { super.setMaximumIntegerDigits(Math.min(newValue, 309)); } public void setMinimumFractionDigits (int newValue) { super.setMinimumFractionDigits(Math.min(newValue, 340)); } public void setMinimumIntegerDigits (int newValue) { super.setMinimumIntegerDigits(Math.min(newValue, 309)); } public void setMultiplier (int newValue) { multiplier = newValue; } public void setNegativePrefix (String newValue) { negativePrefix = newValue; } public void setNegativeSuffix (String newValue) { negativeSuffix = newValue; } public void setPositivePrefix (String newValue) { positivePrefix = newValue; } public void setPositiveSuffix (String newValue) { positiveSuffix = newValue; } private void quoteFix(StringBuffer buf, String text, String patChars) { int len = text.length(); for (int index = 0; index < len; ++index) { char c = text.charAt(index); if (patChars.indexOf(c) != -1) { buf.append('\''); buf.append(c); buf.append('\''); } else buf.append(c); } } private String computePattern(DecimalFormatSymbols syms) { StringBuffer mainPattern = new StringBuffer (); // We have to at least emit a zero for the minimum number of // digits. Past that we need hash marks up to the grouping // separator (and one beyond). int total_digits = Math.max(minimumIntegerDigits, groupingUsed ? groupingSize + 1: groupingSize); for (int i = 0; i < total_digits - minimumIntegerDigits; ++i) mainPattern.append(syms.getDigit()); for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i) mainPattern.append(syms.getZeroDigit()); // Inserting the gropuing operator afterwards is easier. if (groupingUsed) mainPattern.insert(mainPattern.length() - groupingSize, syms.getGroupingSeparator()); // See if we need decimal info. if (minimumFractionDigits > 0 || maximumFractionDigits > 0 || decimalSeparatorAlwaysShown) mainPattern.append(syms.getDecimalSeparator()); for (int i = 0; i < minimumFractionDigits; ++i) mainPattern.append(syms.getZeroDigit()); for (int i = minimumFractionDigits; i < maximumFractionDigits; ++i) mainPattern.append(syms.getDigit()); if (useExponentialNotation) { mainPattern.append(syms.getExponential()); for (int i = 0; i < minExponentDigits; ++i) mainPattern.append(syms.getZeroDigit()); if (minExponentDigits == 0) mainPattern.append(syms.getDigit()); } String main = mainPattern.toString(); String patChars = patternChars (syms); mainPattern.setLength(0); quoteFix (mainPattern, positivePrefix, patChars); mainPattern.append(main); quoteFix (mainPattern, positiveSuffix, patChars); if (negativePrefix != null) { quoteFix (mainPattern, negativePrefix, patChars); mainPattern.append(main); quoteFix (mainPattern, negativeSuffix, patChars); } return mainPattern.toString(); } public String toLocalizedPattern () { return computePattern (symbols); } public String toPattern () { return computePattern (nonLocalizedSymbols); } private static final int MAXIMUM_INTEGER_DIGITS = 309; // These names are fixed by the serialization spec. private boolean decimalSeparatorAlwaysShown; private byte groupingSize; private byte minExponentDigits; private int exponentRound; private int multiplier; private String negativePrefix; private String negativeSuffix; private String positivePrefix; private String positiveSuffix; private int[] negativePrefixRanges, positivePrefixRanges; private HashMap[] negativePrefixAttrs, positivePrefixAttrs; private int[] negativeSuffixRanges, positiveSuffixRanges; private HashMap[] negativeSuffixAttrs, positiveSuffixAttrs; private int serialVersionOnStream = 1; private DecimalFormatSymbols symbols; private boolean useExponentialNotation; private static final long serialVersionUID = 864413376551465018L; private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); if (serialVersionOnStream < 1) { useExponentialNotation = false; serialVersionOnStream = 1; } } // The locale-independent pattern symbols happen to be the same as // the US symbols. private static final DecimalFormatSymbols nonLocalizedSymbols = new DecimalFormatSymbols (Locale.US); /** * <p> * Substitutes the currency symbol into the given string, * based on the value used. Currency symbols can either * be a simple series of characters (e.g. '$'), which are * simply used as is, or they can be of a more complex * form: * </p> * <p> * (lower bound)|(mid value)|(upper bound) * </p> * <p> * where each bound has the syntax '(value)(# or <)(symbol)', * to indicate the bounding value and the symbol used. * </p> * <p> * The currency symbol replaces the currency specifier, '\u00a4', * an unlocalised character, which thus is used as such in all formats. * If this symbol occurs twice, the international currency code is used * instead. * </p> * * @param string The string containing the currency specifier, '\u00a4'. * @param number the number being formatted. * @return a string formatted for the correct currency. */ private String substituteCurrency(String string, double number) { int index; int length; char currentChar; StringBuffer buf; index = 0; length = string.length(); buf = new StringBuffer(); while (index < length) { currentChar = string.charAt(index); if (string.charAt(index) == '\u00a4') { if ((index + 1) < length && string.charAt(index + 1) == '\u00a4') { buf.append(symbols.getInternationalCurrencySymbol()); index += 2; } else { String symbol; symbol = symbols.getCurrencySymbol(); if (symbol.startsWith("=")) { String[] bounds; int[] boundValues; String[] boundSymbols; bounds = symbol.substring(1).split("\\|"); boundValues = new int[3]; boundSymbols = new String[3]; for (int a = 0; a < 3; ++a) { String[] bound; bound = bounds[a].split("[#<]"); boundValues[a] = Integer.parseInt(bound[0]); boundSymbols[a] = bound[1]; } if (number <= boundValues[0]) { buf.append(boundSymbols[0]); } else if (number >= boundValues[2]) { buf.append(boundSymbols[2]); } else { buf.append(boundSymbols[1]); } ++index; } else { buf.append(symbol); ++index; } } } else { buf.append(string.charAt(index)); ++index; } } return buf.toString(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -