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/18 12:26:02 UTC

svn commit: r394904 [1/2] - in /incubator/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math: BigDecimal.java BigInteger.java

Author: mloenko
Date: Tue Apr 18 03:25:58 2006
New Revision: 394904

URL: http://svn.apache.org/viewcvs?rev=394904&view=rev
Log:
fixes for HARMONY-273
javadoc can be copied from the IBM math implementation to the new Intel math implementation

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

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=394904&r1=394903&r2=394904&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 Tue Apr 18 03:25:58 2006
@@ -1,629 +1,737 @@
-/*
- *  Copyright 2005 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: 1.11.2.3 $
- */
-
-package java.math;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.StreamCorruptedException;
-import java.io.Serializable;
-
-/**
- * @com.intel.drl.spec_ref
- */
-public class BigDecimal extends Number implements Comparable, Serializable {
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    private static final long serialVersionUID = 6108874887143696463L; 
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    private BigInteger intVal;
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    private int scale;
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final BigDecimal ONE = new BigDecimal(BigInteger.ONE, 0);
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final BigDecimal TEN = new BigDecimal(BigInteger.TEN, 0);
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final BigDecimal ZERO = new BigDecimal(BigInteger.ZERO, 0);
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_CEILING = 2;
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_DOWN = 1;
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_FLOOR = 3;
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_HALF_DOWN = 5;
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_HALF_EVEN = 6;
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_HALF_UP = 4;
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_UNNECESSARY = 7;
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static final int ROUND_UP = 0;
-    
-    /**
-     * Verifies if a value overflows a 32-bit integer.
-     * @param longVal long value to be verified.
-     * @param val the name of the value.
-     * @return int longVal.
-     */
-    private static int getValidInt(long longVal, String val) {
-        if (longVal != (int)longVal) {
-            throw new ArithmeticException(val + " outside the range of a 32-bit integer");
-        }
-        return (int)longVal;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static BigDecimal valueOf(long value) {
-        return valueOf(value, 0);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public static BigDecimal valueOf(long unscaledValue, int scale) {
-        return new BigDecimal(BigInteger.valueOf(unscaledValue), scale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal(BigInteger value) {
-        intVal = value;
-        scale = 0;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal(BigInteger unScaledValue, int scale) {
-        intVal = unScaledValue;
-        this.scale = scale;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal(double value) {
-        if (value != value) {
-            throw new NumberFormatException ("argument is NaN");
-        }
-        if (Double.isInfinite(value)) {
-            throw new NumberFormatException ("argument is infinite");
-        }
-        long longValue = Double.doubleToLongBits(value);
-        long significand = longValue & 0x000fffffffffffffL; // mantissa
-        scale = ((int)(longValue >> 52)) & 0x7ff; // exponent
-        if (scale == 0) {
-            scale = 1; // to be calculated correctly in the next operation 
-        } else {
-            significand |= 0x0010000000000000L;
-        }
-        scale -= 1075;
-        // if the scale is negative, strip tailing zeros 
-        // to ensure that the scale is the smallest
-        while ((significand & 1) == 0 && scale < 0) {
-            significand >>= 1;
-            scale++;
-        }
-        intVal = BigInteger.valueOf((longValue & 0x8000000000000000L) == 0 ?
-            significand : -significand);
-        if (scale > 0) {
-            intVal = intVal.shiftLeft(scale);
-            scale = 0;
-        } else {
-            // m * 2 ^ e = m * (10 / 5) ^ e = (m * 5 ^ (-e)) * 10 ^ e
-            intVal = intVal.multiply(BigInteger.valueOf(5L).pow(-scale));
-            scale = -scale;
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal(String value) {
-        int count; // the significand's length
-        int dotPlace = -1;
-        int strLen = value.length();
-        String unscaled;
-        String exponent;
-        char symbol = value.charAt(0);
-        int startPoint = symbol == '+' ? 1 : 0;
-        
-        // parse the significand
-        for (count = 0; count < strLen; count++) {
-            symbol = value.charAt(count);
-            if (symbol == '.') {
-                dotPlace = count;
-            }
-            if (symbol == 'e' || symbol == 'E') {
-                break;
-            }
-        }
-        if (dotPlace == -1) {
-            unscaled = value.substring(startPoint, count);
-            scale = 0;
-        } else {
-            unscaled = value.substring(startPoint, dotPlace) + 
-                value.substring(dotPlace + 1, count);
-            scale = count - dotPlace - 1;
-        }
-        intVal = new BigInteger(unscaled);
-        
-        // parse the exponent
-        if (count < strLen) {
-            if (++count == strLen) {    // skip 'E'
-                throw new NumberFormatException("empty exponent");
-            }
-            symbol = value.charAt(count);
-            if ((symbol == '+' || symbol == '-') && count == strLen - 1) {
-                throw new NumberFormatException("empty exponent");
-            }
-            if (symbol == '+') {
-                count++;
-            }
-            exponent = value.substring(count, strLen);
-            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 abs() {
-        return new BigDecimal(intVal.abs(), this.scale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal add(BigDecimal value) {
-        if (scale == value.scale) {
-            return new BigDecimal(intVal.add(value.intVal), scale);
-        }
-        boolean thisScaleIsLess = this.scale < value.scale;
-        int newScale = thisScaleIsLess ? value.scale : this.scale;
-        if (thisScaleIsLess) {
-            return new BigDecimal(this.intVal.multiply
-                (BigInteger.TEN.pow(value.scale - this.scale)).add(value.intVal), newScale);
-        } else {
-            return new BigDecimal(value.intVal.multiply
-                (BigInteger.TEN.pow(this.scale - value.scale)).add(this.intVal), newScale);
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int compareTo(BigDecimal value) {
-        if (this.scale == value.scale) {
-            return this.intVal.compareTo(value.intVal);
-        }
-        if (this.scale < value.scale) {
-            return this.intVal.multiply(BigInteger.TEN.pow(value.scale - this.scale)).
-                compareTo(value.intVal);
-        } else {
-            return this.intVal.compareTo(value.intVal.multiply
-                (BigInteger.TEN.pow(this.scale - value.scale)));
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int compareTo(Object object) {
-        if (object instanceof BigDecimal) {
-            return (this.compareTo((BigDecimal)object));
-        }
-        throw new ClassCastException("BigDecimals are comparable only with other BigDecimals");
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal divide(BigDecimal value, int roundingMode) {
-        return divide(value, this.scale, roundingMode);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal divide(BigDecimal value, int quotientScale, int roundingMode) {
-        if (roundingMode > 7 || roundingMode < 0) {
-            throw new IllegalArgumentException("invalid rounding mode");
-        }
-        if (value.intVal.signum() == 0) {
-            throw new ArithmeticException("division by zero");
-        }
-        int exponent = quotientScale - this.scale + value.scale; 
-        // If exponent > 0, the dividend should be multiplied by 10**exponent.
-        // If exponent < 0, the divisor should be multiplied by 10**(-exponent).
-        BigInteger dividend = this.intVal;
-        BigInteger divisor = value.intVal;
-        if (exponent < 0) {
-            divisor = divisor.multiply(BigInteger.TEN.pow(-exponent));
-        } else if (exponent > 0) {
-            dividend = dividend.multiply(BigInteger.TEN.pow(exponent));
-        }
-        BigInteger res[] = dividend.divideAndRemainder(divisor);
-        BigInteger quotient = res[0];
-        if (res[1].signum() != 0) {
-            if (roundingMode == ROUND_UNNECESSARY) {
-                throw new ArithmeticException
-                    ("rounding mode is ROUND_UNNECESSARY but the result is not exact");
-            }
-            boolean negativeQuotient = intVal.signum() != divisor.signum();
-            boolean negativeRemainder = res[1].signum() == -1;
-            boolean negativeDivisor = divisor.signum() == -1;
-            if (roundingMode == ROUND_FLOOR) {
-                roundingMode = negativeQuotient ? ROUND_UP : ROUND_DOWN;
-            } else if (roundingMode == ROUND_CEILING) {
-                roundingMode = negativeQuotient ? ROUND_DOWN : ROUND_UP;
-            } else {
-                if (negativeDivisor) {
-                    divisor = divisor.abs();
-                }
-                if (negativeRemainder) {
-                    res[1] = res[1].abs();
-                }
-                // distance == -1 if the quotient is NOT the nearest neighbor to the exact result;
-                // distance == 0 if the exact result is equidistant from the neighbors;
-                // distance == +1 if the quotient is the nearest neighbor to the exact result.
-                int distance = divisor.subtract(res[1]).compareTo(res[1]);
-                if (roundingMode == ROUND_HALF_DOWN) {
-                    roundingMode = distance >= 0 ? ROUND_DOWN : ROUND_UP;
-                } else if (roundingMode == ROUND_HALF_UP) {
-                    roundingMode = distance > 0 ? ROUND_DOWN : ROUND_UP;
-                } else if (roundingMode == ROUND_HALF_EVEN) {
-                    if (distance > 0) {
-                        roundingMode = ROUND_DOWN;
-                    } else if (distance < 0) {
-                        roundingMode = ROUND_UP;
-                    } else if (!quotient.testBit(0)) {
-                        roundingMode = ROUND_DOWN;
-                    } else {
-                        roundingMode = ROUND_UP;
-                    }
-                } 
-            }
-            if (roundingMode == ROUND_UP) { 
-                quotient = quotient.add(BigInteger.valueOf(negativeQuotient ? -1 : 1));
-            }
-        }
-        return new BigDecimal(quotient, quotientScale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public double doubleValue() {
-        return Double.valueOf(toString()).doubleValue();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public boolean equals(Object object) {
-        return (object instanceof BigDecimal &&
-            this.compareTo(object) == 0 && 
-            this.scale == ((BigDecimal)object).scale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public float floatValue() {
-        return Float.valueOf(toString()).floatValue();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int hashCode() {
-        return intVal.intValue() + scale;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int intValue() {
-        return toBigInteger().intValue();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public long longValue() {
-        return toBigInteger().longValue();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal max(BigDecimal value) {
-        return (this.compareTo(value) >= 0 ? this : value);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal min(BigDecimal value) {
-        return (this.compareTo(value) <= 0 ? this : value);
-    }
-
-    /**
-     * Moves the decimal point shift digits
-     * @param shift shift distance
-     */
-    private BigDecimal movePoint(int shift) {
-        int newScale = getValidInt((long)scale + (long)shift, "scale");
-        if (newScale > 0) {
-            return new BigDecimal(intVal, newScale);
-        }
-        return new BigDecimal(this.intVal.multiply(BigInteger.TEN.pow(-newScale)), 0);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal movePointLeft(int shift) {
-        return movePoint(shift);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal movePointRight(int shift) {
-        return movePoint(-shift);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal multiply(BigDecimal value) {
-        return new BigDecimal(this.intVal.multiply(value.intVal), 
-            this.scale + value.scale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal negate() {
-        return new BigDecimal(intVal.negate(), scale);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int scale() {
-        return scale;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal setScale(int newScale) {
-        return setScale(newScale, ROUND_UNNECESSARY);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal setScale(int newScale, int roundingMode) {
-        int delta = this.scale - newScale;
-        if (delta == 0) {
-            return this;
-        }
-        if (delta > 0) {
-            return divide(new BigDecimal(BigInteger.TEN.pow(delta), delta), newScale, roundingMode);
-        } else {
-            return new BigDecimal(intVal.multiply(BigInteger.TEN.pow(-delta)), newScale);
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int signum() {
-        return intVal.signum();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigDecimal subtract(BigDecimal value) {
-        if (scale == value.scale) {
-            return new BigDecimal(intVal.subtract(value.intVal), scale);
-        }
-        boolean thisScaleIsLess = this.scale < value.scale;
-        int newScale = thisScaleIsLess ? value.scale : this.scale;
-        if (thisScaleIsLess) {
-            return new BigDecimal(this.intVal.multiply(BigInteger.TEN.pow(value.scale - this.scale)).
-                subtract(value.intVal), newScale);
-        } else {
-            return new BigDecimal(this.intVal.
-                subtract(value.intVal.multiply(BigInteger.TEN.pow(this.scale - value.scale))), newScale);
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public BigInteger toBigInteger() {
-        if (scale == 0) {
-            return intVal;
-        }
-        if (scale > 0) {
-            return intVal.divide(BigInteger.TEN.pow(scale));
-        }
-        return intVal.multiply(BigInteger.TEN.pow(-scale));
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public String toPlainString() {
-        String intString = intVal.toString();
-        if (scale == 0) {
-            return intString;
-        }
-        boolean negNumber = intVal.signum() < 0;
-        int startPoint = negNumber ? 2 : 1;
-        int endPoint = intString.length();
-        int dotPosition = -scale + intString.length() - (negNumber ? 2 : 1);
-        StringBuffer result = new StringBuffer(intString);
-        char zeros[];
-        if (scale > 0) {
-            if (dotPosition >= 0) {
-                result.insert(dotPosition + (negNumber ? 2 : 1), '.');
-            } else {
-                zeros = new char[-dotPosition + 1];
-                zeros[0] = '0';
-                zeros[1] = '.';
-                for (int i = 2; i < zeros.length; i++) {
-                    zeros[i] = '0';
-                }
-                result.insert(negNumber ? 1 : 0, zeros);
-            }
-        } else {
-            zeros = new char[-scale];
-            for (int i = 0; i < zeros.length; i++) {
-                zeros[i] = '0';
-            }
-            result.insert(endPoint, zeros);
-        }
-        return result.toString();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public String toString() {
-        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();
-        result.append(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 {
-            if (endPoint - startPoint >= 1) {
-                result.insert(startPoint, '.');
-                endPoint++;
-            }
-            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 BigInteger unscaledValue() {
-        return intVal;
-    }
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        if (intVal == null) {
-            throw new StreamCorruptedException("null unscaled value");
-        }
-    }
-}
\ No newline at end of file
+/*
+ *  Copyright 2005 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: 1.11.2.3 $
+ */
+
+package java.math;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.StreamCorruptedException;
+import java.io.Serializable;
+
+/**
+ * BigDecimal objects represent an arbitrary precisioned decimal Number. They
+ * contain values that cannot be changed. Thus, most operations on the
+ * BigDecimal object yield new instances of BigDecimal.
+ * <p>
+ * BigDecimal is respresented by an unscaled BigInteger value and an integer
+ * representing the scale of the object. The scale of the BigDecimal is the
+ * number of digits after the decimal point. Eg. 1.234 would have a scale of 3
+ * and an unscaled value of 1234. Therefore, decimal representation of a
+ * BigDecimal is BigIntegerValue/10^scale.
+ * 
+ * @see java.math.BigInteger
+ */
+public class BigDecimal extends Number implements Comparable, Serializable {
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    private static final long serialVersionUID = 6108874887143696463L; 
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    private BigInteger intVal;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    private int scale;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final BigDecimal ONE = new BigDecimal(BigInteger.ONE, 0);
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final BigDecimal TEN = new BigDecimal(BigInteger.TEN, 0);
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final BigDecimal ZERO = new BigDecimal(BigInteger.ZERO, 0);
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_CEILING = 2;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_DOWN = 1;
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_FLOOR = 3;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_HALF_DOWN = 5;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_HALF_EVEN = 6;
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_HALF_UP = 4;
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_UNNECESSARY = 7;
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static final int ROUND_UP = 0;
+    
+    /**
+     * Verifies if a value overflows a 32-bit integer.
+     * @param longVal long value to be verified.
+     * @param val the name of the value.
+     * @return int longVal.
+     */
+    private static int getValidInt(long longVal, String val) {
+        if (longVal != (int)longVal) {
+            throw new ArithmeticException(val + " outside the range of a 32-bit integer");
+        }
+        return (int)longVal;
+    }
+
+    /**
+     * Translate long value into a BigDecimal with scale of zero.
+     * 
+     * @return BigDecimal BigDecimal equivalence of a long value.
+     */
+    public static BigDecimal valueOf(long value) {
+        return valueOf(value, 0);
+    }
+
+    /**
+     * Translate long unscaled value into a BigDecimal specified by the scale.
+     * 
+     * @return BigDecimal BigDecimal equalvalence of a long value.
+     * @exception NumberFormatException
+     *                the scale value is < 0;
+     */
+    public static BigDecimal valueOf(long unscaledValue, int scale) {
+        return new BigDecimal(BigInteger.valueOf(unscaledValue), scale);
+    }
+
+    /**
+     * Constructs a BigDecimal with unscaled value initialized as value and scale
+     * as 0.
+     */
+    public BigDecimal(BigInteger value) {
+        intVal = value;
+        scale = 0;
+    }
+
+    /**
+     * Constructs a BigDecimal with unscaled value initialized as unScaledValue and scale
+     * as scale from the argument.
+     */
+    public BigDecimal(BigInteger unScaledValue, int scale) {
+        intVal = unScaledValue;
+        this.scale = scale;
+    }
+
+    /**
+     * Constructs a BigDecimal with a double value as an arugment.
+     * 
+     * @exception NumberFormatException
+     *                If the is Infinity, Negative Infinity or NaN.
+     */
+    public BigDecimal(double value) {
+        if (value != value) {
+            throw new NumberFormatException ("argument is NaN");
+        }
+        if (Double.isInfinite(value)) {
+            throw new NumberFormatException ("argument is infinite");
+        }
+        long longValue = Double.doubleToLongBits(value);
+        long significand = longValue & 0x000fffffffffffffL; // mantissa
+        scale = ((int)(longValue >> 52)) & 0x7ff; // exponent
+        if (scale == 0) {
+            scale = 1; // to be calculated correctly in the next operation 
+        } else {
+            significand |= 0x0010000000000000L;
+        }
+        scale -= 1075;
+        // if the scale is negative, strip tailing zeros 
+        // to ensure that the scale is the smallest
+        while ((significand & 1) == 0 && scale < 0) {
+            significand >>= 1;
+            scale++;
+        }
+        intVal = BigInteger.valueOf((longValue & 0x8000000000000000L) == 0 ?
+            significand : -significand);
+        if (scale > 0) {
+            intVal = intVal.shiftLeft(scale);
+            scale = 0;
+        } else {
+            // m * 2 ^ e = m * (10 / 5) ^ e = (m * 5 ^ (-e)) * 10 ^ e
+            intVal = intVal.multiply(BigInteger.valueOf(5L).pow(-scale));
+            scale = -scale;
+        }
+    }
+
+    /**
+     * Constructs a BigDecimal from the string which can only
+     * contain digits of 0-9, a decimal point and a negative sign.
+     * 
+     * @exception NumberFormatException
+     *                If the argument contained characters other than digits.
+     */
+    public BigDecimal(String value) {
+        int count; // the significand's length
+        int dotPlace = -1;
+        int strLen = value.length();
+        String unscaled;
+        String exponent;
+        char symbol = value.charAt(0);
+        int startPoint = symbol == '+' ? 1 : 0;
+        
+        // parse the significand
+        for (count = 0; count < strLen; count++) {
+            symbol = value.charAt(count);
+            if (symbol == '.') {
+                dotPlace = count;
+            }
+            if (symbol == 'e' || symbol == 'E') {
+                break;
+            }
+        }
+        if (dotPlace == -1) {
+            unscaled = value.substring(startPoint, count);
+            scale = 0;
+        } else {
+            unscaled = value.substring(startPoint, dotPlace) + 
+                value.substring(dotPlace + 1, count);
+            scale = count - dotPlace - 1;
+        }
+        intVal = new BigInteger(unscaled);
+        
+        // parse the exponent
+        if (count < strLen) {
+            if (++count == strLen) {    // skip 'E'
+                throw new NumberFormatException("empty exponent");
+            }
+            symbol = value.charAt(count);
+            if ((symbol == '+' || symbol == '-') && count == strLen - 1) {
+                throw new NumberFormatException("empty exponent");
+            }
+            if (symbol == '+') {
+                count++;
+            }
+            exponent = value.substring(count, strLen);
+            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;
+        }
+    }
+
+    /**
+     * Answers the absolute value of this BigDecimal.
+     * 
+     * @return BigDecimal absolute value of the receiver.
+     */
+    public BigDecimal abs() {
+        return new BigDecimal(intVal.abs(), this.scale);
+    }
+
+    /**
+     * Answers the sum of the receiver and argument.
+     * 
+     * @return BigDecimal The sum of adding two BigDecimal.
+     */
+    public BigDecimal add(BigDecimal value) {
+        if (scale == value.scale) {
+            return new BigDecimal(intVal.add(value.intVal), scale);
+        }
+        boolean thisScaleIsLess = this.scale < value.scale;
+        int newScale = thisScaleIsLess ? value.scale : this.scale;
+        if (thisScaleIsLess) {
+            return new BigDecimal(this.intVal.multiply
+                (BigInteger.TEN.pow(value.scale - this.scale)).add(value.intVal), newScale);
+        } else {
+            return new BigDecimal(value.intVal.multiply
+                (BigInteger.TEN.pow(this.scale - value.scale)).add(this.intVal), newScale);
+        }
+    }
+
+    /**
+     * Compares the receiver BigDecimal and argument BigDecimal e.x 1.00 & 1.0
+     * will return 0 in compareTo.
+     * 
+     * @return int 0 - equal; 1 - this > value; -1 - this < value.
+     */
+    public int compareTo(BigDecimal value) {
+        if (this.scale == value.scale) {
+            return this.intVal.compareTo(value.intVal);
+        }
+        if (this.scale < value.scale) {
+            return this.intVal.multiply(BigInteger.TEN.pow(value.scale - this.scale)).
+                compareTo(value.intVal);
+        } else {
+            return this.intVal.compareTo(value.intVal.multiply
+                (BigInteger.TEN.pow(this.scale - value.scale)));
+        }
+    }
+
+    /**
+     * 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
+     */
+    public int compareTo(Object object) {
+        if (object instanceof BigDecimal) {
+            return (this.compareTo((BigDecimal)object));
+        }
+        throw new ClassCastException("BigDecimals are comparable only with other BigDecimals");
+    }
+
+    /**
+     * Answers the result of (this / value).
+     * 
+     * @return BigDecimal result of this/value.
+     */
+    public BigDecimal divide(BigDecimal value, int roundingMode) {
+        return divide(value, this.scale, roundingMode);
+    }
+
+    /**
+     * Answers the result of (this / value) and whose scale is specified.
+     * 
+     * @return BigDecimal result of this/value.
+     * @exception ArithmeticException
+     *                division by zero.
+     * @exception IllegalArgumentException
+     *                roundingMode is not valid.
+     */
+    public BigDecimal divide(BigDecimal value, int quotientScale, int roundingMode) {
+        if (roundingMode > 7 || roundingMode < 0) {
+            throw new IllegalArgumentException("invalid rounding mode");
+        }
+        if (value.intVal.signum() == 0) {
+            throw new ArithmeticException("division by zero");
+        }
+        int exponent = quotientScale - this.scale + value.scale; 
+        // If exponent > 0, the dividend should be multiplied by 10**exponent.
+        // If exponent < 0, the divisor should be multiplied by 10**(-exponent).
+        BigInteger dividend = this.intVal;
+        BigInteger divisor = value.intVal;
+        if (exponent < 0) {
+            divisor = divisor.multiply(BigInteger.TEN.pow(-exponent));
+        } else if (exponent > 0) {
+            dividend = dividend.multiply(BigInteger.TEN.pow(exponent));
+        }
+        BigInteger res[] = dividend.divideAndRemainder(divisor);
+        BigInteger quotient = res[0];
+        if (res[1].signum() != 0) {
+            if (roundingMode == ROUND_UNNECESSARY) {
+                throw new ArithmeticException
+                    ("rounding mode is ROUND_UNNECESSARY but the result is not exact");
+            }
+            boolean negativeQuotient = intVal.signum() != divisor.signum();
+            boolean negativeRemainder = res[1].signum() == -1;
+            boolean negativeDivisor = divisor.signum() == -1;
+            if (roundingMode == ROUND_FLOOR) {
+                roundingMode = negativeQuotient ? ROUND_UP : ROUND_DOWN;
+            } else if (roundingMode == ROUND_CEILING) {
+                roundingMode = negativeQuotient ? ROUND_DOWN : ROUND_UP;
+            } else {
+                if (negativeDivisor) {
+                    divisor = divisor.abs();
+                }
+                if (negativeRemainder) {
+                    res[1] = res[1].abs();
+                }
+                // distance == -1 if the quotient is NOT the nearest neighbor to the exact result;
+                // distance == 0 if the exact result is equidistant from the neighbors;
+                // distance == +1 if the quotient is the nearest neighbor to the exact result.
+                int distance = divisor.subtract(res[1]).compareTo(res[1]);
+                if (roundingMode == ROUND_HALF_DOWN) {
+                    roundingMode = distance >= 0 ? ROUND_DOWN : ROUND_UP;
+                } else if (roundingMode == ROUND_HALF_UP) {
+                    roundingMode = distance > 0 ? ROUND_DOWN : ROUND_UP;
+                } else if (roundingMode == ROUND_HALF_EVEN) {
+                    if (distance > 0) {
+                        roundingMode = ROUND_DOWN;
+                    } else if (distance < 0) {
+                        roundingMode = ROUND_UP;
+                    } else if (!quotient.testBit(0)) {
+                        roundingMode = ROUND_DOWN;
+                    } else {
+                        roundingMode = ROUND_UP;
+                    }
+                } 
+            }
+            if (roundingMode == ROUND_UP) { 
+                quotient = quotient.add(BigInteger.valueOf(negativeQuotient ? -1 : 1));
+            }
+        }
+        return new BigDecimal(quotient, quotientScale);
+    }
+
+    /**
+     * 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.
+     * 
+     * @return double the value of the receiver.
+     */
+    public double doubleValue() {
+        return Double.valueOf(toString()).doubleValue();
+    }
+
+    /**
+     * Compares the argument to the receiver, and answers true if they represent
+     * the <em>same</em> object using a class specific comparison. The
+     * implementation in Object answers true only if the argument is the exact
+     * same object as the receiver (==).
+     * 
+     * @param o
+     *            Object the object to compare with this object.
+     * @return boolean <code>true</code> if the object is the same as this
+     *         object <code>false</code> if it is different from this object.
+     * @see hashCode
+     */
+    public boolean equals(Object object) {
+        return (object instanceof BigDecimal &&
+            this.compareTo(object) == 0 && 
+            this.scale == ((BigDecimal)object).scale);
+    }
+
+    /**
+     * Converts this BigDecimal to a float.If magnitude of the BigDecimal value
+     * is larger than what can be represented by a float, either Infinity or
+     * -Infinity is returned.
+     * 
+     * @return float the value of the receiver.
+     */
+    public float floatValue() {
+        return Float.valueOf(toString()).floatValue();
+    }
+
+    /**
+     * Answers an integer hash code for the receiver. Any two objects which
+     * answer <code>true</code> when passed to <code>.equals</code> must
+     * answer the same value for this method.
+     * 
+     * @return int the receiver's hash.
+     * 
+     * @see #equals(Object)
+     */
+    public int hashCode() {
+        return intVal.intValue() + scale;
+    }
+
+    /**
+     * Converts this BigDecimal to an int.
+     * 
+     * @return int the value of the receiver.
+     */
+    public int intValue() {
+        return toBigInteger().intValue();
+    }
+
+    /**
+     * Converts this BigDecimal to a long.
+     * 
+     * @return long long representation of the receiver.
+     */
+    public long longValue() {
+        return toBigInteger().longValue();
+    }
+
+    /**
+     * Answers the max value between the receiver and this BigDecimal.
+     * 
+     * @return BigDecimal max BigDecimal.
+     */
+    public BigDecimal max(BigDecimal value) {
+        return (this.compareTo(value) >= 0 ? this : value);
+    }
+
+    /**
+     * Answers the min value between the receiver and argument.
+     * 
+     * @return BigDecimal min BigDecimal.
+     */
+    public BigDecimal min(BigDecimal value) {
+        return (this.compareTo(value) <= 0 ? this : value);
+    }
+
+    /**
+     * Moves the decimal point shift digits
+     * @param shift shift distance
+     */
+    private BigDecimal movePoint(int shift) {
+        int newScale = getValidInt((long)scale + (long)shift, "scale");
+        if (newScale > 0) {
+            return new BigDecimal(intVal, newScale);
+        }
+        return new BigDecimal(this.intVal.multiply(BigInteger.TEN.pow(-newScale)), 0);
+    }
+
+    /**
+     * Moves the decimal point of this BigDecimal n places to the left.
+     * 
+     * @return BigDecimal new BigDecimal with decimal moved n places to the
+     *         left.
+     */
+    public BigDecimal movePointLeft(int shift) {
+        return movePoint(shift);
+    }
+
+    /**
+     * Moves the decimal point of this BigDecimal n places to the right.
+     * 
+     * @return BigDecimal new BigDecimal with decimal moved n places to the
+     *         right.
+     */
+    public BigDecimal movePointRight(int shift) {
+        return movePoint(-shift);
+    }
+
+    /**
+     * Answers the multiplication result of the receiver and argument.
+     * 
+     * @return BigDecimal result of multiplying two bigDecimals.
+     */
+    public BigDecimal multiply(BigDecimal value) {
+        return new BigDecimal(this.intVal.multiply(value.intVal), 
+            this.scale + value.scale);
+    }
+
+    /**
+     * Negates this BigDecimal value.
+     * 
+     * @return BigDecimal new BigDecimal with value negated.
+     */
+    public BigDecimal negate() {
+        return new BigDecimal(intVal.negate(), scale);
+    }
+
+    /**
+     * Returns the scale of this BigDecimal.
+     * 
+     * @return int scale value.
+     */
+    public int scale() {
+        return scale;
+    }
+
+    /**
+     * Sets the scale of this BigDecimal.
+     * 
+     * @return BigDecimal a BigDecimal with the same value, but specified scale.
+     */
+    public BigDecimal setScale(int newScale) {
+        return setScale(newScale, ROUND_UNNECESSARY);
+    }
+
+    /**
+     * Sets the scale of this BigDecimal. The unscaled value is determined by
+     * the rounding Mode
+     * 
+     * @return BigDecimal a BigDecimal with the same value, but specified cale.
+     * @exception ArithmeticException
+     *                rounding mode must be specified if lose of precision due
+     *                to setting scale.
+     * @exception IllegalArgumentException
+     *                invalid rounding mode
+     */
+    public BigDecimal setScale(int newScale, int roundingMode) {
+        int delta = this.scale - newScale;
+        if (delta == 0) {
+            return this;
+        }
+        if (delta > 0) {
+            return divide(new BigDecimal(BigInteger.TEN.pow(delta), delta), newScale, roundingMode);
+        } else {
+            return new BigDecimal(intVal.multiply(BigInteger.TEN.pow(-delta)), newScale);
+        }
+    }
+
+    /**
+     * Answers the signum function of this instance.
+     * 
+     * @return int -1, 0, or 1 if the receiver is negative, zero, or positive.
+     */
+    public int signum() {
+        return intVal.signum();
+    }
+
+    /**
+     * Answers the subtract result of the receiver and argument.
+     * 
+     * @return BigDecimal The result of subtracting the BigDecimal argument.
+     */
+    public BigDecimal subtract(BigDecimal value) {
+        if (scale == value.scale) {
+            return new BigDecimal(intVal.subtract(value.intVal), scale);
+        }
+        boolean thisScaleIsLess = this.scale < value.scale;
+        int newScale = thisScaleIsLess ? value.scale : this.scale;
+        if (thisScaleIsLess) {
+            return new BigDecimal(this.intVal.multiply(BigInteger.TEN.pow(value.scale - this.scale)).
+                subtract(value.intVal), newScale);
+        } else {
+            return new BigDecimal(this.intVal.
+                subtract(value.intVal.multiply(BigInteger.TEN.pow(this.scale - value.scale))), newScale);
+        }
+    }
+
+    /**
+     * Converts this to a BigInteger.
+     * 
+     * @return BigInteger BigDecimal equivalent of BigInteger.
+     */
+    public BigInteger toBigInteger() {
+        if (scale == 0) {
+            return intVal;
+        }
+        if (scale > 0) {
+            return intVal.divide(BigInteger.TEN.pow(scale));
+        }
+        return intVal.multiply(BigInteger.TEN.pow(-scale));
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String toPlainString() {
+        String intString = intVal.toString();
+        if (scale == 0) {
+            return intString;
+        }
+        boolean negNumber = intVal.signum() < 0;
+        int startPoint = negNumber ? 2 : 1;
+        int endPoint = intString.length();
+        int dotPosition = -scale + intString.length() - (negNumber ? 2 : 1);
+        StringBuffer result = new StringBuffer(intString);
+        char zeros[];
+        if (scale > 0) {
+            if (dotPosition >= 0) {
+                result.insert(dotPosition + (negNumber ? 2 : 1), '.');
+            } else {
+                zeros = new char[-dotPosition + 1];
+                zeros[0] = '0';
+                zeros[1] = '.';
+                for (int i = 2; i < zeros.length; i++) {
+                    zeros[i] = '0';
+                }
+                result.insert(negNumber ? 1 : 0, zeros);
+            }
+        } else {
+            zeros = new char[-scale];
+            for (int i = 0; i < zeros.length; i++) {
+                zeros[i] = '0';
+            }
+            result.insert(endPoint, zeros);
+        }
+        return result.toString();
+    }
+
+    /**
+     * Answers a string containing a concise, human-readable description of the
+     * receiver.
+     * 
+     * @return String a printable representation for the receiver.
+     */
+    public String toString() {
+        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();
+        result.append(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 {
+            if (endPoint - startPoint >= 1) {
+                result.insert(startPoint, '.');
+                endPoint++;
+            }
+            result.insert(endPoint, 'E');
+            if (exponent > 0) {
+                result.insert(++endPoint, '+');
+            }
+            result.insert(++endPoint, Integer.toString(exponent));
+        }
+        return result.toString();
+    }
+
+    /**
+     * Returns an unscaled value of this BigDecimal.
+     * 
+     * @return BigInteger The unscaled value.
+     */
+    public BigInteger unscaledValue() {
+        return intVal;
+    }
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        if (intVal == null) {
+            throw new StreamCorruptedException("null unscaled value");
+        }
+    }
+}