This is the mail archive of the java-patches@sources.redhat.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: BigDecimal - libgcj/1596: setScale() missing from BigDecimal


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);
   }
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]