提交 946ac52d 编写于 作者: S sherman

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
上级 81b5273c
...@@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException; ...@@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.text.DecimalFormat; import java.text.DecimalFormat;
...@@ -1252,7 +1253,7 @@ import sun.misc.FormattedFloatingDecimal; ...@@ -1252,7 +1253,7 @@ import sun.misc.FormattedFloatingDecimal;
* Double#toString(double)} respectively, then the value will be rounded * Double#toString(double)} respectively, then the value will be rounded
* using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision. * 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 * Float#toString(float)} or {@link Double#toString(double)} as
* appropriate. * appropriate.
* *
...@@ -3569,15 +3570,23 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3569,15 +3570,23 @@ public final class Formatter implements Closeable, Flushable {
// Create a new BigDecimal with the desired precision. // Create a new BigDecimal with the desired precision.
int prec = (precision == -1 ? 6 : precision); int prec = (precision == -1 ? 6 : precision);
int scale = value.scale(); 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 if (scale > prec) {
= new BigDecimalLayout(v.unscaledValue(), v.scale(), // 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); BigDecimalLayoutForm.DECIMAL_FLOAT);
char mant[] = bdl.mantissa(); char mant[] = bdl.mantissa();
......
...@@ -1054,6 +1054,52 @@ public class Basic$Type$ extends Basic { ...@@ -1054,6 +1054,52 @@ public class Basic$Type$ extends Basic {
test("%4.1f", " 1.0", val); test("%4.1f", " 1.0", val);
test("%4.2f", "0.99", val); test("%4.2f", "0.99", val);
test("%4.3f", "0.990", 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] #end[BigDecimal]
#if[float] #if[float]
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* @summary Unit test for formatter * @summary Unit test for formatter
* @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937
* 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 * 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 * @run shell/timeout=240 Basic.sh
*/ */
......
...@@ -1055,6 +1055,52 @@ public class BasicBigDecimal extends Basic { ...@@ -1055,6 +1055,52 @@ public class BasicBigDecimal extends Basic {
test("%4.2f", "0.99", val); test("%4.2f", "0.99", val);
test("%4.3f", "0.990", 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);
......
...@@ -1503,6 +1503,52 @@ public class BasicBigInteger extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicBigInteger extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicBoolean extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicBoolean extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicBooleanObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicBooleanObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicByte extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicByte extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicByteObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicByteObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicChar extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicChar extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicCharObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicCharObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicDateTime extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicDateTime extends Basic {
......
...@@ -1053,6 +1053,52 @@ public class BasicDouble extends Basic { ...@@ -1053,6 +1053,52 @@ public class BasicDouble extends Basic {
......
...@@ -1053,6 +1053,52 @@ public class BasicDoubleObject extends Basic { ...@@ -1053,6 +1053,52 @@ public class BasicDoubleObject extends Basic {
......
...@@ -1056,6 +1056,52 @@ public class BasicFloat extends Basic { ...@@ -1056,6 +1056,52 @@ public class BasicFloat extends Basic {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// %f - float // %f - float
......
...@@ -1069,6 +1069,52 @@ public class BasicFloatObject extends Basic { ...@@ -1069,6 +1069,52 @@ public class BasicFloatObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicInt extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicInt extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicIntObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicIntObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicLong extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicLong extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicLongObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicLongObject extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicShort extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicShort extends Basic {
......
...@@ -1503,6 +1503,52 @@ public class BasicShortObject extends Basic { ...@@ -1503,6 +1503,52 @@ public class BasicShortObject extends Basic {
......
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
# have any questions. # have any questions.
# #
SPP='sh ../../../../make/java/nio/spp.sh' javac -d . ../../../../make/tools/src/build/tools/spp/Spp.java
gen() { gen() {
# if [ $3 = "true" ] # if [ $3 = "true" ]
# then $SPP -K$1 -Dtype=$1 -DType=$2 -Kprim<Basic-X.java >Basic$2.java # then $SPP -K$1 -Dtype=$1 -DType=$2 -Kprim<Basic-X.java >Basic$2.java
# else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 <Basic-X.java >Basic$2.java # else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 <Basic-X.java >Basic$2.java
# fi # fi
$SPP -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 <Basic-X.java >Basic$2.java java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 <Basic-X.java >Basic$2.java
} }
gen boolean Boolean prim "" "" "" gen boolean Boolean prim "" "" ""
...@@ -54,3 +54,5 @@ gen Double DoubleObject "" fp "" "" ...@@ -54,3 +54,5 @@ gen Double DoubleObject "" fp "" ""
gen BigDecimal BigDecimal "" fp "" "" gen BigDecimal BigDecimal "" fp "" ""
gen Calendar DateTime "" "" "" datetime gen Calendar DateTime "" "" "" datetime
rm -rf build
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册