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 * (<0 or >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 * (<0 or >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 * (<0 or >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 * (<0 or >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