Save This Page
Home » openjdk-7 » java » math » [javadoc | source]
    1   /*
    2    * Portions Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /*
   27    * Portions Copyright IBM Corporation, 1997, 2001. All Rights Reserved.
   28    */
   29   
   30   package java.math;
   31   import java.io;
   32   
   33   /**
   34    * Immutable objects which encapsulate the context settings which
   35    * describe certain rules for numerical operators, such as those
   36    * implemented by the {@link BigDecimal} class.
   37    *
   38    * <p>The base-independent settings are:
   39    * <ol>
   40    * <li>{@code precision}:
   41    * the number of digits to be used for an operation; results are
   42    * rounded to this precision
   43    *
   44    * <li>{@code roundingMode}:
   45    * a {@link RoundingMode} object which specifies the algorithm to be
   46    * used for rounding.
   47    * </ol>
   48    *
   49    * @see     BigDecimal
   50    * @see     RoundingMode
   51    * @author  Mike Cowlishaw
   52    * @author  Joseph D. Darcy
   53    * @since 1.5
   54    */
   55   
   56   public final class MathContext implements Serializable {
   57   
   58       /* ----- Constants ----- */
   59   
   60       // defaults for constructors
   61       private static final int DEFAULT_DIGITS = 9;
   62       private static final RoundingMode DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP;
   63       // Smallest values for digits (Maximum is Integer.MAX_VALUE)
   64       private static final int MIN_DIGITS = 0;
   65   
   66       // Serialization version
   67       private static final long serialVersionUID = 5579720004786848255L;
   68   
   69       /* ----- Public Properties ----- */
   70       /**
   71        *  A {@code MathContext} object whose settings have the values
   72        *  required for unlimited precision arithmetic.
   73        *  The values of the settings are:
   74        *  <code>
   75        *  precision=0 roundingMode=HALF_UP
   76        *  </code>
   77        */
   78       public static final MathContext UNLIMITED =
   79           new MathContext(0, RoundingMode.HALF_UP);
   80   
   81       /**
   82        *  A {@code MathContext} object with a precision setting
   83        *  matching the IEEE 754R Decimal32 format, 7 digits, and a
   84        *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
   85        *  IEEE 754R default.
   86        */
   87       public static final MathContext DECIMAL32 =
   88           new MathContext(7, RoundingMode.HALF_EVEN);
   89   
   90       /**
   91        *  A {@code MathContext} object with a precision setting
   92        *  matching the IEEE 754R Decimal64 format, 16 digits, and a
   93        *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
   94        *  IEEE 754R default.
   95        */
   96       public static final MathContext DECIMAL64 =
   97           new MathContext(16, RoundingMode.HALF_EVEN);
   98   
   99       /**
  100        *  A {@code MathContext} object with a precision setting
  101        *  matching the IEEE 754R Decimal128 format, 34 digits, and a
  102        *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
  103        *  IEEE 754R default.
  104        */
  105       public static final MathContext DECIMAL128 =
  106           new MathContext(34, RoundingMode.HALF_EVEN);
  107   
  108       /* ----- Shared Properties ----- */
  109       /**
  110        * The number of digits to be used for an operation.  A value of 0
  111        * indicates that unlimited precision (as many digits as are
  112        * required) will be used.  Note that leading zeros (in the
  113        * coefficient of a number) are never significant.
  114        *
  115        * <p>{@code precision} will always be non-negative.
  116        *
  117        * @serial
  118        */
  119       final int precision;
  120   
  121       /**
  122        * The rounding algorithm to be used for an operation.
  123        *
  124        * @see RoundingMode
  125        * @serial
  126        */
  127       final RoundingMode roundingMode;
  128   
  129       /**
  130        *  Lookaside for the rounding points (the numbers which determine
  131        *  whether the coefficient of a number will require rounding).
  132        *  These will be present if {@code precision > 0} and
  133        *  {@code precision <= MAX_LOOKASIDE}.  In this case they will share the
  134        *  {@code BigInteger int[]} array.  Note that the transients
  135        *  cannot be {@code final} because they are reconstructed on
  136        *  deserialization.
  137        */
  138       transient BigInteger roundingMax = null;
  139       transient BigInteger roundingMin = null;
  140       private static final int MAX_LOOKASIDE = 1000;
  141   
  142       /* ----- Constructors ----- */
  143   
  144       /**
  145        * Constructs a new {@code MathContext} with the specified
  146        * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding
  147        * mode.
  148        *
  149        * @param setPrecision The non-negative {@code int} precision setting.
  150        * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
  151        *         than zero.
  152        */
  153       public MathContext(int setPrecision) {
  154           this(setPrecision, DEFAULT_ROUNDINGMODE);
  155           return;
  156       }
  157   
  158       /**
  159        * Constructs a new {@code MathContext} with a specified
  160        * precision and rounding mode.
  161        *
  162        * @param setPrecision The non-negative {@code int} precision setting.
  163        * @param setRoundingMode The rounding mode to use.
  164        * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
  165        *         than zero.
  166        * @throws NullPointerException if the rounding mode argument is {@code null}
  167        */
  168       public MathContext(int setPrecision,
  169                          RoundingMode setRoundingMode) {
  170           if (setPrecision < MIN_DIGITS)
  171               throw new IllegalArgumentException("Digits < 0");
  172           if (setRoundingMode == null)
  173               throw new NullPointerException("null RoundingMode");
  174   
  175           precision = setPrecision;
  176           if (precision > 0 && precision <= MAX_LOOKASIDE) {
  177               roundingMax = BigInteger.TEN.pow(precision);
  178               roundingMin = roundingMax.negate();
  179           }
  180   
  181           roundingMode = setRoundingMode;
  182           return;
  183       }
  184   
  185       /**
  186        * Constructs a new {@code MathContext} from a string.
  187        *
  188        * The string must be in the same format as that produced by the
  189        * {@link #toString} method.
  190        *
  191        * <p>An {@code IllegalArgumentException} is thrown if the precision
  192        * section of the string is out of range ({@code < 0}) or the string is
  193        * not in the format created by the {@link #toString} method.
  194        *
  195        * @param val The string to be parsed
  196        * @throws IllegalArgumentException if the precision section is out of range
  197        * or of incorrect format
  198        * @throws NullPointerException if the argument is {@code null}
  199        */
  200       public MathContext(String val) {
  201           boolean bad = false;
  202           int setPrecision;
  203           if (val == null)
  204               throw new NullPointerException("null String");
  205           try { // any error here is a string format problem
  206               if (!val.startsWith("precision=")) throw new RuntimeException();
  207               int fence = val.indexOf(' ');    // could be -1
  208               int off = 10;                     // where value starts
  209               setPrecision = Integer.parseInt(val.substring(10, fence));
  210   
  211               if (!val.startsWith("roundingMode=", fence+1))
  212                   throw new RuntimeException();
  213               off = fence + 1 + 13;
  214               String str = val.substring(off, val.length());
  215               roundingMode = RoundingMode.valueOf(str);
  216           } catch (RuntimeException re) {
  217               throw new IllegalArgumentException("bad string format");
  218           }
  219   
  220           if (setPrecision < MIN_DIGITS)
  221               throw new IllegalArgumentException("Digits < 0");
  222           // the other parameters cannot be invalid if we got here
  223           precision = setPrecision;
  224           if (precision > 0 && precision <= MAX_LOOKASIDE) {
  225               roundingMax = BigInteger.TEN.pow(precision);
  226               roundingMin = roundingMax.negate();
  227           }
  228       }
  229   
  230       /**
  231        * Returns the {@code precision} setting.
  232        * This value is always non-negative.
  233        *
  234        * @return an {@code int} which is the value of the {@code precision}
  235        *         setting
  236        */
  237       public int getPrecision() {
  238           return precision;
  239       }
  240   
  241       /**
  242        * Returns the roundingMode setting.
  243        * This will be one of
  244        * {@link  RoundingMode#CEILING},
  245        * {@link  RoundingMode#DOWN},
  246        * {@link  RoundingMode#FLOOR},
  247        * {@link  RoundingMode#HALF_DOWN},
  248        * {@link  RoundingMode#HALF_EVEN},
  249        * {@link  RoundingMode#HALF_UP},
  250        * {@link  RoundingMode#UNNECESSARY}, or
  251        * {@link  RoundingMode#UP}.
  252        *
  253        * @return a {@code RoundingMode} object which is the value of the
  254        *         {@code roundingMode} setting
  255        */
  256   
  257       public RoundingMode getRoundingMode() {
  258           return roundingMode;
  259       }
  260   
  261       /**
  262        * Compares this {@code MathContext} with the specified
  263        * {@code Object} for equality.
  264        *
  265        * @param  x {@code Object} to which this {@code MathContext} is to
  266        *         be compared.
  267        * @return {@code true} if and only if the specified {@code Object} is
  268        *         a {@code MathContext} object which has exactly the same
  269        *         settings as this object
  270        */
  271       public boolean equals(Object x){
  272           MathContext mc;
  273           if (!(x instanceof MathContext))
  274               return false;
  275           mc = (MathContext) x;
  276           return mc.precision == this.precision
  277               && mc.roundingMode == this.roundingMode; // no need for .equals()
  278       }
  279   
  280       /**
  281        * Returns the hash code for this {@code MathContext}.
  282        *
  283        * @return hash code for this {@code MathContext}
  284        */
  285       public int hashCode() {
  286           return this.precision + roundingMode.hashCode() * 59;
  287       }
  288   
  289       /**
  290        * Returns the string representation of this {@code MathContext}.
  291        * The {@code String} returned represents the settings of the
  292        * {@code MathContext} object as two space-delimited words
  293        * (separated by a single space character, <tt>'&#92;u0020'</tt>,
  294        * and with no leading or trailing white space), as follows:
  295        * <ol>
  296        * <li>
  297        * The string {@code "precision="}, immediately followed
  298        * by the value of the precision setting as a numeric string as if
  299        * generated by the {@link Integer#toString(int) Integer.toString}
  300        * method.
  301        *
  302        * <li>
  303        * The string {@code "roundingMode="}, immediately
  304        * followed by the value of the {@code roundingMode} setting as a
  305        * word.  This word will be the same as the name of the
  306        * corresponding public constant in the {@link RoundingMode}
  307        * enum.
  308        * </ol>
  309        * <p>
  310        * For example:
  311        * <pre>
  312        * precision=9 roundingMode=HALF_UP
  313        * </pre>
  314        *
  315        * Additional words may be appended to the result of
  316        * {@code toString} in the future if more properties are added to
  317        * this class.
  318        *
  319        * @return a {@code String} representing the context settings
  320        */
  321       public java.lang.String toString() {
  322           return "precision=" +           precision + " " +
  323                  "roundingMode=" +        roundingMode.toString();
  324       }
  325   
  326       // Private methods
  327   
  328       /**
  329        * Reconstitute the {@code MathContext} instance from a stream (that is,
  330        * deserialize it).
  331        *
  332        * @param s the stream being read.
  333        */
  334       private void readObject(java.io.ObjectInputStream s)
  335           throws java.io.IOException, ClassNotFoundException {
  336           s.defaultReadObject();     // read in all fields
  337           // validate possibly bad fields
  338           if (precision < MIN_DIGITS) {
  339               String message = "MathContext: invalid digits in stream";
  340               throw new java.io.StreamCorruptedException(message);
  341           }
  342           if (roundingMode == null) {
  343               String message = "MathContext: null roundingMode in stream";
  344               throw new java.io.StreamCorruptedException(message);
  345           }
  346           // Set the lookaside, if applicable
  347           if (precision <= MAX_LOOKASIDE) {
  348               roundingMax = BigInteger.TEN.pow(precision);
  349               roundingMin = roundingMax.negate();
  350           }
  351       }
  352   
  353   }

Save This Page
Home » openjdk-7 » java » math » [javadoc | source]