diff -r 000000000000 -r 724f3e1ea53e emul/compact/src/main/java/java/math/MathContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/compact/src/main/java/java/math/MathContext.java Sat Sep 07 13:51:24 2013 +0200 @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Portions Copyright IBM Corporation, 1997, 2001. All Rights Reserved. + */ + +package java.math; +import java.io.*; + +/** + * Immutable objects which encapsulate the context settings which + * describe certain rules for numerical operators, such as those + * implemented by the {@link BigDecimal} class. + * + *

The base-independent settings are: + *

    + *
  1. {@code precision}: + * the number of digits to be used for an operation; results are + * rounded to this precision + * + *
  2. {@code roundingMode}: + * a {@link RoundingMode} object which specifies the algorithm to be + * used for rounding. + *
+ * + * @see BigDecimal + * @see RoundingMode + * @author Mike Cowlishaw + * @author Joseph D. Darcy + * @since 1.5 + */ + +public final class MathContext implements Serializable { + + /* ----- Constants ----- */ + + // defaults for constructors + private static final int DEFAULT_DIGITS = 9; + private static final RoundingMode DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP; + // Smallest values for digits (Maximum is Integer.MAX_VALUE) + private static final int MIN_DIGITS = 0; + + // Serialization version + private static final long serialVersionUID = 5579720004786848255L; + + /* ----- Public Properties ----- */ + /** + * A {@code MathContext} object whose settings have the values + * required for unlimited precision arithmetic. + * The values of the settings are: + * + * precision=0 roundingMode=HALF_UP + * + */ + public static final MathContext UNLIMITED = + new MathContext(0, RoundingMode.HALF_UP); + + /** + * A {@code MathContext} object with a precision setting + * matching the IEEE 754R Decimal32 format, 7 digits, and a + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the + * IEEE 754R default. + */ + public static final MathContext DECIMAL32 = + new MathContext(7, RoundingMode.HALF_EVEN); + + /** + * A {@code MathContext} object with a precision setting + * matching the IEEE 754R Decimal64 format, 16 digits, and a + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the + * IEEE 754R default. + */ + public static final MathContext DECIMAL64 = + new MathContext(16, RoundingMode.HALF_EVEN); + + /** + * A {@code MathContext} object with a precision setting + * matching the IEEE 754R Decimal128 format, 34 digits, and a + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the + * IEEE 754R default. + */ + public static final MathContext DECIMAL128 = + new MathContext(34, RoundingMode.HALF_EVEN); + + /* ----- Shared Properties ----- */ + /** + * The number of digits to be used for an operation. A value of 0 + * indicates that unlimited precision (as many digits as are + * required) will be used. Note that leading zeros (in the + * coefficient of a number) are never significant. + * + *

{@code precision} will always be non-negative. + * + * @serial + */ + final int precision; + + /** + * The rounding algorithm to be used for an operation. + * + * @see RoundingMode + * @serial + */ + final RoundingMode roundingMode; + + /* ----- Constructors ----- */ + + /** + * Constructs a new {@code MathContext} with the specified + * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding + * mode. + * + * @param setPrecision The non-negative {@code int} precision setting. + * @throws IllegalArgumentException if the {@code setPrecision} parameter is less + * than zero. + */ + public MathContext(int setPrecision) { + this(setPrecision, DEFAULT_ROUNDINGMODE); + return; + } + + /** + * Constructs a new {@code MathContext} with a specified + * precision and rounding mode. + * + * @param setPrecision The non-negative {@code int} precision setting. + * @param setRoundingMode The rounding mode to use. + * @throws IllegalArgumentException if the {@code setPrecision} parameter is less + * than zero. + * @throws NullPointerException if the rounding mode argument is {@code null} + */ + public MathContext(int setPrecision, + RoundingMode setRoundingMode) { + if (setPrecision < MIN_DIGITS) + throw new IllegalArgumentException("Digits < 0"); + if (setRoundingMode == null) + throw new NullPointerException("null RoundingMode"); + + precision = setPrecision; + roundingMode = setRoundingMode; + return; + } + + /** + * Constructs a new {@code MathContext} from a string. + * + * The string must be in the same format as that produced by the + * {@link #toString} method. + * + *

An {@code IllegalArgumentException} is thrown if the precision + * section of the string is out of range ({@code < 0}) or the string is + * not in the format created by the {@link #toString} method. + * + * @param val The string to be parsed + * @throws IllegalArgumentException if the precision section is out of range + * or of incorrect format + * @throws NullPointerException if the argument is {@code null} + */ + public MathContext(String val) { + boolean bad = false; + int setPrecision; + if (val == null) + throw new NullPointerException("null String"); + try { // any error here is a string format problem + if (!val.startsWith("precision=")) throw new RuntimeException(); + int fence = val.indexOf(' '); // could be -1 + int off = 10; // where value starts + setPrecision = Integer.parseInt(val.substring(10, fence)); + + if (!val.startsWith("roundingMode=", fence+1)) + throw new RuntimeException(); + off = fence + 1 + 13; + String str = val.substring(off, val.length()); + roundingMode = RoundingMode.valueOf(str); + } catch (RuntimeException re) { + throw new IllegalArgumentException("bad string format"); + } + + if (setPrecision < MIN_DIGITS) + throw new IllegalArgumentException("Digits < 0"); + // the other parameters cannot be invalid if we got here + precision = setPrecision; + } + + /** + * Returns the {@code precision} setting. + * This value is always non-negative. + * + * @return an {@code int} which is the value of the {@code precision} + * setting + */ + public int getPrecision() { + return precision; + } + + /** + * Returns the roundingMode setting. + * This will be one of + * {@link RoundingMode#CEILING}, + * {@link RoundingMode#DOWN}, + * {@link RoundingMode#FLOOR}, + * {@link RoundingMode#HALF_DOWN}, + * {@link RoundingMode#HALF_EVEN}, + * {@link RoundingMode#HALF_UP}, + * {@link RoundingMode#UNNECESSARY}, or + * {@link RoundingMode#UP}. + * + * @return a {@code RoundingMode} object which is the value of the + * {@code roundingMode} setting + */ + + public RoundingMode getRoundingMode() { + return roundingMode; + } + + /** + * Compares this {@code MathContext} with the specified + * {@code Object} for equality. + * + * @param x {@code Object} to which this {@code MathContext} is to + * be compared. + * @return {@code true} if and only if the specified {@code Object} is + * a {@code MathContext} object which has exactly the same + * settings as this object + */ + public boolean equals(Object x){ + MathContext mc; + if (!(x instanceof MathContext)) + return false; + mc = (MathContext) x; + return mc.precision == this.precision + && mc.roundingMode == this.roundingMode; // no need for .equals() + } + + /** + * Returns the hash code for this {@code MathContext}. + * + * @return hash code for this {@code MathContext} + */ + public int hashCode() { + return this.precision + roundingMode.hashCode() * 59; + } + + /** + * Returns the string representation of this {@code MathContext}. + * The {@code String} returned represents the settings of the + * {@code MathContext} object as two space-delimited words + * (separated by a single space character, '\u0020', + * and with no leading or trailing white space), as follows: + *

    + *
  1. + * The string {@code "precision="}, immediately followed + * by the value of the precision setting as a numeric string as if + * generated by the {@link Integer#toString(int) Integer.toString} + * method. + * + *
  2. + * The string {@code "roundingMode="}, immediately + * followed by the value of the {@code roundingMode} setting as a + * word. This word will be the same as the name of the + * corresponding public constant in the {@link RoundingMode} + * enum. + *
+ *

+ * For example: + *

+     * precision=9 roundingMode=HALF_UP
+     * 
+ * + * Additional words may be appended to the result of + * {@code toString} in the future if more properties are added to + * this class. + * + * @return a {@code String} representing the context settings + */ + public java.lang.String toString() { + return "precision=" + precision + " " + + "roundingMode=" + roundingMode.toString(); + } + + // Private methods + + /** + * Reconstitute the {@code MathContext} instance from a stream (that is, + * deserialize it). + * + * @param s the stream being read. + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); // read in all fields + // validate possibly bad fields + if (precision < MIN_DIGITS) { + String message = "MathContext: invalid digits in stream"; + throw new java.io.StreamCorruptedException(message); + } + if (roundingMode == null) { + String message = "MathContext: null roundingMode in stream"; + throw new java.io.StreamCorruptedException(message); + } + } + +}