我正在尝试使用DecimalFormat
格式化双数字,只打印带有2位小数的数字,如果它有小数部分,我想按原样打印数字。当数字很小时,下面的代码工作正常但数字很大,它没有按预期工作。
DecimalFormat df = new DecimalFormat("#.##"); //have tried just # too
double d1 = 56789d;
System.out.println(df.format(d1)); //works fine - prints 56789
double d2 = 1234567879123456789d;
System.out.println(df.format(d2)); // does not work
我需要1234567879123456770
时输出1234567879123456789
。对于带小数部分的双精度值,我只想保留两个小数点。
关于出了什么问题的任何建议?
答案 0 :(得分:8)
关于19
关闭解析值的原因的解释在于double
值的表示方式,为IEEE floating-point numbers,精度为53位。也就是说,对于输入时的较大值,精度实际上大于1
。方法Math.ulp
,对于“最后位置的单位”,给出了最接近的double
值可以在其参数的大小上分开。
double d2 = 1234567879123456789d;
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(Math.ulp(d2));
System.out.println(df.format(d2));
此输出
256.0
1234567879123456770
因此,您在源代码中输入的数字最接近double
。 Section 3.10.2 of the JLS涵盖double
文字:
float和double类型的元素分别是可以使用IEEE 754 32位单精度和64位双精度二进制浮点格式表示的值。
对于类Float的方法valueOf和包java.lang的类Double,描述了从浮点数的Unicode字符串表示到内部IEEE 754二进制浮点表示的正确输入转换的详细信息。 / p>
被视为代表通常的“计算机化科学记数法”中的精确十进制值或精确的十六进制值;然后,这个精确的数值在概念上被转换为“无限精确”的二进制值,然后通过IEEE 754浮点运算的通常的舍入到最接近的规则舍入为double类型[...]
此外,此值仍在long
值的范围内,这仍将正确表示整数值。
long l2 = 1234567879123456789L;
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(df.format(l2));
此输出
1234567879123456789
答案 1 :(得分:0)
你的文字有19个十进制数字,但双精度只有15.9十进制数字。