001: /* Generated from 'MathContext.nrx' 8 Sep 2000 11:07:48 [v2.00] */
002: /* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
003: package com.ibm.icu.math;
004:
005: /* ------------------------------------------------------------------ */
006: /* MathContext -- Math context settings */
007: /* ------------------------------------------------------------------ */
008: /* Copyright IBM Corporation, 1997, 2000, 2005. All Rights Reserved. */
009: /* */
010: /* The MathContext object encapsulates the settings used by the */
011: /* BigDecimal class; it could also be used by other arithmetics. */
012: /* ------------------------------------------------------------------ */
013: /* Notes: */
014: /* */
015: /* 1. The properties are checked for validity on construction, so */
016: /* the BigDecimal class may assume that they are correct. */
017: /* ------------------------------------------------------------------ */
018: /* Author: Mike Cowlishaw */
019: /* 1997.09.03 Initial version (edited from netrexx.lang.RexxSet) */
020: /* 1997.09.12 Add lostDigits property */
021: /* 1998.05.02 Make the class immutable and final; drop set methods */
022: /* 1998.06.05 Add Round (rounding modes) property */
023: /* 1998.06.25 Rename from DecimalContext; allow digits=0 */
024: /* 1998.10.12 change to com.ibm.icu.math package */
025: /* 1999.02.06 add javadoc comments */
026: /* 1999.03.05 simplify; changes from discussion with J. Bloch */
027: /* 1999.03.13 1.00 release to IBM Centre for Java Technology */
028: /* 1999.07.10 1.04 flag serialization unused */
029: /* 2000.01.01 1.06 copyright update */
030: /* ------------------------------------------------------------------ */
031:
032: /**
033: * The <code>MathContext</code> immutable class encapsulates the
034: * settings understood by the operator methods of the {@link BigDecimal}
035: * class (and potentially other classes). Operator methods are those
036: * that effect an operation on a number or a pair of numbers.
037: * <p>
038: * The settings, which are not base-dependent, comprise:
039: * <ol>
040: * <li><code>digits</code>:
041: * the number of digits (precision) to be used for an operation
042: * <li><code>form</code>:
043: * the form of any exponent that results from the operation
044: * <li><code>lostDigits</code>:
045: * whether checking for lost digits is enabled
046: * <li><code>roundingMode</code>:
047: * the algorithm to be used for rounding.
048: * </ol>
049: * <p>
050: * When provided, a <code>MathContext</code> object supplies the
051: * settings for an operation directly.
052: * <p>
053: * When <code>MathContext.DEFAULT</code> is provided for a
054: * <code>MathContext</code> parameter then the default settings are used
055: * (<code>9, SCIENTIFIC, false, ROUND_HALF_UP</code>).
056: * <p>
057: * In the <code>BigDecimal</code> class, all methods which accept a
058: * <code>MathContext</code> object defaults) also have a version of the
059: * method which does not accept a MathContext parameter. These versions
060: * carry out unlimited precision fixed point arithmetic (as though the
061: * settings were (<code>0, PLAIN, false, ROUND_HALF_UP</code>).
062: * <p>
063: * The instance variables are shared with default access (so they are
064: * directly accessible to the <code>BigDecimal</code> class), but must
065: * never be changed.
066: * <p>
067: * The rounding mode constants have the same names and values as the
068: * constants of the same name in <code>java.math.BigDecimal</code>, to
069: * maintain compatibility with earlier versions of
070: * <code>BigDecimal</code>.
071: *
072: * @see BigDecimal
073: * @author Mike Cowlishaw
074: * @stable ICU 2.0
075: */
076:
077: public final class MathContext implements java.io.Serializable {
078: private static final java.lang.String $0 = "MathContext.nrx";
079:
080: /* ----- Properties ----- */
081: /* properties public constant */
082: /**
083: * Plain (fixed point) notation, without any exponent.
084: * Used as a setting to control the form of the result of a
085: * <code>BigDecimal</code> operation.
086: * A zero result in plain form may have a decimal part of one or
087: * more zeros.
088: *
089: * @see #ENGINEERING
090: * @see #SCIENTIFIC
091: * @stable ICU 2.0
092: */
093: public static final int PLAIN = 0; // [no exponent]
094:
095: /**
096: * Standard floating point notation (with scientific exponential
097: * format, where there is one digit before any decimal point).
098: * Used as a setting to control the form of the result of a
099: * <code>BigDecimal</code> operation.
100: * A zero result in plain form may have a decimal part of one or
101: * more zeros.
102: *
103: * @see #ENGINEERING
104: * @see #PLAIN
105: * @stable ICU 2.0
106: */
107: public static final int SCIENTIFIC = 1; // 1 digit before .
108:
109: /**
110: * Standard floating point notation (with engineering exponential
111: * format, where the power of ten is a multiple of 3).
112: * Used as a setting to control the form of the result of a
113: * <code>BigDecimal</code> operation.
114: * A zero result in plain form may have a decimal part of one or
115: * more zeros.
116: *
117: * @see #PLAIN
118: * @see #SCIENTIFIC
119: * @stable ICU 2.0
120: */
121: public static final int ENGINEERING = 2; // 1-3 digits before .
122:
123: // The rounding modes match the original BigDecimal class values
124: /**
125: * Rounding mode to round to a more positive number.
126: * Used as a setting to control the rounding mode used during a
127: * <code>BigDecimal</code> operation.
128: * <p>
129: * If any of the discarded digits are non-zero then the result
130: * should be rounded towards the next more positive digit.
131: * @stable ICU 2.0
132: */
133: public static final int ROUND_CEILING = 2;
134:
135: /**
136: * Rounding mode to round towards zero.
137: * Used as a setting to control the rounding mode used during a
138: * <code>BigDecimal</code> operation.
139: * <p>
140: * All discarded digits are ignored (truncated). The result is
141: * neither incremented nor decremented.
142: * @stable ICU 2.0
143: */
144: public static final int ROUND_DOWN = 1;
145:
146: /**
147: * Rounding mode to round to a more negative number.
148: * Used as a setting to control the rounding mode used during a
149: * <code>BigDecimal</code> operation.
150: * <p>
151: * If any of the discarded digits are non-zero then the result
152: * should be rounded towards the next more negative digit.
153: * @stable ICU 2.0
154: */
155: public static final int ROUND_FLOOR = 3;
156:
157: /**
158: * Rounding mode to round to nearest neighbor, where an equidistant
159: * value is rounded down.
160: * Used as a setting to control the rounding mode used during a
161: * <code>BigDecimal</code> operation.
162: * <p>
163: * If the discarded digits represent greater than half (0.5 times)
164: * the value of a one in the next position then the result should be
165: * rounded up (away from zero). Otherwise the discarded digits are
166: * ignored.
167: * @stable ICU 2.0
168: */
169: public static final int ROUND_HALF_DOWN = 5;
170:
171: /**
172: * Rounding mode to round to nearest neighbor, where an equidistant
173: * value is rounded to the nearest even neighbor.
174: * Used as a setting to control the rounding mode used during a
175: * <code>BigDecimal</code> operation.
176: * <p>
177: * If the discarded digits represent greater than half (0.5 times)
178: * the value of a one in the next position then the result should be
179: * rounded up (away from zero). If they represent less than half,
180: * then the result should be rounded down.
181: * <p>
182: * Otherwise (they represent exactly half) the result is rounded
183: * down if its rightmost digit is even, or rounded up if its
184: * rightmost digit is odd (to make an even digit).
185: * @stable ICU 2.0
186: */
187: public static final int ROUND_HALF_EVEN = 6;
188:
189: /**
190: * Rounding mode to round to nearest neighbor, where an equidistant
191: * value is rounded up.
192: * Used as a setting to control the rounding mode used during a
193: * <code>BigDecimal</code> operation.
194: * <p>
195: * If the discarded digits represent greater than or equal to half
196: * (0.5 times) the value of a one in the next position then the result
197: * should be rounded up (away from zero). Otherwise the discarded
198: * digits are ignored.
199: * @stable ICU 2.0
200: */
201: public static final int ROUND_HALF_UP = 4;
202:
203: /**
204: * Rounding mode to assert that no rounding is necessary.
205: * Used as a setting to control the rounding mode used during a
206: * <code>BigDecimal</code> operation.
207: * <p>
208: * Rounding (potential loss of information) is not permitted.
209: * If any of the discarded digits are non-zero then an
210: * <code>ArithmeticException</code> should be thrown.
211: * @stable ICU 2.0
212: */
213: public static final int ROUND_UNNECESSARY = 7;
214:
215: /**
216: * Rounding mode to round away from zero.
217: * Used as a setting to control the rounding mode used during a
218: * <code>BigDecimal</code> operation.
219: * <p>
220: * If any of the discarded digits are non-zero then the result will
221: * be rounded up (away from zero).
222: * @stable ICU 2.0
223: */
224: public static final int ROUND_UP = 0;
225:
226: /* properties shared */
227: /**
228: * The number of digits (precision) to be used for an operation.
229: * A value of 0 indicates that unlimited precision (as many digits
230: * as are required) will be used.
231: * <p>
232: * The {@link BigDecimal} operator methods use this value to
233: * determine the precision of results.
234: * Note that leading zeros (in the integer part of a number) are
235: * never significant.
236: * <p>
237: * <code>digits</code> will always be non-negative.
238: *
239: * @serial
240: */
241: int digits;
242:
243: /**
244: * The form of results from an operation.
245: * <p>
246: * The {@link BigDecimal} operator methods use this value to
247: * determine the form of results, in particular whether and how
248: * exponential notation should be used.
249: *
250: * @see #ENGINEERING
251: * @see #PLAIN
252: * @see #SCIENTIFIC
253: * @serial
254: */
255: int form; // values for this must fit in a byte
256:
257: /**
258: * Controls whether lost digits checking is enabled for an
259: * operation.
260: * Set to <code>true</code> to enable checking, or
261: * to <code>false</code> to disable checking.
262: * <p>
263: * When enabled, the {@link BigDecimal} operator methods check
264: * the precision of their operand or operands, and throw an
265: * <code>ArithmeticException</code> if an operand is more precise
266: * than the digits setting (that is, digits would be lost).
267: * When disabled, operands are rounded to the specified digits.
268: *
269: * @serial
270: */
271: boolean lostDigits;
272:
273: /**
274: * The rounding algorithm to be used for an operation.
275: * <p>
276: * The {@link BigDecimal} operator methods use this value to
277: * determine the algorithm to be used when non-zero digits have to
278: * be discarded in order to reduce the precision of a result.
279: * The value must be one of the public constants whose name starts
280: * with <code>ROUND_</code>.
281: *
282: * @see #ROUND_CEILING
283: * @see #ROUND_DOWN
284: * @see #ROUND_FLOOR
285: * @see #ROUND_HALF_DOWN
286: * @see #ROUND_HALF_EVEN
287: * @see #ROUND_HALF_UP
288: * @see #ROUND_UNNECESSARY
289: * @see #ROUND_UP
290: * @serial
291: */
292: int roundingMode;
293:
294: /* properties private constant */
295: // default settings
296: private static final int DEFAULT_FORM = SCIENTIFIC;
297: private static final int DEFAULT_DIGITS = 9;
298: private static final boolean DEFAULT_LOSTDIGITS = false;
299: private static final int DEFAULT_ROUNDINGMODE = ROUND_HALF_UP;
300:
301: /* properties private constant */
302:
303: private static final int MIN_DIGITS = 0; // smallest value for DIGITS.
304: private static final int MAX_DIGITS = 999999999; // largest value for DIGITS. If increased,
305: // the BigDecimal class may need update.
306: // list of valid rounding mode values, most common two first
307: private static final int ROUNDS[] = new int[] { ROUND_HALF_UP,
308: ROUND_UNNECESSARY, ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR,
309: ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_UP };
310:
311: private static final java.lang.String ROUNDWORDS[] = new java.lang.String[] {
312: "ROUND_HALF_UP", "ROUND_UNNECESSARY", "ROUND_CEILING",
313: "ROUND_DOWN", "ROUND_FLOOR", "ROUND_HALF_DOWN",
314: "ROUND_HALF_EVEN", "ROUND_UP" }; // matching names of the ROUNDS values
315:
316: /* properties private constant unused */
317:
318: // Serialization version
319: private static final long serialVersionUID = 7163376998892515376L;
320:
321: /* properties public constant */
322: /**
323: * A <code>MathContext</code> object initialized to the default
324: * settings for general-purpose arithmetic. That is,
325: * <code>digits=9 form=SCIENTIFIC lostDigits=false
326: * roundingMode=ROUND_HALF_UP</code>.
327: *
328: * @see #SCIENTIFIC
329: * @see #ROUND_HALF_UP
330: * @stable ICU 2.0
331: */
332: public static final com.ibm.icu.math.MathContext DEFAULT = new com.ibm.icu.math.MathContext(
333: DEFAULT_DIGITS, DEFAULT_FORM, DEFAULT_LOSTDIGITS,
334: DEFAULT_ROUNDINGMODE);
335:
336: /* ----- Constructors ----- */
337:
338: /**
339: * Constructs a new <code>MathContext</code> with a specified
340: * precision.
341: * The other settings are set to the default values
342: * (see {@link #DEFAULT}).
343: *
344: * An <code>IllegalArgumentException</code> is thrown if the
345: * <code>setdigits</code> parameter is out of range
346: * (<0 or >999999999).
347: *
348: * @param setdigits The <code>int</code> digits setting
349: * for this <code>MathContext</code>.
350: * @throws IllegalArgumentException parameter out of range.
351: * @stable ICU 2.0
352: */
353:
354: public MathContext(int setdigits) {
355: this (setdigits, DEFAULT_FORM, DEFAULT_LOSTDIGITS,
356: DEFAULT_ROUNDINGMODE);
357: return;
358: }
359:
360: /**
361: * Constructs a new <code>MathContext</code> with a specified
362: * precision and form.
363: * The other settings are set to the default values
364: * (see {@link #DEFAULT}).
365: *
366: * An <code>IllegalArgumentException</code> is thrown if the
367: * <code>setdigits</code> parameter is out of range
368: * (<0 or >999999999), or if the value given for the
369: * <code>setform</code> parameter is not one of the appropriate
370: * constants.
371: *
372: * @param setdigits The <code>int</code> digits setting
373: * for this <code>MathContext</code>.
374: * @param setform The <code>int</code> form setting
375: * for this <code>MathContext</code>.
376: * @throws IllegalArgumentException parameter out of range.
377: * @stable ICU 2.0
378: */
379:
380: public MathContext(int setdigits, int setform) {
381: this (setdigits, setform, DEFAULT_LOSTDIGITS,
382: DEFAULT_ROUNDINGMODE);
383: return;
384: }
385:
386: /**
387: * Constructs a new <code>MathContext</code> with a specified
388: * precision, form, and lostDigits setting.
389: * The roundingMode setting is set to its default value
390: * (see {@link #DEFAULT}).
391: *
392: * An <code>IllegalArgumentException</code> is thrown if the
393: * <code>setdigits</code> parameter is out of range
394: * (<0 or >999999999), or if the value given for the
395: * <code>setform</code> parameter is not one of the appropriate
396: * constants.
397: *
398: * @param setdigits The <code>int</code> digits setting
399: * for this <code>MathContext</code>.
400: * @param setform The <code>int</code> form setting
401: * for this <code>MathContext</code>.
402: * @param setlostdigits The <code>boolean</code> lostDigits
403: * setting for this <code>MathContext</code>.
404: * @throws IllegalArgumentException parameter out of range.
405: * @stable ICU 2.0
406: */
407:
408: public MathContext(int setdigits, int setform, boolean setlostdigits) {
409: this (setdigits, setform, setlostdigits, DEFAULT_ROUNDINGMODE);
410: return;
411: }
412:
413: /**
414: * Constructs a new <code>MathContext</code> with a specified
415: * precision, form, lostDigits, and roundingMode setting.
416: *
417: * An <code>IllegalArgumentException</code> is thrown if the
418: * <code>setdigits</code> parameter is out of range
419: * (<0 or >999999999), or if the value given for the
420: * <code>setform</code> or <code>setroundingmode</code> parameters is
421: * not one of the appropriate constants.
422: *
423: * @param setdigits The <code>int</code> digits setting
424: * for this <code>MathContext</code>.
425: * @param setform The <code>int</code> form setting
426: * for this <code>MathContext</code>.
427: * @param setlostdigits The <code>boolean</code> lostDigits
428: * setting for this <code>MathContext</code>.
429: * @param setroundingmode The <code>int</code> roundingMode setting
430: * for this <code>MathContext</code>.
431: * @throws IllegalArgumentException parameter out of range.
432: * @stable ICU 2.0
433: */
434:
435: public MathContext(int setdigits, int setform,
436: boolean setlostdigits, int setroundingmode) {
437: super ();
438:
439: // set values, after checking
440: if (setdigits != DEFAULT_DIGITS) {
441: if (setdigits < MIN_DIGITS)
442: throw new java.lang.IllegalArgumentException(
443: "Digits too small:" + " " + setdigits);
444: if (setdigits > MAX_DIGITS)
445: throw new java.lang.IllegalArgumentException(
446: "Digits too large:" + " " + setdigits);
447: }
448: {/*select*/
449: if (setform == SCIENTIFIC) {
450: // [most common]
451: } else if (setform == ENGINEERING) {
452: } else if (setform == PLAIN) {
453: } else {
454: throw new java.lang.IllegalArgumentException(
455: "Bad form value:" + " " + setform);
456: }
457: }
458: if ((!(isValidRound(setroundingmode))))
459: throw new java.lang.IllegalArgumentException(
460: "Bad roundingMode value:" + " " + setroundingmode);
461: digits = setdigits;
462: form = setform;
463: lostDigits = setlostdigits; // [no bad value possible]
464: roundingMode = setroundingmode;
465: return;
466: }
467:
468: /**
469: * Returns the digits setting.
470: * This value is always non-negative.
471: *
472: * @return an <code>int</code> which is the value of the digits
473: * setting
474: * @stable ICU 2.0
475: */
476:
477: public int getDigits() {
478: return digits;
479: }
480:
481: /**
482: * Returns the form setting.
483: * This will be one of
484: * {@link #ENGINEERING},
485: * {@link #PLAIN}, or
486: * {@link #SCIENTIFIC}.
487: *
488: * @return an <code>int</code> which is the value of the form setting
489: * @stable ICU 2.0
490: */
491:
492: public int getForm() {
493: return form;
494: }
495:
496: /**
497: * Returns the lostDigits setting.
498: * This will be either <code>true</code> (enabled) or
499: * <code>false</code> (disabled).
500: *
501: * @return a <code>boolean</code> which is the value of the lostDigits
502: * setting
503: * @stable ICU 2.0
504: */
505:
506: public boolean getLostDigits() {
507: return lostDigits;
508: }
509:
510: /**
511: * Returns the roundingMode setting.
512: * This will be one of
513: * {@link #ROUND_CEILING},
514: * {@link #ROUND_DOWN},
515: * {@link #ROUND_FLOOR},
516: * {@link #ROUND_HALF_DOWN},
517: * {@link #ROUND_HALF_EVEN},
518: * {@link #ROUND_HALF_UP},
519: * {@link #ROUND_UNNECESSARY}, or
520: * {@link #ROUND_UP}.
521: *
522: * @return an <code>int</code> which is the value of the roundingMode
523: * setting
524: * @stable ICU 2.0
525: */
526:
527: public int getRoundingMode() {
528: return roundingMode;
529: }
530:
531: /** Returns the <code>MathContext</code> as a readable string.
532: * The <code>String</code> returned represents the settings of the
533: * <code>MathContext</code> object as four blank-delimited words
534: * separated by a single blank and with no leading or trailing blanks,
535: * as follows:
536: * <ol>
537: * <li>
538: * <code>digits=</code>, immediately followed by
539: * the value of the digits setting as a numeric word.
540: * <li>
541: * <code>form=</code>, immediately followed by
542: * the value of the form setting as an uppercase word
543: * (one of <code>SCIENTIFIC</code>, <code>PLAIN</code>, or
544: * <code>ENGINEERING</code>).
545: * <li>
546: * <code>lostDigits=</code>, immediately followed by
547: * the value of the lostDigits setting
548: * (<code>1</code> if enabled, <code>0</code> if disabled).
549: * <li>
550: * <code>roundingMode=</code>, immediately followed by
551: * the value of the roundingMode setting as a word.
552: * This word will be the same as the name of the corresponding public
553: * constant.
554: * </ol>
555: * <p>
556: * For example:
557: * <br><code>
558: * digits=9 form=SCIENTIFIC lostDigits=0 roundingMode=ROUND_HALF_UP
559: * </code>
560: * <p>
561: * Additional words may be appended to the result of
562: * <code>toString</code> in the future if more properties are added
563: * to the class.
564: *
565: * @return a <code>String</code> representing the context settings.
566: * @stable ICU 2.0
567: */
568:
569: public java.lang.String toString() {
570: java.lang.String formstr = null;
571: int r = 0;
572: java.lang.String roundword = null;
573: {/*select*/
574: if (form == SCIENTIFIC)
575: formstr = "SCIENTIFIC";
576: else if (form == ENGINEERING)
577: formstr = "ENGINEERING";
578: else {
579: formstr = "PLAIN";/* form=PLAIN */
580: }
581: }
582: {
583: int $1 = ROUNDS.length;
584: r = 0;
585: r: for (; $1 > 0; $1--, r++) {
586: if (roundingMode == ROUNDS[r]) {
587: roundword = ROUNDWORDS[r];
588: break r;
589: }
590: }
591: }/*r*/
592: return "digits=" + digits + " " + "form=" + formstr + " "
593: + "lostDigits=" + (lostDigits ? "1" : "0") + " "
594: + "roundingMode=" + roundword;
595: }
596:
597: /* <sgml> Test whether round is valid. </sgml> */
598: // This could be made shared for use by BigDecimal for setScale.
599: private static boolean isValidRound(int testround) {
600: int r = 0;
601: {
602: int $2 = ROUNDS.length;
603: r = 0;
604: r: for (; $2 > 0; $2--, r++) {
605: if (testround == ROUNDS[r])
606: return true;
607: }
608: }/*r*/
609: return false;
610: }
611: }
|