?? bigdecimal.java
字號(hào):
/* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * @(#)BigDecimal.java 1.42 03/01/23 */package java.math;/** * Immutable, arbitrary-precision signed decimal numbers. A BigDecimal * consists of an arbitrary precision integer <i>unscaled value</i> and a * non-negative 32-bit integer <i>scale</i>, which represents the number of * digits to the right of the decimal point. The number represented by the * BigDecimal is <tt>(unscaledValue/10<sup>scale</sup>)</tt>. BigDecimal * provides operations for basic arithmetic, scale manipulation, comparison, * hashing, and format conversion. * <p> * The BigDecimal class gives its user complete control over rounding * behavior, forcing the user to explicitly specify a rounding * behavior for operations capable of discarding precision ({@link * #divide(BigDecimal, int)}, {@link #divide(BigDecimal, int, int)}, * and {@link #setScale}). Eight <em>rounding modes</em> are provided * for this purpose. * <p> * Two types of operations are provided for manipulating the scale of a * BigDecimal: scaling/rounding operations and decimal point motion * operations. Scaling/rounding operations (<tt>setScale</tt>) return a * BigDecimal whose value is approximately (or exactly) equal to that of the * operand, but whose scale is the specified value; that is, they increase or * decrease the precision of the number with minimal effect on its value. * Decimal point motion operations ({@link #movePointLeft} and * {@link #movePointRight}) return a BigDecimal created from the operand by * moving the decimal point a specified distance in the specified direction; * that is, they change a number's value without affecting its precision. * <p> * For the sake of brevity and clarity, pseudo-code is used throughout the * descriptions of BigDecimal methods. The pseudo-code expression * <tt>(i + j)</tt> is shorthand for "a BigDecimal whose value is * that of the BigDecimal <tt>i</tt> plus that of the BigDecimal <tt>j</tt>." * The pseudo-code expression <tt>(i == j)</tt> is shorthand for * "<tt>true</tt> if and only if the BigDecimal <tt>i</tt> represents the same * value as the the BigDecimal <tt>j</tt>." Other pseudo-code expressions are * interpreted similarly. * <p> * Note: care should be exercised if BigDecimals are to be used as * keys in a {@link java.util.SortedMap} or elements in a {@link * java.util.SortedSet}, as BigDecimal's <i>natural ordering</i> is * <i>inconsistent with equals</i>. See {@link Comparable}, {@link * java.util.SortedMap} or {@link java.util.SortedSet} for more * information. * <p> * All methods and constructors for this class * throw <CODE>NullPointerException</CODE> when passed * a null object reference for any input parameter. * * @see BigInteger * @see java.util.SortedMap * @see java.util.SortedSet * @version 1.42, 01/23/03 * @author Josh Bloch */public class BigDecimal extends Number implements Comparable { /** * The unscaled value of this BigDecimal, as returned by unscaledValue(). * * @serial * @see #unscaledValue */ private BigInteger intVal; /** * The scale of this BigDecimal, as returned by scale(). * * @serial * @see #scale */ private int scale = 0; /* Appease the serialization gods */ private static final long serialVersionUID = 6108874887143696463L; // Constructors /** * Translates the String representation of a BigDecimal into a * BigDecimal. The String representation consists of an optional * sign, <tt>'+'</tt> (<tt>'\u002B'</tt>) or <tt>'-'</tt> * (<tt>'\u002D'</tt>), followed by a sequence of zero or more * decimal digits ("the integer"), optionally followed by a * fraction, optionally followed by an exponent. * * <p>The fraction consists of of a decimal point followed by zero or more * decimal digits. The string must contain at least one digit in either * the integer or the fraction. The number formed by the sign, the * integer and the fraction is referred to as the <i>significand</i>. * * <p>The exponent consists of the character <tt>'e'</tt> * (<tt>'\u0075'</tt>) or <tt>'E'</tt> (<tt>'\u0045'</tt>) * followed by one or more decimal digits. The value of the * exponent must lie between -{@link Integer#MAX_VALUE} ({@link * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive. * * <p>More formally, the strings this constructor accepts are * described by the following grammar: * <blockquote> * <dl> * <dt><i>BigDecimalString:</i> * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i> * <p> * <dt><i>Sign:</i> * <dd><code>+</code> * <dd><code>-</code> * <p> * <dt><i>Significand:</i> * <dd><i>IntegerPart</i> <code>.</code> <i>FractionPart<sub>opt</sub></i> * <dd><code>.</code> <i>FractionPart</i> * <dd><i>IntegerPart</i> * <p> * <dt><i>IntegerPart: * <dd>Digits</i> * <p> * <dt><i>FractionPart: * <dd>Digits</i> * <p> * <dt><i>Exponent: * <dd>ExponentIndicator SignedInteger</i> * <p> * <dt><i>ExponentIndicator:</i> * <dd><code>e</code> * <dd><code>E</code> * <p> * <dt><i>SignedInteger: * <dd>Sign<sub>opt</sub> Digits</i> * <p> * <dt><i>Digits: * <dd>Digit * <dd>Digits Digit</i> * <p> * <dt><i>Digit:</i> * <dd>any character for which {@link Character#isDigit} * returns <code>true</code>, including 0, 1, 2 ... * </dl> * </blockquote> * * <p>The scale of the returned BigDecimal will be the number of digits in * the fraction, or zero if the string contains no decimal point, subject * to adjustment for any exponent: If the string contains an exponent, the * exponent is subtracted from the scale. If the resulting scale is * negative, the scale of the returned BigDecimal is zero and the unscaled * value is multiplied by the appropriate power of ten so that, in every * case, the resulting BigDecimal is equal to <i>significand</i> × * 10<i><sup>exponent</sup></i>. (If in the future this specification is * amended to permit negative scales, the final step of zeroing the scale * and adjusting the unscaled value will be eliminated.) * * <p>The character-to-digit mapping is provided by {@link * java.lang.Character#digit} set to convert to radix 10. The * String may not contain any extraneous characters (whitespace, * for example). * * <p>Note: For values other <tt>float</tt> and <tt>double</tt> * NaN and ±Infinity, this constructor is compatible with * the values returned by {@link Float#toString} and {@link * Double#toString}. This is generally the preferred way to * convert a <tt>float</tt> or <tt>double</tt> into a BigDecimal, * as it doesn't suffer from the unpredictability of the {@link * #BigDecimal(double)} constructor. * * <p>Note: the optional leading plus sign and trailing exponent were * added in release 1.3. * * @param val String representation of BigDecimal. * @throws NumberFormatException <tt>val</tt> is not a valid representation * of a BigDecimal. */ public BigDecimal(String val) { // Empty string not accepted if (val.length() == 0) throw new NumberFormatException(); // Deal with leading plus sign if present if (val.charAt(0) == '+') { val = val.substring(1); /* Discard leading '+' */ if (val.length() == 0 || /* "+" illegal! */ val.charAt(0) == '-') /* "+-123.456" illegal! */ throw new NumberFormatException(); } // If exponent is present, break into exponent and significand int exponent = 0; int ePos = val.indexOf('e'); if (ePos == -1) ePos = val.indexOf('E'); if (ePos != -1) { String exp = val.substring(ePos+1); if (exp.length() == 0) /* "1.2e" illegal! */ throw new NumberFormatException(); if (exp.charAt(0) == '+') { exp = exp.substring(1); /* Discard leading '+' */ if (exp.length() == 0 || /* "123.456e+" illegal! */ exp.charAt(0) == '-') /* "123.456e+-7" illegal! */ throw new NumberFormatException(); } exponent = Integer.parseInt(exp); if (ePos==0) throw new NumberFormatException(); /* "e123" illegal! */ val = val.substring(0, ePos); } // Parse significand int pointPos = val.indexOf('.'); if (pointPos == -1) { /* e.g. "123" */ intVal = new BigInteger(val); } else if (pointPos == val.length()-1) { /* e.g. "123." */ intVal = new BigInteger(val.substring(0, val.length()-1)); } else { /* Fraction part exists */ if (val.charAt(pointPos+1) == '-') /* ".-123" illegal! */ throw new NumberFormatException(); char[] digits = new char[val.length()-1]; // Get chars before decimal point val.getChars(0, pointPos, digits, 0); // Get chars after decimal point val.getChars(pointPos+1, val.length(), digits, pointPos); scale = val.length() - pointPos - 1; intVal = new BigInteger(digits); } // Combine exponent into significand assert (scale >= 0); // && scale <= Integer.MAX_VALUE long longScale = (long)scale - (long)exponent; // Avoid errors // in calculating scale if(longScale > Integer.MAX_VALUE) throw new NumberFormatException("Final scale out of range"); scale = (int)longScale; assert (scale == longScale && // conversion should be exact Math.abs(longScale) <= Integer.MAX_VALUE) // exponent range // check :longScale; if (scale < 0) { intVal = timesTenToThe(intVal, -scale); scale = 0; } } /** * Translates a <code>double</code> into a BigDecimal. The scale * of the BigDecimal is the smallest value such that * <tt>(10<sup>scale</sup> * val)</tt> is an integer. * <p> * Note: the results of this constructor can be somewhat unpredictable. * One might assume that <tt>new BigDecimal(.1)</tt> is exactly equal * to .1, but it is actually equal * to .1000000000000000055511151231257827021181583404541015625. * This is so because .1 cannot be represented exactly as a double * (or, for that matter, as a binary fraction of any finite length). * Thus, the long value that is being passed <i>in</i> to the constructor * is not exactly equal to .1, appearances notwithstanding. * <p> * The (String) constructor, on the other hand, is perfectly predictable: * <tt>new BigDecimal(".1")</tt> is <i>exactly</i> equal to .1, as one * would expect. Therefore, it is generally recommended that the (String) * constructor be used in preference to this one. * * @param val <code>double</code> value to be converted to BigDecimal. * @throws NumberFormatException <tt>val</tt> if <tt>val</tt> is * infinite or NaN. */ public BigDecimal(double val) { if (Double.isInfinite(val) || Double.isNaN(val)) throw new NumberFormatException("Infinite or NaN"); /* * Translate the double into sign, exponent and mantissa, according * to the formulae in JLS, Section 20.10.22. */ long valBits = Double.doubleToLongBits(val); int sign = ((valBits >> 63)==0 ? 1 : -1); int exponent = (int) ((valBits >> 52) & 0x7ffL); long mantissa = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1 : (valBits & ((1L<<52) - 1)) | (1L<<52)); exponent -= 1075; /* At this point, val == sign * mantissa * 2**exponent */ /* * Special case zero to to supress nonterminating normalization * and bogus scale calculation. */ if (mantissa == 0) { intVal = BigInteger.ZERO; return; } /* Normalize */ while((mantissa & 1) == 0) { /* i.e., Mantissa is even */ mantissa >>= 1; exponent++; } /* Calculate intVal and scale */ intVal = BigInteger.valueOf(sign*mantissa); if (exponent < 0) { intVal = intVal.multiply(BigInteger.valueOf(5).pow(-exponent)); scale = -exponent; } else if (exponent > 0) { intVal = intVal.multiply(BigInteger.valueOf(2).pow(exponent)); } } /** * Translates a BigInteger into a BigDecimal. The scale of the BigDecimal * is zero. * * @param val BigInteger value to be converted to BigDecimal. */ public BigDecimal(BigInteger val) { intVal = val; } /** * Translates a BigInteger unscaled value and an <code>int</code> * scale into a BigDecimal. The value of the BigDecimal is * <tt>(unscaledVal/10<sup>scale</sup>)</tt>. * * @param unscaledVal unscaled value of the BigDecimal. * @param scale scale of the BigDecimal. * @throws NumberFormatException scale is negative */ public BigDecimal(BigInteger unscaledVal, int scale) { if (scale < 0) throw new NumberFormatException("Negative scale"); intVal = unscaledVal; this.scale = scale; } // Static Factory Methods /** * Translates a <code>long</code> unscaled value and an * <code>int</code> scale into a BigDecimal. This "static factory * method" is provided in preference to a (<code>long</code>, * <code>int</code>) constructor because it allows for reuse of * frequently used BigDecimals. * * @param unscaledVal unscaled value of the BigDecimal. * @param scale scale of the BigDecimal. * @return a BigDecimal whose value is * <tt>(unscaledVal/10<sup>scale</sup>)</tt>. */ public static BigDecimal valueOf(long unscaledVal, int scale) { return new BigDecimal(BigInteger.valueOf(unscaledVal), scale); } /** * Translates a <code>long</code> value into a BigDecimal with a * scale of zero. This "static factory method" is provided in * preference to a (<code>long</code>) constructor because it * allows for reuse of frequently used BigDecimals. *
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -