I tested the rounding methods and made a fix to the round() method.
Satisfied with this I implemented several constructors that required
rounding facilities and the abs(MathContext) method that also required
rounding.

2006-02-24  Anthony Balkissoon  <[EMAIL PROTECTED]>

        * java/math/BigDecimal.java:
        (BigDecimal(long, MathContext)): New constructor.
        (BigDecimal(BigInteger, MathContext)): Likewise.
        (BigDecimal(String, MathContext)): Likewise.
        (BigDecimal(double, MathContext)): Likewise.
        (round): Fixed a typo where the precision field was used instead of a
        call to the precision method, and also store the new precision in the
        returned BigDecimal.
        (abs(MathContext)): New method.

--Tony
Index: java/math/BigDecimal.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v
retrieving revision 1.17.2.10
diff -u -r1.17.2.10 BigDecimal.java
--- java/math/BigDecimal.java	24 Feb 2006 19:44:30 -0000	1.17.2.10
+++ java/math/BigDecimal.java	24 Feb 2006 21:45:04 -0000
@@ -99,6 +99,66 @@
   }
   
   /**
+   * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
+   * and then rounds according to the MathContext.
+   * @param val the long from which we create the initial BigDecimal
+   * @param mc the MathContext that specifies the rounding behaviour
+   * @since 1.5
+   */
+  public BigDecimal (long val, MathContext mc)
+  {
+    this(val);
+    if (mc.getPrecision() != 0)
+      {
+        BigDecimal result = this.round(mc);
+        this.intVal = result.intVal;
+        this.scale = result.scale;
+        this.precision = result.precision;
+      }    
+  }
+  
+  /**
+   * Constructs a BigDecimal whose value is given by num rounded according to 
+   * mc.  Since num is already a BigInteger, the rounding refers only to the 
+   * precision setting in mc, if mc.getPrecision() returns an int lower than
+   * the number of digits in num, then rounding is necessary.
+   * @param num the unscaledValue, before rounding
+   * @param mc the MathContext that specifies the precision
+   * @since 1.5
+   */
+  public BigDecimal (BigInteger num, MathContext mc)
+  {
+    this (num, 0);
+    if (mc.getPrecision() != 0)
+      {
+        BigDecimal result = this.round(mc);
+        this.intVal = result.intVal;
+        this.scale = result.scale;
+        this.precision = result.precision;
+      }
+  }
+  
+  /**
+   * Constructs a BigDecimal from the String val according to the same
+   * rules as the BigDecimal(String) constructor and then rounds 
+   * according to the MathContext mc.
+   * @param val the String from which we construct the initial BigDecimal
+   * @param mc the MathContext that specifies the rounding
+   * @since 1.5
+   */
+  public BigDecimal (String val, MathContext mc)
+  {
+    this (val);
+    if (mc.getPrecision() != 0)
+      {
+        BigDecimal result = this.round(mc);
+        this.intVal = result.intVal;
+        this.scale = result.scale;
+        this.precision = result.precision;
+      }
+  }
+  
+  /**
    * Constructs a BigDecimal whose unscaled value is num and whose
    * scale is zero.
    * @param num the value of the new BigDecimal
@@ -120,6 +180,25 @@
     this.scale = scale;
   }
 
+  /**
+   * Constructs a BigDecimal in the same way as BigDecimal(double) and then
+   * rounds according to the MathContext.
+   * @param num the double from which the initial BigDecimal is created
+   * @param mc the MathContext that specifies the rounding behaviour
+   * @since 1.5
+   */
+  public BigDecimal (double num, MathContext mc)
+  {
+    this (num);
+    if (mc.getPrecision() != 0)
+      {
+        BigDecimal result = this.round(mc);
+        this.intVal = result.intVal;
+        this.scale = result.scale;
+        this.precision = result.precision;
+      }
+  }
+  
   public BigDecimal (double num) throws NumberFormatException 
   {
     if (Double.isInfinite (num) || Double.isNaN (num))
@@ -703,7 +782,7 @@
   public BigDecimal round(MathContext mc)
   {
     int mcPrecision = mc.getPrecision();
-    int numToChop = precision - mcPrecision;
+    int numToChop = precision() - mcPrecision;
     // If mc specifies not to chop any digits or if we've already chopped 
     // enough digits (say by using a MathContext in the constructor for this
     // BigDecimal) then just return this.
@@ -716,6 +795,7 @@
       new BigDecimal(BigInteger.valueOf((long)Math.pow(10, numToChop)));
     BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
     rounded.scale -= numToChop;
+    rounded.precision = mcPrecision;
     return rounded;
   }
   
@@ -1161,5 +1241,16 @@
     return result;
   }
   
-
+  /**
+   * Returns a BigDecimal whose value is the absolute value of this BigDecimal
+   * with rounding according to the given MathContext.
+   * @param mc the MathContext
+   * @return the new BigDecimal
+   */
+  public BigDecimal abs(MathContext mc)
+  {
+    BigDecimal result = abs();
+    result = result.round(mc);
+    return result;
+  }
 }

Reply via email to