decimalformat.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 824 行 · 第 1/2 页

JAVA
824
字号
				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.setLength(dest.length() - extra_zeros);
				total_digits -= extra_zeros;
			}

			// If required, add the decimal symbol.
			if (decimalSeparatorAlwaysShown || total_digits > 0) {
				dest.insert(decimal_index, symbols.getDecimalSeparator());
				if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) {
					fieldPos.setBeginIndex(decimal_index + 1);
					fieldPos.setEndIndex(dest.length());
				}
			}

			// Finally, print the exponent.
			if (useExponentialNotation) {
				dest.append(symbols.getExponential());
				if (exponent < 0) {
					dest.append(symbols.getMinusSign());
					exponent = -exponent;
				}
				index = dest.length();
				for (count = 0; exponent > 0 || count < minExponentDigits; ++count) {
					long dig = exponent % 10;
					exponent /= 10;
					dest.insert(index, (char) (symbols.getZeroDigit() + dig));
				}
			}
		}

		if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) {
			fieldPos.setBeginIndex(integerBeginIndex);
			fieldPos.setEndIndex(integerEndIndex);
		}

		dest.append((is_neg && negativeSuffix != null) ? negativeSuffix : positiveSuffix);
		return dest;
	}

	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(negativePrefix);
			else {
				dest.append(symbols.getMinusSign());
				dest.append(positivePrefix);
			}
			number = -number;
		} else
			dest.append(positivePrefix);

		int integerBeginIndex = dest.length();
		int index = dest.length();
		int count = 0;
		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 && 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) ? negativeSuffix : positiveSuffix);
		return dest;
	}

	public DecimalFormatSymbols getDecimalFormatSymbols() {
		return symbols;
	}

	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;
	}

	public int hashCode() {
		int hash = (negativeSuffix.hashCode() ^ negativePrefix.hashCode() ^ positivePrefix.hashCode() ^ positiveSuffix.hashCode());
		// FIXME.
		return hash;
	}

	public boolean isDecimalSeparatorAlwaysShown() {
		return decimalSeparatorAlwaysShown;
	}

	public Number parse(String str, ParsePosition pos) {
		// Our strategy is simple: copy the text into a buffer,
		// translating or omitting locale-specific information.  Then
		// let Double or Long convert the number for us.

		boolean is_neg = false;
		int index = pos.getIndex();
		StringBuffer 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/maxmimum digit stuff?
		// What about leading zeros?  What about multiplier?

		int start_index = index;
		int max = str.length();
		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 && (index - last_group) % groupingSize != 0) {
					pos.setErrorIndex(index);
					return null;
				}
				last_group = index;
			} else if (c >= zero && c <= zero + 9) {
				buf.append((char) (c - zero + '0'));
				exp_part = false;
			} else if (parseIntegerOnly)
				break;
			else if (c == symbols.getDecimalSeparator()) {
				if (last_group != -1 && (index - last_group) % groupingSize != 0) {
					pos.setErrorIndex(index);
					return null;
				}
				buf.append('.');
				int_part = false;
			} else if (c == symbols.getExponential()) {
				buf.append('E');
				int_part = false;
				exp_part = true;
			} 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;
		}

		String suffix = is_neg ? ns : positiveSuffix;
		if (is_neg)
			buf.insert(0, '-');

		String t = buf.toString();
		Number result = null;
		try {
			result = new Long(t);
		} catch (NumberFormatException x1) {
			try {
				result = new Double(t);
			} catch (NumberFormatException x2) {
			}
		}
		if (result == null) {
			pos.setErrorIndex(index);
			return null;
		}

		pos.setIndex(index + suffix.length());

		return result;
	}

	public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
		symbols = newSymbols;
	}

	public void setDecimalSeparatorAlwaysShown(boolean newValue) {
		decimalSeparatorAlwaysShown = newValue;
	}

	public void setGroupingSize(int groupSize) {
		groupingSize = (byte) groupSize;
	}

	public void setMaximumFractionDigits(int newValue) {
		maximumFractionDigits = Math.min(newValue, 340);
	}

	public void setMaximumIntegerDigits(int newValue) {
		maximumIntegerDigits = Math.min(newValue, 309);
	}

	public void setMinimumFractionDigits(int newValue) {
		minimumFractionDigits = Math.min(newValue, 340);
	}

	public void setMinimumIntegerDigits(int newValue) {
		minimumIntegerDigits = 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 final 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 final 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 : 0);
		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);
	}

	// These names are fixed by the serialization spec.
	private boolean decimalSeparatorAlwaysShown;
	private byte groupingSize;
	private byte minExponentDigits;
	private int multiplier;
	private String negativePrefix;
	private String negativeSuffix;
	private String positivePrefix;
	private String positiveSuffix;
	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);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?