KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > math > MathContext


1 /*
2  * @(#)MathContext.java 1.2 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /*
9  * @(#)MathContext.java 1.x 01/xx/xx
10  *
11  * Copyright IBM Corporation, 1997, 2001. All Rights Reserved.
12  *
13  * This software is the proprietary information of Sun Microsystems, Inc.
14  * and IBM Corporation. Use is subject to license terms.
15  *
16  */

17
18 package java.math;
19 import java.io.*;
20
21 /**
22  * Immutable objects which encapsulate the context settings which
23  * describe certain rules for numerical operators, such as those
24  * implemented by the {@link BigDecimal} class.
25  *
26  * <p>The base-independent settings are:
27  * <ol>
28  * <li><tt>precision</tt>:
29  * the number of digits to be used for an operation; results are
30  * rounded to this precision
31  *
32  * <li><tt>roundingMode</tt>:
33  * a {@link RoundingMode} object which specifies the algorithm to be
34  * used for rounding.
35  * </ol>
36  *
37  * @see BigDecimal
38  * @see RoundingMode
39  * @author Mike Cowlishaw
40  * @author Joseph D. Darcy
41  */

42
43 public final class MathContext implements Serializable {
44
45     /* ----- Constants ----- */
46
47     // defaults for constructors
48
private static final int DEFAULT_DIGITS = 9;
49     private static final RoundingMode JavaDoc DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP;
50     // Smallest values for digits (Maximum is Integer.MAX_VALUE)
51
private static final int MIN_DIGITS = 0;
52
53     // Serialization version
54
private static final long serialVersionUID = 5579720004786848255L;
55
56     /* ----- Public Properties ----- */
57     /**
58      * A <tt>MathContext</tt> object whose settings have the values
59      * required for unlimited precision arithmetic.
60      * The values of the settings are:
61      * <code>
62      * precision=0 roundingMode=HALF_UP
63      * </code>
64      */

65     public static final MathContext JavaDoc UNLIMITED =
66         new MathContext JavaDoc(0, RoundingMode.HALF_UP);
67
68     /**
69      * A <tt>MathContext</tt> object with a precision setting
70      * matching the IEEE 754R Decimal32 format, 7 digits, and a
71      * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
72      * IEEE 754R default.
73      */

74     public static final MathContext JavaDoc DECIMAL32 =
75         new MathContext JavaDoc(7, RoundingMode.HALF_EVEN);
76
77     /**
78      * A <tt>MathContext</tt> object with a precision setting
79      * matching the IEEE 754R Decimal64 format, 16 digits, and a
80      * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
81      * IEEE 754R default.
82      */

83     public static final MathContext JavaDoc DECIMAL64 =
84         new MathContext JavaDoc(16, RoundingMode.HALF_EVEN);
85
86     /**
87      * A <tt>MathContext</tt> object with a precision setting
88      * matching the IEEE 754R Decimal128 format, 34 digits, and a
89      * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
90      * IEEE 754R default.
91      */

92     public static final MathContext JavaDoc DECIMAL128 =
93         new MathContext JavaDoc(34, RoundingMode.HALF_EVEN);
94
95     /* ----- Shared Properties ----- */
96     /**
97      * The number of digits to be used for an operation. A value of 0
98      * indicates that unlimited precision (as many digits as are
99      * required) will be used. Note that leading zeros (in the
100      * coefficient of a number) are never significant.
101      *
102      * <p><tt>precision</tt> will always be non-negative.
103      *
104      * @serial
105      */

106     final int precision;
107
108     /**
109      * The rounding algorithm to be used for an operation.
110      *
111      * @see RoundingMode
112      * @serial
113      */

114     final RoundingMode JavaDoc roundingMode;
115
116     /**
117      * Lookaside for the rounding points (the numbers which determine
118      * whether the coefficient of a number will require rounding).
119      * These will be present if precision&gt;0 and
120      * precision&lt;=MAX_LOOKASIDE. In this case they will share the
121      * <tt>BigInteger int[]</tt> array. Note that the transients
122      * cannot be <tt>final</tt> because they are reconstructed on
123      * deserialization.
124      */

125     transient BigInteger JavaDoc roundingMax = null;
126     transient BigInteger JavaDoc roundingMin = null;
127     private static final int MAX_LOOKASIDE = 1000;
128
129     /* ----- Constructors ----- */
130
131     /**
132      * Constructs a new <tt>MathContext</tt> with the specified
133      * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding
134      * mode.
135      *
136      * @param setPrecision The non-negative <tt>int</tt> precision setting.
137      * @throws IllegalArgumentException <tt>setPrecision</tt> parameter less
138      * than zero.
139      */

140     public MathContext(int setPrecision) {
141         this(setPrecision, DEFAULT_ROUNDINGMODE);
142         return;
143     }
144
145     /**
146      * Constructs a new <tt>MathContext</tt> with a specified
147      * precision and rounding mode.
148      *
149      * @param setPrecision The non-negative <tt>int</tt> precision setting.
150      * @param setRoundingMode The rounding mode to use.
151      * @throws IllegalArgumentException <tt>setPrecision</tt> parameter less
152      * than zero.
153      */

154     public MathContext(int setPrecision,
155                RoundingMode JavaDoc setRoundingMode) {
156         if (setPrecision < MIN_DIGITS)
157             throw new IllegalArgumentException JavaDoc("Digits < 0");
158         if (setRoundingMode == null)
159             throw new NullPointerException JavaDoc("null RoundingMode");
160
161         precision = setPrecision;
162         if (precision > 0 && precision <= MAX_LOOKASIDE) {
163             roundingMax = BigInteger.TEN.pow(precision);
164             roundingMin = roundingMax.negate();
165         }
166
167         roundingMode = setRoundingMode;
168         return;
169     }
170
171     /**
172      * Constructs a new <tt>MathContext</tt> from a string.
173      *
174      * The string must be in the same format as that produced by the
175      * {@link #toString} method.
176      *
177      * <p>An <tt>IllegalArgumentException</tt> is thrown if the precision
178      * section of the string is out of range (&lt; 0) or the string is
179      * not in the format created by the {@link #toString} method.
180      *
181      * @param val The string to be parsed
182      * @throws IllegalArgumentException precision parameter out of range
183      * or incorrect format
184      */

185     public MathContext(String JavaDoc val) {
186         boolean bad = false;
187         int setPrecision;
188         if (val == null)
189             throw new NullPointerException JavaDoc("null String");
190         try { // any error here is a string format problem
191
if (!val.startsWith("precision=")) throw new RuntimeException JavaDoc();
192             int fence = val.indexOf(' '); // could be -1
193
int off = 10; // where value starts
194
setPrecision = Integer.parseInt(val.substring(10, fence));
195
196             if (!val.startsWith("roundingMode=", fence+1))
197         throw new RuntimeException JavaDoc();
198             off = fence + 1 + 13;
199             String JavaDoc str = val.substring(off, val.length());
200             roundingMode = RoundingMode.valueOf(str);
201         } catch (RuntimeException JavaDoc re) {
202             throw new IllegalArgumentException JavaDoc("bad string format");
203         }
204
205         if (setPrecision < MIN_DIGITS)
206             throw new IllegalArgumentException JavaDoc("Digits < 0");
207         // the other parameters cannot be invalid if we got here
208
precision = setPrecision;
209         if (precision > 0 && precision <= MAX_LOOKASIDE) {
210             roundingMax = BigInteger.TEN.pow(precision);
211             roundingMin = roundingMax.negate();
212         }
213     }
214
215     /**
216      * Returns the <tt>precision</tt> setting.
217      * This value is always non-negative.
218      *
219      * @return an <tt>int</tt> which is the value of the <tt>precision</tt>
220      * setting
221      */

222     public int getPrecision() {
223         return precision;
224     }
225
226     /**
227      * Returns the roundingMode setting.
228      * This will be one of
229      * {@link RoundingMode#CEILING},
230      * {@link RoundingMode#DOWN},
231      * {@link RoundingMode#FLOOR},
232      * {@link RoundingMode#HALF_DOWN},
233      * {@link RoundingMode#HALF_EVEN},
234      * {@link RoundingMode#HALF_UP},
235      * {@link RoundingMode#UNNECESSARY}, or
236      * {@link RoundingMode#UP}.
237      *
238      * @return a <tt>RoundingMode</tt> object which is the value of the
239      * <tt>roundingMode</tt> setting
240      */

241
242     public RoundingMode JavaDoc getRoundingMode() {
243         return roundingMode;
244     }
245
246     /**
247      * Compares this <tt>MathContext</tt> with the specified
248      * <tt>Object</tt> for equality.
249      *
250      * @param x <tt>Object</tt> to which this <tt>MathContext</tt> is to
251      * be compared.
252      * @return <tt>true</tt> if and only if the specified <tt>Object</tt> is
253      * a <tt>MathContext</tt> object which has exactly the same
254      * settings as this object.
255      */

256     public boolean equals(Object JavaDoc x){
257         MathContext JavaDoc mc;
258         if (!(x instanceof MathContext JavaDoc))
259             return false;
260         mc = (MathContext JavaDoc) x;
261         return mc.precision == this.precision
262             && mc.roundingMode == this.roundingMode; // no need for .equals()
263
}
264
265     /**
266      * Returns the hash code for this <tt>MathContext</tt>.
267      *
268      * @return hash code for this <tt>MathContext</tt>
269      */

270     public int hashCode() {
271         return this.precision + roundingMode.hashCode() * 59;
272     }
273
274     /**
275      * Returns the string representation of this <tt>MathContext</tt>.
276      * The <tt>String</tt> returned represents the settings of the
277      * <tt>MathContext</tt> object as two space-delimited words
278      * (separated by a single space character, <tt>'&#92;u0020'</tt>,
279      * and with no leading or trailing white space), as follows:
280      * <ol>
281      * <li>
282      * The string <tt>&quot;precision=&quot;</tt>, immediately followed
283      * by the value of the precision setting as a numeric string as if
284      * generated by the {@link Integer#toString(int) Integer.toString}
285      * method.
286      *
287      * <li>
288      * The string <tt>&quot;roundingMode=&quot;</tt>, immediately
289      * followed by the value of the <tt>roundingMode</tt> setting as a
290      * word. This word will be the same as the name of the
291      * corresponding public constant in the {@link RoundingMode}
292      * enum.
293      * </ol>
294      * <p>
295      * For example:
296      * <pre>
297      * precision=9 roundingMode=HALF_UP
298      * </pre>
299      *
300      * Additional words may be appended to the result of
301      * <tt>toString</tt> in the future if more properties are added to
302      * this class.
303      *
304      * @return a <tt>String</tt> representing the context settings.
305      */

306     public java.lang.String JavaDoc toString() {
307         return "precision=" + precision + " " +
308            "roundingMode=" + roundingMode.toString();
309     }
310
311     // Private methods
312

313     /**
314      * Reconstitute the <tt>MathContext</tt> instance from a stream (that is,
315      * deserialize it).
316      *
317      * @param s the stream being read.
318      */

319     private synchronized void readObject(java.io.ObjectInputStream JavaDoc s)
320         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
321         s.defaultReadObject(); // read in all fields
322
// validate possibly bad fields
323
if (precision < MIN_DIGITS) {
324             String JavaDoc message = "MathContext: invalid digits in stream";
325             throw new java.io.StreamCorruptedException JavaDoc(message);
326         }
327         if (roundingMode == null) {
328             String JavaDoc message = "MathContext: null roundingMode in stream";
329             throw new java.io.StreamCorruptedException JavaDoc(message);
330         }
331         // Set the lookaside, if applicable
332
if (precision <= MAX_LOOKASIDE) {
333             roundingMax = BigInteger.TEN.pow(precision);
334             roundingMin = roundingMax.negate();
335         }
336     }
337
338 }
339
Popular Tags