From 946ac52dd6081077b0e3c6d9245238826abd2891 Mon Sep 17 00:00:00 2001 From: sherman Date: Thu, 22 Jan 2009 20:29:54 -0800 Subject: [PATCH] 6476425: (fmt)java.util.Formatter.print() throws IllegalArgumentException on large BigDecima Summary: Correct the wrong calculation of "precision" in certain circumstances. Reviewed-by: darcy, alanb --- src/share/classes/java/util/Formatter.java | 27 +++++++---- test/java/util/Formatter/Basic-X.java | 46 +++++++++++++++++++ test/java/util/Formatter/Basic.java | 2 +- test/java/util/Formatter/BasicBigDecimal.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicBigInteger.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicBoolean.java | 46 +++++++++++++++++++ .../util/Formatter/BasicBooleanObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicByte.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicByteObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicChar.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicCharObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicDateTime.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicDouble.java | 46 +++++++++++++++++++ .../util/Formatter/BasicDoubleObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicFloat.java | 46 +++++++++++++++++++ .../java/util/Formatter/BasicFloatObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicInt.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicIntObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicLong.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicLongObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/BasicShort.java | 46 +++++++++++++++++++ .../java/util/Formatter/BasicShortObject.java | 46 +++++++++++++++++++ test/java/util/Formatter/genBasic.sh | 6 ++- 23 files changed, 943 insertions(+), 12 deletions(-) diff --git a/src/share/classes/java/util/Formatter.java b/src/share/classes/java/util/Formatter.java index ad4dca1d3..5100adbd2 100644 --- a/src/share/classes/java/util/Formatter.java +++ b/src/share/classes/java/util/Formatter.java @@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; +import java.math.RoundingMode; import java.nio.charset.Charset; import java.text.DateFormatSymbols; import java.text.DecimalFormat; @@ -1252,7 +1253,7 @@ import sun.misc.FormattedFloatingDecimal; * Double#toString(double)} respectively, then the value will be rounded * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up * algorithm}. Otherwise, zeros may be appended to reach the precision. - * For a canonical representation of the value,use {@link + * For a canonical representation of the value, use {@link * Float#toString(float)} or {@link Double#toString(double)} as * appropriate. * @@ -3569,15 +3570,23 @@ public final class Formatter implements Closeable, Flushable { // Create a new BigDecimal with the desired precision. int prec = (precision == -1 ? 6 : precision); int scale = value.scale(); - int compPrec = value.precision(); - if (scale > prec) - compPrec -= (scale - prec); - MathContext mc = new MathContext(compPrec); - BigDecimal v - = new BigDecimal(value.unscaledValue(), scale, mc); - BigDecimalLayout bdl - = new BigDecimalLayout(v.unscaledValue(), v.scale(), + if (scale > prec) { + // more "scale" digits than the requested "precision + int compPrec = value.precision(); + if (compPrec <= scale) { + // case of 0.xxxxxx + value = value.setScale(prec, RoundingMode.HALF_UP); + } else { + compPrec -= (scale - prec); + value = new BigDecimal(value.unscaledValue(), + scale, + new MathContext(compPrec)); + } + } + BigDecimalLayout bdl = new BigDecimalLayout( + value.unscaledValue(), + value.scale(), BigDecimalLayoutForm.DECIMAL_FLOAT); char mant[] = bdl.mantissa(); diff --git a/test/java/util/Formatter/Basic-X.java b/test/java/util/Formatter/Basic-X.java index b4a603f7b..4677062cc 100644 --- a/test/java/util/Formatter/Basic-X.java +++ b/test/java/util/Formatter/Basic-X.java @@ -1054,6 +1054,52 @@ public class Basic$Type$ extends Basic { test("%4.1f", " 1.0", val); test("%4.2f", "0.99", val); test("%4.3f", "0.990", val); + + // #6476425 + val = new BigDecimal("0.00001"); + test("%.0f", "0", val); + test("%.1f", "0.0", val); + test("%.2f", "0.00", val); + test("%.3f", "0.000", val); + test("%.4f", "0.0000", val); + test("%.5f", "0.00001", val); + + val = new BigDecimal("1.00001"); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "1.0000", val); + test("%.5f", "1.00001", val); + + val = new BigDecimal("1.23456"); + test("%.0f", "1", val); + test("%.1f", "1.2", val); + test("%.2f", "1.23", val); + test("%.3f", "1.235", val); + test("%.4f", "1.2346", val); + test("%.5f", "1.23456", val); + test("%.6f", "1.234560", val); + + val = new BigDecimal("9.99999"); + test("%.0f", "10", val); + test("%.1f", "10.0", val); + test("%.2f", "10.00", val); + test("%.3f", "10.000", val); + test("%.4f", "10.0000", val); + test("%.5f", "9.99999", val); + test("%.6f", "9.999990", val); + + + val = new BigDecimal("1.99999"); + test("%.0f", "2", val); + test("%.1f", "2.0", val); + test("%.2f", "2.00", val); + test("%.3f", "2.000", val); + test("%.4f", "2.0000", val); + test("%.5f", "1.99999", val); + test("%.6f", "1.999990", val); + #end[BigDecimal] #if[float] diff --git a/test/java/util/Formatter/Basic.java b/test/java/util/Formatter/Basic.java index 22d92495d..3a957b2f4 100644 --- a/test/java/util/Formatter/Basic.java +++ b/test/java/util/Formatter/Basic.java @@ -25,7 +25,7 @@ * @summary Unit test for formatter * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 - * 6344623 6369500 6534606 6282094 6286592 + * 6344623 6369500 6534606 6282094 6286592 6476425 * * @run shell/timeout=240 Basic.sh */ diff --git a/test/java/util/Formatter/BasicBigDecimal.java b/test/java/util/Formatter/BasicBigDecimal.java index d35da2565..da9639138 100644 --- a/test/java/util/Formatter/BasicBigDecimal.java +++ b/test/java/util/Formatter/BasicBigDecimal.java @@ -1055,6 +1055,52 @@ public class BasicBigDecimal extends Basic { test("%4.2f", "0.99", val); test("%4.3f", "0.990", val); + // #6476425 + val = new BigDecimal("0.00001"); + test("%.0f", "0", val); + test("%.1f", "0.0", val); + test("%.2f", "0.00", val); + test("%.3f", "0.000", val); + test("%.4f", "0.0000", val); + test("%.5f", "0.00001", val); + + val = new BigDecimal("1.00001"); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "1.0000", val); + test("%.5f", "1.00001", val); + + val = new BigDecimal("1.23456"); + test("%.0f", "1", val); + test("%.1f", "1.2", val); + test("%.2f", "1.23", val); + test("%.3f", "1.235", val); + test("%.4f", "1.2346", val); + test("%.5f", "1.23456", val); + test("%.6f", "1.234560", val); + + val = new BigDecimal("9.99999"); + test("%.0f", "10", val); + test("%.1f", "10.0", val); + test("%.2f", "10.00", val); + test("%.3f", "10.000", val); + test("%.4f", "10.0000", val); + test("%.5f", "9.99999", val); + test("%.6f", "9.999990", val); + + + val = new BigDecimal("1.99999"); + test("%.0f", "2", val); + test("%.1f", "2.0", val); + test("%.2f", "2.00", val); + test("%.3f", "2.000", val); + test("%.4f", "2.0000", val); + test("%.5f", "1.99999", val); + test("%.6f", "1.999990", val); + + diff --git a/test/java/util/Formatter/BasicBigInteger.java b/test/java/util/Formatter/BasicBigInteger.java index e93f60d39..4bba5a0fb 100644 --- a/test/java/util/Formatter/BasicBigInteger.java +++ b/test/java/util/Formatter/BasicBigInteger.java @@ -1503,6 +1503,52 @@ public class BasicBigInteger extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicBoolean.java b/test/java/util/Formatter/BasicBoolean.java index c7af21083..ea60e3886 100644 --- a/test/java/util/Formatter/BasicBoolean.java +++ b/test/java/util/Formatter/BasicBoolean.java @@ -1503,6 +1503,52 @@ public class BasicBoolean extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicBooleanObject.java b/test/java/util/Formatter/BasicBooleanObject.java index 81c1f3e1a..b4fbabb76 100644 --- a/test/java/util/Formatter/BasicBooleanObject.java +++ b/test/java/util/Formatter/BasicBooleanObject.java @@ -1503,6 +1503,52 @@ public class BasicBooleanObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicByte.java b/test/java/util/Formatter/BasicByte.java index ff44286fd..deaf37957 100644 --- a/test/java/util/Formatter/BasicByte.java +++ b/test/java/util/Formatter/BasicByte.java @@ -1503,6 +1503,52 @@ public class BasicByte extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicByteObject.java b/test/java/util/Formatter/BasicByteObject.java index e2b158c3e..06eb68ebd 100644 --- a/test/java/util/Formatter/BasicByteObject.java +++ b/test/java/util/Formatter/BasicByteObject.java @@ -1503,6 +1503,52 @@ public class BasicByteObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicChar.java b/test/java/util/Formatter/BasicChar.java index bb1b5037e..5ada7b166 100644 --- a/test/java/util/Formatter/BasicChar.java +++ b/test/java/util/Formatter/BasicChar.java @@ -1503,6 +1503,52 @@ public class BasicChar extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicCharObject.java b/test/java/util/Formatter/BasicCharObject.java index 2d15fa1c5..1e7d05d54 100644 --- a/test/java/util/Formatter/BasicCharObject.java +++ b/test/java/util/Formatter/BasicCharObject.java @@ -1503,6 +1503,52 @@ public class BasicCharObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicDateTime.java b/test/java/util/Formatter/BasicDateTime.java index 97ae65026..fd42da06f 100644 --- a/test/java/util/Formatter/BasicDateTime.java +++ b/test/java/util/Formatter/BasicDateTime.java @@ -1503,6 +1503,52 @@ public class BasicDateTime extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicDouble.java b/test/java/util/Formatter/BasicDouble.java index abbd093fc..d985b46b1 100644 --- a/test/java/util/Formatter/BasicDouble.java +++ b/test/java/util/Formatter/BasicDouble.java @@ -1053,6 +1053,52 @@ public class BasicDouble extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicDoubleObject.java b/test/java/util/Formatter/BasicDoubleObject.java index d49f9e609..70dfd2929 100644 --- a/test/java/util/Formatter/BasicDoubleObject.java +++ b/test/java/util/Formatter/BasicDoubleObject.java @@ -1053,6 +1053,52 @@ public class BasicDoubleObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicFloat.java b/test/java/util/Formatter/BasicFloat.java index 61493b59b..122b44f1e 100644 --- a/test/java/util/Formatter/BasicFloat.java +++ b/test/java/util/Formatter/BasicFloat.java @@ -1056,6 +1056,52 @@ public class BasicFloat extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //--------------------------------------------------------------------- // %f - float diff --git a/test/java/util/Formatter/BasicFloatObject.java b/test/java/util/Formatter/BasicFloatObject.java index fb7bffa15..64c874cf2 100644 --- a/test/java/util/Formatter/BasicFloatObject.java +++ b/test/java/util/Formatter/BasicFloatObject.java @@ -1069,6 +1069,52 @@ public class BasicFloatObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicInt.java b/test/java/util/Formatter/BasicInt.java index 1945d5b61..4010d2250 100644 --- a/test/java/util/Formatter/BasicInt.java +++ b/test/java/util/Formatter/BasicInt.java @@ -1503,6 +1503,52 @@ public class BasicInt extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicIntObject.java b/test/java/util/Formatter/BasicIntObject.java index 267ffd2eb..fe41ea296 100644 --- a/test/java/util/Formatter/BasicIntObject.java +++ b/test/java/util/Formatter/BasicIntObject.java @@ -1503,6 +1503,52 @@ public class BasicIntObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicLong.java b/test/java/util/Formatter/BasicLong.java index 151dcb789..fe232f197 100644 --- a/test/java/util/Formatter/BasicLong.java +++ b/test/java/util/Formatter/BasicLong.java @@ -1503,6 +1503,52 @@ public class BasicLong extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicLongObject.java b/test/java/util/Formatter/BasicLongObject.java index 3944418b3..c99e0ba3c 100644 --- a/test/java/util/Formatter/BasicLongObject.java +++ b/test/java/util/Formatter/BasicLongObject.java @@ -1503,6 +1503,52 @@ public class BasicLongObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicShort.java b/test/java/util/Formatter/BasicShort.java index 5554c1538..39079e4ad 100644 --- a/test/java/util/Formatter/BasicShort.java +++ b/test/java/util/Formatter/BasicShort.java @@ -1503,6 +1503,52 @@ public class BasicShort extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/BasicShortObject.java b/test/java/util/Formatter/BasicShortObject.java index 629fb5736..e2dcc2301 100644 --- a/test/java/util/Formatter/BasicShortObject.java +++ b/test/java/util/Formatter/BasicShortObject.java @@ -1503,6 +1503,52 @@ public class BasicShortObject extends Basic { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/java/util/Formatter/genBasic.sh b/test/java/util/Formatter/genBasic.sh index 493e03604..2c352ad39 100644 --- a/test/java/util/Formatter/genBasic.sh +++ b/test/java/util/Formatter/genBasic.sh @@ -23,14 +23,14 @@ # have any questions. # -SPP='sh ../../../../make/java/nio/spp.sh' +javac -d . ../../../../make/tools/src/build/tools/spp/Spp.java gen() { # if [ $3 = "true" ] # then $SPP -K$1 -Dtype=$1 -DType=$2 -KprimBasic$2.java # else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 Basic$2.java # fi - $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 Basic$2.java + java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 Basic$2.java } gen boolean Boolean prim "" "" "" @@ -54,3 +54,5 @@ gen Double DoubleObject "" fp "" "" gen BigDecimal BigDecimal "" fp "" "" gen Calendar DateTime "" "" "" datetime + +rm -rf build -- GitLab