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