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