You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/04/20 06:13:47 UTC
svn commit: r395476 [1/3] - in
/incubator/harmony/enhanced/classlib/trunk/modules/math/src:
main/java/java/math/ test/java/org/apache/harmony/tests/java/math/
test/java/tests/api/java/math/
Author: mloenko
Date: Wed Apr 19 21:13:44 2006
New Revision: 395476
URL: http://svn.apache.org/viewcvs?rev=395476&view=rev
Log:
improvements from HARMONY-380:
extension of java.math with 1.5 methods
Added:
incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/MathContext.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/RoundingMode.java
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigDecimalArithmeticTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigDecimalCompareTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigDecimalConstructorsTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigDecimalConvertTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigDecimalScaleOperationsTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerAddTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerAndTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerCompareTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerConstructorsTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerConvertTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerDivideTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerHashCodeTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerModPowTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerMultiplyTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerNotTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerOperateBitsTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerOrTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerSubtractTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerToStringTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/org/apache/harmony/tests/java/math/BigIntegerXorTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/tests/api/java/math/BigDecimalTest.java
incubator/harmony/enhanced/classlib/trunk/modules/math/src/test/java/tests/api/java/math/BigIntegerTest.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java?rev=395476&r1=395475&r2=395476&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java Wed Apr 19 21:13:44 2006
@@ -15,7 +15,7 @@
*/
/**
* @author Elena Semukhina
- * @version $Revision: 1.11.2.3 $
+ * @version $Revision$
*/
package java.math;
@@ -38,7 +38,8 @@
*
* @see java.math.BigInteger
*/
-public class BigDecimal extends Number implements Comparable, Serializable {
+public class BigDecimal extends Number
+ implements Comparable<BigDecimal>, Serializable {
/**
* @com.intel.drl.spec_ref
@@ -46,12 +47,12 @@
private static final long serialVersionUID = 6108874887143696463L;
/**
- * @com.intel.drl.spec_ref
+ * The unscaled value of this BigDecimal
*/
private BigInteger intVal;
/**
- * @com.intel.drl.spec_ref
+ * The scale of this BigDecimal
*/
private int scale;
@@ -111,6 +112,23 @@
public static final int ROUND_UP = 0;
/**
+ * Controls overflow in the calculated preferred scale.
+ * If it overflows a 32-bit integer, return extreme Integer values.
+ * @param longScale the long preferred scale.
+ * @return int scale.
+ */
+ private int getPreferredScale(long longScale) {
+ if (longScale != (int) longScale) {
+ if (longScale < 0) {
+ return Integer.MIN_VALUE;
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+ return (int) longScale;
+ }
+
+ /**
* Verifies if a value overflows a 32-bit integer.
* @param longVal long value to be verified.
* @param val the name of the value.
@@ -124,6 +142,13 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public static BigDecimal valueOf(double value) {
+ return new BigDecimal(Double.toString(value));
+ }
+
+ /**
* Translate long value into a BigDecimal with scale of zero.
*
* @return BigDecimal BigDecimal equivalence of a long value.
@@ -162,6 +187,125 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(BigInteger unscaledVal, int scale, MathContext mC) {
+ this(unscaledVal, scale);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(BigInteger value, MathContext mC) {
+ this(value);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(char[] input) {
+ this(input, 0, input.length);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(char[] in, int offset, int len) {
+ int endIndex = offset + len - 1;
+ if (offset < 0 || endIndex >= in.length) {
+ throw new NumberFormatException("the subarray exceeds the bounds" +
+ " of the array");
+ }
+ int count = 0; // the pointer to the current char
+ int dotPosition = -1; // the position of the decimal point
+ String unscaled;
+ String exponent;
+ char symbol = in[offset];
+ int startIndex = symbol == '+' ? offset + 1 : offset;
+
+ // parse the significand
+ for (count = startIndex; count <= endIndex; count++) {
+ symbol = in[count];
+ if (symbol == '.') {
+ dotPosition = count;
+ }
+ if (symbol == 'e' || symbol == 'E') {
+ break;
+ }
+ }
+ if (dotPosition < 0) {
+ unscaled = new String(in, startIndex, count - startIndex);
+ scale = 0;
+ } else {
+ unscaled = new String(in, startIndex, dotPosition - startIndex) +
+ ((dotPosition == endIndex)
+ ? ""
+ : new String(in, dotPosition + 1, count - dotPosition - 1));
+ scale = count - dotPosition - 1;
+ }
+ intVal = new BigInteger(unscaled);
+
+ // parse the exponent
+ if (count <= endIndex) {
+ if (++count > endIndex) { // skip 'E'
+ throw new NumberFormatException("empty exponent");
+ }
+ symbol = in[count];
+ if ((symbol == '+' || symbol == '-') && count == endIndex) {
+ throw new NumberFormatException("empty exponent");
+ }
+ if (symbol == '+') {
+ count++;
+ }
+ exponent = new String(in, count, endIndex - count + 1);
+ int exp = 0;
+ try {
+ exp = Integer.parseInt(exponent);
+ } catch (NumberFormatException e) {
+ throw new NumberFormatException("exponent is not " +
+ "signed integer");
+ }
+
+ // the value of the resulting scale must lie between
+ // Integer.MIN_VALUE and Integer.MAX_VALUE inclusive
+ long longScale = (long) scale - (long) exp;
+ if (longScale != (int) longScale) {
+ throw new NumberFormatException("resulting scale out of range");
+ }
+ scale = (int) longScale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(char[] input, int offset, int len, MathContext mC) {
+ this(input, offset, len);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(char[] input, MathContext mC) {
+ this(input, 0, input.length, mC);
+ }
+
+ /**
* Constructs a BigDecimal with a double value as an arugment.
*
* @exception NumberFormatException
@@ -202,6 +346,56 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(double value, MathContext mC) {
+ this(value);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(int value) {
+ this(new Integer(value).toString());
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(int value, MathContext mC) {
+ this(value);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(long value) {
+ this(new Long(value).toString());
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(long value, MathContext mC) {
+ this(value);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
* Constructs a BigDecimal from the string which can only
* contain digits of 0-9, a decimal point and a negative sign.
*
@@ -268,6 +462,18 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal(String value, MathContext mC) {
+ this(value);
+ if (mC.precision != 0) {
+ BigDecimal rounded = this.round(mC);
+ this.intVal = rounded.intVal;
+ this.scale = rounded.scale;
+ }
+ }
+
+ /**
* Answers the absolute value of this BigDecimal.
*
* @return BigDecimal absolute value of the receiver.
@@ -277,6 +483,13 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal abs(MathContext mC) {
+ return round(mC).abs();
+ }
+
+ /**
* Answers the sum of the receiver and argument.
*
* @return BigDecimal The sum of adding two BigDecimal.
@@ -297,6 +510,52 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal add(BigDecimal value, MathContext mC) {
+ if (mC.precision == 0) {
+ return add(value);
+ }
+ int newScale = Math.max(this.scale, value.scale);
+ BigDecimal result = null;
+ boolean thisZero = this.intVal.signum() == 0;
+ boolean valueZero = value.intVal.signum() == 0;
+ if (thisZero || valueZero) {
+ if (thisZero && valueZero) {
+ return new BigDecimal(BigInteger.ZERO, newScale);
+ }
+ result = (thisZero) ? value.round(mC) : this.round(mC);
+ if (newScale == result.scale) {
+ return result;
+ }
+ if (newScale > result.scale) {
+ // try to increase the result.scale
+ // and stay in precision's limits
+ if (mC.precision - result.precision() >=
+ newScale - result.scale) {
+
+ return result.setScale(newScale);
+ } else {
+ return result.setScale(result.scale + mC.precision -
+ result.precision());
+ }
+ } else {
+ // try to decrease the result.scale by stripping possible zeros
+ return result.stripTrailingZeros(newScale);
+ }
+ }
+ // both != 0
+ return round(add(value), mC);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public byte byteValueExact() {
+ return (byte)valueExact(3, "127", "-128");
+ }
+
+ /**
* Compares the receiver BigDecimal and argument BigDecimal e.x 1.00 & 1.0
* will return 0 in compareTo.
*
@@ -316,17 +575,46 @@
}
/**
- * Compares an receiver to the argument Object.
- *
- * @return int 0 - equal; 1 - this > object; -1 - this < object
- * @exception ClassCastException
- * if the argument is not of type BigDecimal
+ * @com.intel.drl.spec_ref
*/
- public int compareTo(Object object) {
- if (object instanceof BigDecimal) {
- return (this.compareTo((BigDecimal)object));
+ public BigDecimal divide(BigDecimal value) {
+ if (value.intVal.signum() == 0) {
+ throw new ArithmeticException("division by zero");
}
- throw new ClassCastException("BigDecimals are comparable only with other BigDecimals");
+ int newScale = getValidInt((long) this.scale - (long) value.scale,
+ "preferred scale");
+ if (this.intVal.signum() == 0) {
+ return new BigDecimal(BigInteger.ZERO, newScale);
+ }
+ // Try to evaluate the precision of the terminating decimal expansion
+ // of the result.
+ // this / value = this * (1 / value).
+ // The precision of the result is not greater than the sum of
+ // this.precision and the precision of (1 / value).
+ // It is known that the precision of (1 / 2 ^ n) is n digits.
+ // We approximate the value.intVal by 2 ^ n
+ // where n is the bit length of value.intVal.
+ // It is known that the number of bits for a radix digit is
+ // log(radix) / log(2).
+ // The bit length can be approximated by precision * log(10) / log(2).
+
+ int resultPrecision = getValidInt((long) this.precision() +
+ (long) Math.ceil(value.precision() * 3.321928094887362),
+ "result precision");
+ MathContext divisionMC = new MathContext(resultPrecision,
+ RoundingMode.UNNECESSARY);
+ BigDecimal result;
+ // if the exact result cannot be computed, throw the exception
+ try {
+ result = divide(value, divisionMC);
+ } catch (ArithmeticException e) {
+ throw new ArithmeticException("quotient does not have " +
+ "a terminating decimal expansion");
+ }
+ if (newScale > result.scale) {
+ result = result.setScale(newScale);
+ }
+ return result;
}
/**
@@ -413,6 +701,161 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal divide(BigDecimal value, int scale, RoundingMode rm) {
+ return divide(value, scale, rm.bigDecimalRM);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal divide(BigDecimal value, MathContext mC) {
+ if (mC.precision == 0) {
+ return divide(value);
+ }
+ if (value.intVal.signum() == 0) {
+ throw new ArithmeticException("division by zero");
+ }
+ int newScale = getPreferredScale((long) this.scale - (long) value.scale);
+ if (this.intVal.signum() == 0) {
+ return new BigDecimal(BigInteger.ZERO, newScale);
+ }
+ long sDAdd = newScale > 0 ? newScale + 1L : 1L;
+ int pD = value.precision() - this.precision();
+ long pDAdd = pD > 0 ? pD + 1 : 1;
+ int divScale = getValidInt(mC.precision + 1 + pDAdd + sDAdd,
+ "intermediate division scale");
+ BigDecimal result = divide(value, divScale,
+ mC.roundingMode.bigDecimalRM);
+ result = round(result, mC);
+ if (result.multiply(value).compareTo(this) == 0) {
+ // exact result
+ result = result.stripTrailingZeros(newScale);
+ }
+ return result;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal divide(BigDecimal value, RoundingMode rm) {
+ return divide(value, rm.bigDecimalRM);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal[] divideAndRemainder(BigDecimal value) {
+ BigDecimal resultArray[] = new BigDecimal[2];
+ resultArray[0] = divideToIntegralValue(value);
+ resultArray[1] = subtract(resultArray[0].multiply(value));
+ return resultArray;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal[] divideAndRemainder(BigDecimal value, MathContext mC) {
+ if (mC.precision == 0) {
+ return divideAndRemainder(value);
+ }
+ BigDecimal resultArray[] = new BigDecimal[2];
+ resultArray[0] = divideToIntegralValue(value, mC);
+ resultArray[1] = subtract(resultArray[0].multiply(value));
+ return resultArray;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal divideToIntegralValue(BigDecimal value) {
+ if (value.intVal.signum() == 0) {
+ throw new ArithmeticException("division by zero");
+ }
+ int newScale = getPreferredScale((long) this.scale - (long)value.scale);
+ if (this.intVal.signum() == 0) {
+ return setScale(newScale);
+ }
+ if (value.abs().compareTo(this.abs()) > 0) {
+ // if the divisor > the dividend, return 0
+ return new BigDecimal(BigInteger.ZERO, newScale);
+ }
+ // below the divisor always <= the dividend
+ int dA = this.precision() - this.scale;
+ int dB = value.precision() - value.scale;
+ int divisionPrecision;
+ if (dA > 0 && dB > 0) { // there are integer parts in both numbers
+ // extra digits for rounding
+ divisionPrecision = dA - dB + (dA == dB ? 2 : 1);
+ } else if (dA > 0 && dB <= 0) {
+ // this has an integer part and value is a fraction
+ divisionPrecision = dA + Math.abs(dB) + 1;
+ } else {
+ // both are fractions
+ divisionPrecision = Math.abs(dA) + Math.abs(dB) + 1;
+ }
+ // control overflow
+ if (divisionPrecision < 0) {
+ divisionPrecision = Integer.MAX_VALUE;
+ }
+ BigDecimal result = divide(value, new MathContext(divisionPrecision,
+ RoundingMode.DOWN));
+ if (result.scale > 0) {
+ // round to an integer part
+ result = result.setScale(0, RoundingMode.DOWN);
+ }
+ if (result.scale > newScale) {
+ result = result.stripTrailingZeros(newScale);
+ } else if (result.scale < newScale) {
+ result = result.setScale(newScale);
+ }
+ return result;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal divideToIntegralValue(BigDecimal value, MathContext mC) {
+ if (mC.precision == 0) {
+ return divideToIntegralValue(value);
+ }
+ if (value.intVal.signum() == 0) {
+ throw new ArithmeticException("division by zero");
+ }
+ int newScale = getPreferredScale((long) this.scale - (long)value.scale);
+ if (value.abs().compareTo(this.abs()) > 0) {
+ return new BigDecimal(BigInteger.ZERO, newScale);
+ }
+ BigDecimal result = divide(value, new MathContext(mC.precision,
+ RoundingMode.DOWN));
+ if (result.scale > 0) {
+ // round to an integer part
+ result = result.setScale(0, RoundingMode.DOWN);
+ } else if (result.scale < 0) { // got an integer
+ BigDecimal remainder = this.subtract(result.multiply(value));
+ // compare the divisor and the remainder
+ if ((value.abs()).compareTo(remainder.abs()) == -1) {
+ throw new ArithmeticException(
+ "integer part of the quotient needs more than " +
+ mC.precision + " digits");
+ }
+ }
+ // result.scale <= 0;
+ int dP = mC.precision - result.precision();
+ int dS = getValidInt((long) newScale - (long) result.scale,
+ "temporary scale");
+ if (dS != 0 || dP != 0) {
+ if (dS < 0 || dP < 0) {
+ result = result.stripTrailingZeros(newScale);
+ } else {
+ result = result.setScale(result.scale + Math.min(dS, dP));
+ }
+ }
+ return result;
+ }
+
+ /**
* Converts this BigDecimal to a double. If magnitude of the BigDecimal
* value is larger than what can be represented by a double, either Infinity
* or -Infinity is returned.
@@ -437,8 +880,8 @@
*/
public boolean equals(Object object) {
return (object instanceof BigDecimal &&
- this.compareTo(object) == 0 &&
- this.scale == ((BigDecimal)object).scale);
+ this.compareTo((BigDecimal)object) == 0 &&
+ this.scale == ((BigDecimal)object).scale);
}
/**
@@ -475,6 +918,13 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public int intValueExact() {
+ return (int) valueExact(10, "2147483647", "-2147483648");
+ }
+
+ /**
* Converts this BigDecimal to a long.
*
* @return long long representation of the receiver.
@@ -484,6 +934,13 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public long longValueExact() {
+ return valueExact(19, "9223372036854775807", "-9223372036854775808");
+ }
+
+ /**
* Answers the max value between the receiver and this BigDecimal.
*
* @return BigDecimal max BigDecimal.
@@ -544,6 +1001,17 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal multiply(BigDecimal value, MathContext mC) {
+ if (mC.precision != 0) {
+ return round(this.multiply(value), mC);
+ } else {
+ return this.multiply(value);
+ }
+ }
+
+ /**
* Negates this BigDecimal value.
*
* @return BigDecimal new BigDecimal with value negated.
@@ -553,6 +1021,136 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal negate(MathContext mC) {
+ return round(mC).negate();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal plus() {
+ return this;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal plus(MathContext mc) {
+ return round(mc);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal pow(int exp) {
+ if (exp < 0 || exp > 999999999) {
+ throw new ArithmeticException("power is out of range");
+ }
+ if (intVal.signum() == 0 && exp == 0) {
+ return ONE;
+ }
+ // test if it fits an int
+ int newScale = getValidInt((long) scale * exp, "result scale");
+ return new BigDecimal(this.intVal.pow(exp), newScale);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal pow(int exp, MathContext mC) {
+ if (mC.precision == 0) {
+ return pow(exp);
+ }
+ if (exp < -999999999 || exp > 999999999) {
+ throw new ArithmeticException("exponent out of range");
+ }
+ if (exp == 0) {
+ return ONE;
+ }
+ int expV = Math.abs(exp);
+ int expLen = new Integer(expV).toString().length();
+ if (expLen > mC.precision) {
+ throw new ArithmeticException("exponent is longer than " +
+ "MathContext precision");
+ }
+ MathContext multMC = new MathContext(mC.precision + expLen + 1,
+ mC.roundingMode);
+ BigDecimal result = ONE;
+ do {
+ result = this.multiply(result, multMC);
+ } while (--expV > 0);
+ if (exp < 0) {
+ result = ONE.divide(result, multMC);
+ }
+ return round(result, mC);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public int precision() {
+ if (intVal.equals(BigInteger.ZERO)) {
+ return 1;
+ }
+ return intVal.toString().length() - (intVal.signum() == -1 ? 1 : 0);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal remainder(BigDecimal value) {
+ return divideAndRemainder(value)[1];
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal remainder(BigDecimal value, MathContext mC) {
+ return divideAndRemainder(value, mC)[1];
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal round(MathContext mC) {
+ if (mC.precision == 0) {
+ return this;
+ }
+ return round(this, mC);
+ }
+
+ /**
+ * Rounds a BigDecimal according to required MathContext
+ * @param value the BigDecimal to be rounded
+ * @param mc the context to use
+ * @return the rounded value
+ */
+ private BigDecimal round(BigDecimal value, MathContext mC) {
+ int delta = mC.precision - value.precision();
+ if (delta >= 0) {
+ return value;
+ }
+ BigDecimal result =
+ value.divide(new BigDecimal(BigInteger.TEN.pow(-delta), 0),
+ value.scale, mC.roundingMode.bigDecimalRM);
+ result.scale += delta;
+ if (result.precision() != mC.precision) {
+ result = round(result, mC);
+ }
+ return result;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal scaleByPowerOfTen(int n) {
+ int intScale = getValidInt((long) this.scale - (long) n, "scale");
+ return new BigDecimal(this.intVal, intScale);
+ }
+
+ /**
* Returns the scale of this BigDecimal.
*
* @return int scale value.
@@ -594,6 +1192,53 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal setScale(int newScale, RoundingMode rm) {
+ return setScale(newScale, rm.bigDecimalRM);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public short shortValueExact() {
+ return (short)valueExact(5, "36767", "-36768");
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal stripTrailingZeros() {
+ return stripTrailingZeros(Integer.MIN_VALUE);
+ }
+
+ /**
+ * Remove trailing zeros to make the scale closer to the required scale
+ * @param newScale the required scale
+ * @return this BigDecimal with reduced scale
+ */
+ private BigDecimal stripTrailingZeros(int newScale) {
+ if (intVal.testBit(0)) {
+ return this;
+ }
+ BigDecimal result = this;
+ StringBuffer strVal = new StringBuffer(intVal.toString());
+ int checkedChar = strVal.length();
+ while (--checkedChar > 0) {
+ if (strVal.charAt(checkedChar) != '0') {
+ break;
+ }
+ strVal.deleteCharAt(checkedChar);
+ result.scale--;
+ if (result.scale == newScale) {
+ break;
+ }
+ }
+ result.intVal = new BigInteger(strVal.toString());
+ return result;
+ }
+
+ /**
* Answers the signum function of this instance.
*
* @return int -1, 0, or 1 if the receiver is negative, zero, or positive.
@@ -623,6 +1268,16 @@
}
/**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal subtract(BigDecimal value, MathContext mC) {
+ if (mC.precision == 0) {
+ return subtract(value);
+ }
+ return add(value.negate(), mC);
+ }
+
+ /**
* Converts this to a BigInteger.
*
* @return BigInteger BigDecimal equivalent of BigInteger.
@@ -640,6 +1295,87 @@
/**
* @com.intel.drl.spec_ref
*/
+ public BigInteger toBigIntegerExact() {
+ if (intVal.signum() == 0) {
+ return intVal;
+ }
+ String strVal = this.intVal.toString();
+ if (scale > 0) {
+ // check the fractional part
+ int checkedChar = strVal.length();
+ for (int i = 1; i <= scale; i++) {
+ if (strVal.charAt(--checkedChar) != '0') {
+ throw new ArithmeticException("nonzero fractional part");
+ }
+ }
+ }
+ return toBigInteger();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public String toEngineeringString() {
+ String intString = intVal.toString();
+ if (scale == 0) {
+ return intString;
+ }
+ boolean negNumber = intVal.signum() < 0;
+ int startPoint = negNumber ? 2 : 1;
+ int endPoint = intString.length();
+ int exponent = -scale + intString.length() - (negNumber ? 2 : 1);
+ StringBuffer result = new StringBuffer(intString);
+ if (scale > 0 && exponent >= -6) {
+ if (exponent >= 0) {
+ result.insert(exponent + (negNumber ? 2 : 1), '.');
+ } else {
+ char zeros[] = new char[-exponent + 1];
+ zeros[0] = '0';
+ zeros[1] = '.';
+ for (int i = 2; i < zeros.length; i++) {
+ zeros[i] = '0';
+ }
+ result.insert(negNumber ? 1 : 0, zeros);
+ }
+ } else {
+ int delta = endPoint - startPoint;
+ int rem = exponent % 3;
+ if (rem != 0) {
+ // adjust exponent so it is a multiple of three
+ if (intVal.signum() == 0) {
+ // zero value
+ rem = rem < 0 ? -rem : 3 - rem;
+ exponent += rem;
+ } else {
+ // nonzero value
+ rem = rem < 0 ? rem + 3 : rem;
+ exponent -= rem;
+ startPoint += rem;
+ }
+ if (delta < 3) {
+ for (int i = rem - delta; i > 0; i--) {
+ result.insert(endPoint++, '0');
+ }
+ }
+ }
+ if (endPoint - startPoint >= 1) {
+ result.insert(startPoint, '.');
+ endPoint++;
+ }
+ if (exponent != 0) {
+ result.insert(endPoint, 'E');
+ if (exponent > 0) {
+ result.insert(++endPoint, '+');
+ }
+ result.insert(++endPoint, Integer.toString(exponent));
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
public String toPlainString() {
String intString = intVal.toString();
if (scale == 0) {
@@ -714,6 +1450,61 @@
result.insert(++endPoint, Integer.toString(exponent));
}
return result.toString();
+ }
+
+ /**
+ * Calculates an exact value of a primitive type.
+ * @param charsPerMaxValue the number of characters in a type's
+ * extreme value, e.g. 9 for an int.
+ * @param maxValue the type's maximal value
+ * @param minValue the type's minimal value
+ * @return the long value of this BigDecimal
+ */
+ private long valueExact(int charsPerMaxValue, String maxValue,
+ String minValue) {
+ int valueSign = intVal.signum();
+ if (valueSign == 0) {
+ return 0;
+ }
+ StringBuffer strVal = new StringBuffer(intVal.toString());
+ int startChar = valueSign == 1 ? 0 : 1;
+ if (scale > 0) {
+ // check the fractional part
+ int checkedChar = strVal.length() - 1;
+ for (int i = 1; i <= scale; i++) {
+ if (strVal.charAt(checkedChar) != '0') {
+ throw new ArithmeticException("nonzero fractional part");
+ }
+ strVal.deleteCharAt(checkedChar);
+ checkedChar--;
+ }
+ } else {
+ for (int i = 1; i <= -scale; i++) {
+ strVal.append('0');
+ }
+ }
+ int delta = ((valueSign == 1)
+ ? charsPerMaxValue
+ : charsPerMaxValue + 1) - strVal.length();
+ if (delta < 0) {
+ throw new ArithmeticException("number does not fit in an int");
+ }
+ for (int i = 0; i < delta; i++) {
+ strVal.insert(startChar, '0');
+ }
+ String stringValue = strVal.toString();
+ if (valueSign == 1 && stringValue.compareTo(maxValue) > 0 ||
+ valueSign == -1 && stringValue.compareTo(minValue) > 0 ) {
+ throw new ArithmeticException("number does not fit in an int");
+ }
+ return new Long(stringValue).longValue();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public BigDecimal ulp() {
+ return new BigDecimal(BigInteger.ONE, scale);
}
/**
Modified: incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java?rev=395476&r1=395475&r2=395476&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java Wed Apr 19 21:13:44 2006
@@ -15,7 +15,7 @@
*/
/**
* @author Elena Semukhina
- * @version $Revision: 1.30.2.4 $
+ * @version $Revision$
*/
package java.math;
@@ -31,12 +31,24 @@
* contain values that cannot be changed. Thus, most operations on the
* BigInteger objects yield new instances of BigInteger.
*/
-public class BigInteger extends Number implements Comparable, Serializable {
+public class BigInteger extends Number implements Comparable<BigInteger>, Serializable {
private static final int EQUALS = 0;
private static final int GREATER = 1;
private static final int LESS = -1;
private static final BigInteger NEG_ONE = new BigInteger (-1, 1);
+ // bigRadices values are precomputed maximal powers of radices
+ // (integer numbers from 2 to 36) that fit into unsigned int (32 bits).
+ // bigRadices[0] = 2 ^ 31, bigRadices[8] = 10 ^ 9, etc.
+ private static final int bigRadices[] = {
+ -2147483648, 1162261467, 1073741824, 1220703125, -2118184960,
+ 1977326743,1073741824, 387420489, 1000000000, 214358881, 429981696,
+ 815730721, 1475789056, 170859375, 268435456, 410338673, 612220032,
+ 893871739, 1280000000, 1801088541, 113379904, 148035889, 191102976,
+ 244140625, 308915776, 387420489, 481890304, 594823321, 729000000,
+ 887503681, 1073741824, 1291467969, 1544804416, 1838265625, 60466176
+ };
+
// the first 54 prime numbers were copied from the published sources,
// e.g. http://en.wikipedia.org/wiki/List_of_prime_numbers#The_first_500_prime_numbers
private static final int primes[] = {
@@ -808,23 +820,20 @@
bigRadixDigitsLength++;
}
digits = new int[bigRadixDigitsLength];
-
- // calculate "big radix": exp(radix, charsPerInt)
+ // get the maximal power of radix that fits in int
+ int bigRadix = bigRadices[radix - 2];
- int bigRadix = radix;
- for (int n = 1; n < charsPerInt; n++) {
- bigRadix *= radix;
- }
-
// parse an input string and accumulate the BigInteger's magnitude
int digitIndex = 0; // index of digits array
- int substrEnd = startChar + (topChars == 0 ? charsPerInt : topChars);
+ int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
int newDigit;
for (int substrStart = startChar; substrStart < endChar;
- substrStart = substrEnd, substrEnd = substrStart + charsPerInt) {
- int bigRadixDigit = Integer.parseInt(stringValue.substring(
- substrStart, substrEnd), radix);
+ substrStart = substrEnd,
+ substrEnd = substrStart + charsPerInt) {
+ int bigRadixDigit =
+ Integer.parseInt(stringValue.substring(substrStart, substrEnd),
+ radix);
newDigit = multiplyByInt(digits, digitIndex, bigRadix);
newDigit += addIntToArray(digits, digitIndex, bigRadixDigit);
digits[digitIndex++] = newDigit;
@@ -1179,27 +1188,6 @@
}
/**
- * Answers an integer indicating the relative positions of the receiver and
- * the argument in the natural order of elements of the receiver's class.
- *
- * @return int which should be <0 if the receiver should sort before the
- * argument, 0 if the receiver should sort in the same position as
- * the argument, and >0 if the receiver should sort after the
- * argument.
- * @param obj
- * Object an object to compare the receiver to
- * @exception ClassCastException
- * if the argument can not be converted into something
- * comparable with the receiver.
- */
- public int compareTo(Object obj) {
- if (obj instanceof BigInteger) {
- return (this.compareTo((BigInteger)obj));
- }
- throw new ClassCastException();
- }
-
- /**
* Constructs randomly a big integer of the specified bit length.
* @param numberBitLength the length in bits
* @param rand source of random bits
@@ -2333,42 +2321,36 @@
}
double bitsForRadixDigit;
if (radix == 10) {
- bitsForRadixDigit = 3.321928094887362; // precomputed
+ bitsForRadixDigit = 3.3219280948873626;
} else {
bitsForRadixDigit = Math.log(radix) / Math.log(2);
}
- int resLengthInChars = (int)(abs().bitLength() /
- bitsForRadixDigit + (sign == -1 ? 1 : 0));
- StringBuffer result = new StringBuffer(resLengthInChars);
- int resDigit = -1;
- if (radix == 16) {
- for (int i = 0; i < numberLength; i++) {
- for (int j = 0; j < 8; j++) {
- resDigit = digits[i] >> (4 * j) & 0xf;
- result.insert(0, Character.forDigit(resDigit, 16));
- }
- }
- } else {
+ int resLengthInChars = (int)(abs().bitLength() / bitsForRadixDigit
+ + ((sign == -1) ? 1 : 0)) + 1;
+ char result[] = new char[resLengthInChars];
+ int currentChar = resLengthInChars;
+ int resDigit;
+ if (radix != 16) {
int temp[] = new int[numberLength];
System.arraycopy(digits, 0, temp, 0, numberLength);
int tempLen = numberLength;
int charsPerInt = getCharsPerInt(radix);
- int bigRadix = 1;
int i;
- // compute the maximal power of radix that fits in int
- for (i = 1; i < charsPerInt; i++) {
- bigRadix *= radix;
- }
+ // get the maximal power of radix that fits in int
+ int bigRadix = bigRadices[radix - 2];
while (true) {
// divide the array of digits by bigRadix and convert remainders
- // to String representation concatenating them in a StringBuffer
+ // to characters collecting them in the char array
resDigit = divideArrayByInt(temp, temp, tempLen, bigRadix);
- String res = Integer.toString(resDigit, radix);
- result.insert(0, res);
- int delta = charsPerInt - res.length() - 1;
- for (i = 0; i < delta; i++) {
- result.insert(0, '0');
- }
+ int previous = currentChar;
+ do {
+ result[--currentChar] =
+ Character.forDigit(resDigit % radix, radix);
+ } while (((resDigit /= radix) != 0) && (currentChar != 0));
+ int delta = charsPerInt - previous + currentChar;
+ for (i = 0; i < delta && currentChar > 0; i++) {
+ result[--currentChar] = '0';
+ }
for (i = tempLen - 1; i > 0 && temp[i] == 0; i--) {
;
}
@@ -2377,14 +2359,22 @@
break;
}
}
+ } else {
+ // radix == 16
+ for (int i = 0; i < numberLength; i++) {
+ for (int j = 0; j < 8 && currentChar > 0; j++) {
+ resDigit = digits[i] >> (4 * j) & 0xf;
+ result[--currentChar] = Character.forDigit(resDigit, 16);
+ }
+ }
}
- while (result.charAt(0) == '0') {
- result.deleteCharAt(0);
+ while (result[currentChar] == '0') {
+ currentChar++;
}
if (sign == -1) {
- result.insert(0, '-');
+ result[--currentChar] = '-';
}
- return result.toString();
+ return new String(result, currentChar, resLengthInChars - currentChar);
}
/**
Added: incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/MathContext.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/MathContext.java?rev=395476&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/MathContext.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/MathContext.java Wed Apr 19 21:13:44 2006
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Elena Semukhina
+ * @version $Revision$
+ */
+
+package java.math;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * @com.intel.drl.spec_ref
+ */
+public class MathContext implements Serializable {
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final MathContext DECIMAL128 =
+ new MathContext(34, RoundingMode.HALF_EVEN);
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final MathContext DECIMAL32 =
+ new MathContext(7, RoundingMode.HALF_EVEN);
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final MathContext DECIMAL64 =
+ new MathContext(16, RoundingMode.HALF_EVEN);
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final MathContext UNLIMITED =
+ new MathContext(0, RoundingMode.HALF_UP);
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final long serialVersionUID = 5579720004786848255L;
+
+ final int precision;
+ final RoundingMode roundingMode;
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public MathContext(int requiredPrecision) {
+ this(requiredPrecision, RoundingMode.HALF_UP);
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public MathContext(int requiredPrecision, RoundingMode rm) {
+ if (rm == null) {
+ throw new NullPointerException("null roundingMode");
+ }
+ if (requiredPrecision < 0) {
+ throw new IllegalArgumentException("negative precision");
+ }
+ this.precision = requiredPrecision;
+ this.roundingMode = rm;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public MathContext(String value) {
+ if (!value.startsWith("precision=")) {
+ throw new IllegalArgumentException("the argument should start " +
+ "with \"precision=\"");
+ }
+ int spacePosition = value.indexOf(' ');
+ if (spacePosition == -1) {
+ throw new IllegalArgumentException("the argument's words should " +
+ "be separated by the space");
+ }
+ if (value.lastIndexOf(" ") != spacePosition) {
+ throw new IllegalArgumentException("there should be only one " +
+ "space symbol in the argument");
+ }
+ try {
+ precision = Integer.parseInt(value.substring(10, spacePosition));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("bad precision value");
+ }
+ int shift = spacePosition + 1;
+ int valLen = value.length();
+ if (valLen - shift < 14) {
+ throw new IllegalArgumentException("bad roundingMode value");
+ }
+ if (!value.substring(shift, shift + 13).equals("roundingMode=")) {
+ throw new IllegalArgumentException
+ ("the second word in the argument should " +
+ "be \"roundingMode=<rounding mode>\"");
+ }
+ shift += 13;
+ try {
+ roundingMode = RoundingMode.valueOf(value.substring(shift, valLen));
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("bad roundingMode value");
+ }
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public boolean equals(Object obj) {
+ return (obj instanceof MathContext &&
+ this.precision == ((MathContext)obj).precision &&
+ this.roundingMode.equals(((MathContext)obj).roundingMode));
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public int getPrecision() {
+ return precision;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public RoundingMode getRoundingMode() {
+ return roundingMode;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public int hashCode() {
+ return precision * roundingMode.ordinal() + roundingMode.hashCode();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public String toString() {
+ return "precision=" + precision + " roundingMode=" +
+ roundingMode.toString();
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException,
+ ClassNotFoundException {
+ s.defaultReadObject();
+ if (precision < 0) {
+ throw new StreamCorruptedException("bad precision value");
+ }
+ if (roundingMode == null) {
+ throw new StreamCorruptedException("null roundingMode");
+ }
+ }
+}
+
Added: incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/RoundingMode.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/RoundingMode.java?rev=395476&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/RoundingMode.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/RoundingMode.java Wed Apr 19 21:13:44 2006
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Elena Semukhina
+ * @version $Revision$
+ */
+
+package java.math;
+
+/**
+ * @com.intel.drl.spec_ref
+ */
+public enum RoundingMode {
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ UP(BigDecimal.ROUND_UP),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ DOWN(BigDecimal.ROUND_DOWN),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ CEILING(BigDecimal.ROUND_CEILING),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ FLOOR(BigDecimal.ROUND_FLOOR),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ HALF_UP(BigDecimal.ROUND_HALF_UP),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
+
+ protected final int bigDecimalRM;
+
+ RoundingMode(int rm) {
+ bigDecimalRM = rm;
+ }
+
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ public static RoundingMode valueOf(int rM) {
+ switch(rM) {
+ case BigDecimal.ROUND_CEILING:
+ return CEILING;
+ case BigDecimal.ROUND_DOWN:
+ return DOWN;
+ case BigDecimal.ROUND_FLOOR:
+ return FLOOR;
+ case BigDecimal.ROUND_HALF_DOWN:
+ return HALF_DOWN;
+ case BigDecimal.ROUND_HALF_EVEN:
+ return HALF_EVEN;
+ case BigDecimal.ROUND_HALF_UP:
+ return HALF_UP;
+ case BigDecimal.ROUND_UNNECESSARY:
+ return UNNECESSARY;
+ case BigDecimal.ROUND_UP:
+ return UP;
+ default:
+ throw new IllegalArgumentException("rounding mode out of range");
+ }
+ }
+}