Fixed a problem with toBigInteger, it was crashing when the scale was negative. Also wrote the new methods toBigIntegerExact and stripTrailingZeros.
2006-02-24 Anthony Balkissoon <[EMAIL PROTECTED]> * java/math/BigDecimal.java (toBigInteger): Fixed problem where this method couldn't handle negative values for scale. (toBigIntegerExact): New method. (stripTrailingZeros): Likewise. --Tony
Index: java/math/BigDecimal.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.9 diff -u -r1.17.2.9 BigDecimal.java --- java/math/BigDecimal.java 23 Feb 2006 22:39:04 -0000 1.17.2.9 +++ java/math/BigDecimal.java 24 Feb 2006 19:43:16 -0000 @@ -1017,16 +1017,78 @@ return sb.toString(); } + /** + * Converts this BigDecimal to a BigInteger. Any fractional part will + * be discarded. + * @return a BigDecimal whose value is equal to floor[this] + */ public BigInteger toBigInteger () { - return scale == 0 ? intVal : - intVal.divide (BigInteger.valueOf (10).pow (scale)); + // If scale > 0 then we must divide, if scale > 0 then we must multiply, + // and if scale is zero then we just return intVal; + if (scale > 0) + return intVal.divide (BigInteger.valueOf (10).pow (scale)); + else if (scale < 0) + return intVal.multiply(BigInteger.valueOf(10).pow(-scale)); + return intVal; + } + + /** + * Converts this BigDecimal into a BigInteger, throwing an + * ArithmeticException if the conversion is not exact. + * @return a BigInteger whose value is equal to the value of this BigDecimal + * @since 1.5 + */ + public BigInteger toBigIntegerExact() + { + if (scale > 0) + { + // If we have to divide, we must check if the result is exact. + BigInteger[] result = + intVal.divideAndRemainder(BigInteger.valueOf(10).pow(scale)); + if (result[1].equals(BigInteger.ZERO)) + return result[0]; + throw new ArithmeticException("No exact BigInteger representation"); + } + else if (scale < 0) + // If we're multiplying instead, then we needn't check for exactness. + return intVal.multiply(BigInteger.valueOf(10).pow(-scale)); + // If the scale is zero we can simply return intVal. + return intVal; } public int intValue () { return toBigInteger ().intValue (); } + + /** + * Returns a BigDecimal which is numerically equal to this BigDecimal but + * with no trailing zeros in the representation. For example, if this + * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns + * a BigDecimal with [unscaledValue, scale] = [6313, 1]. As another + * example, [12400, -2] would become [124, -4]. + * @return a numerically equal BigDecimal with no trailing zeros + */ + public BigDecimal stripTrailingZeros() + { + String intValStr = intVal.toString(); + int newScale = scale; + int pointer = intValStr.length() - 1; + // This loop adjusts pointer which will be used to give us the substring + // of intValStr to use in our new BigDecimal, and also accordingly + // adjusts the scale of our new BigDecimal. + while (intValStr.charAt(pointer) == '0') + { + pointer --; + newScale --; + } + // Create a new BigDecimal with the appropriate substring and then + // set its scale. + BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1)); + result.scale = newScale; + return result; + } public long longValue () {