/* * Copyright (c) 2003, 2021, 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: *
{@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){
if (!(x instanceof MathContext mc))
return false;
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:
*
* 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. * @throws IOException if an I/O error occurs * @throws ClassNotFoundException if a serialized class cannot be loaded */ @java.io.Serial 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); } } }