This is the mail archive of the
java-patches@sources.redhat.com
mailing list for the Java project.
PATCH: BigDecimal - libgcj/1596: setScale() missing from BigDecimal
- To: Java Patch List <java-patches at sources dot redhat dot com>
- Subject: PATCH: BigDecimal - libgcj/1596: setScale() missing from BigDecimal
- From: Warren Levy <warrenl at redhat dot com>
- Date: Wed, 10 Jan 2001 01:44:13 -0800 (PST)
- cc: jeff dot sturm at commerceone dot com
Folks,
Here's a patch for libgcj/1596. In fixing it a couple other bugs turned
up (in BigDecimal.divide). Turns out the newScale arg to the divide
method wasn't properly checked for validity; and small newScale values
for BigDecimal.divide sometimes caused an IllegalArgumentException
because they caused a BigInteger.pow() with a negative value to be
attempted. I took care of both of them and I'm checking in a test case to
Mauve for this.
Here's the patch I've checked in (to Classpath also).
--warrenl
2001-01-10 Warren Levy <warrenl@redhat.com>
Fix for PR libgcj/1596:
* java/math/BigDecimal.java (divide): Check newScale for validity.
Ensure that BigInteger.pow() is called with a non-negative value.
(setScale (int)): New public method.
(setScale (int,int)): New public method.
Index: BigDecimal.java
===================================================================
RCS file: /cvs/gcc/egcs/libjava/java/math/BigDecimal.java,v
retrieving revision 1.2
diff -u -p -r1.2 BigDecimal.java
--- BigDecimal.java 2000/10/27 10:33:46 1.2
+++ BigDecimal.java 2001/01/10 09:28:36
@@ -1,5 +1,5 @@
/* java.math.BigDecimal -- Arbitrary precision decimals.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -133,16 +133,27 @@ public class BigDecimal extends Number i
throw
new IllegalArgumentException("illegal rounding mode: " + roundingMode);
- if (scale < 0)
- throw new ArithmeticException ("scale is negative: " + scale);
+ if (newScale < 0)
+ throw new ArithmeticException ("scale is negative: " + newScale);
if (intVal.signum () == 0) // handle special case of 0.0/0.0
return ZERO;
- BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow
- (newScale + 1 - (scale - val.scale)));
+ // Ensure that pow gets a non-negative value.
+ int valScale = val.scale;
+ BigInteger valIntVal = val.intVal;
+ int power = newScale + 1 - (scale - val.scale);
+ if (power < 0)
+ {
+ // Effectively increase the scale of val to avoid an
+ // IllegalArgumentException for a negative power.
+ valIntVal = valIntVal.multiply (BigInteger.valueOf (10).pow (-power));
+ power = 0;
+ }
+
+ BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power));
- BigInteger parts[] = dividend.divideAndRemainder (val.intVal);
+ BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
// System.out.println("int: " + parts[0]);
// System.out.println("rem: " + parts[1]);
@@ -346,5 +357,16 @@ public class BigDecimal extends Number i
public double doubleValue()
{
return Double.valueOf(toString()).doubleValue();
+ }
+
+ public BigDecimal setScale (int scale) throws ArithmeticException
+ {
+ return setScale (scale, ROUND_UNNECESSARY);
+ }
+
+ public BigDecimal setScale (int scale, int roundingMode)
+ throws ArithmeticException, IllegalArgumentException
+ {
+ return divide (ONE, scale, roundingMode);
}
}