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