使用DecimalFormat格式化大双数

时间:2014-02-25 23:41:47

标签: java

我正在尝试使用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。对于带小数部分的双精度值,我只想保留两个小数点。

关于出了什么问题的任何建议?

2 个答案:

答案 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

因此,您在源代码中输入的数字最接近doubleSection 3.10.2 of the JLS涵盖double文字:

  

float和double类型的元素分别是可以使用IEEE 754 32位单精度和64位双精度二进制浮点格式表示的值。

     

对于类Float的方法valueOf和包java.lang的类Double,描述了从浮点数的Unicode字符串表示到内部IEEE 754二进制浮点表示的正确输入转换的详细信息。 / p>

并参考Double.valueOf javadocs

  

被视为代表通常的“计算机化科学记数法”中的精确十进制值或精确的十六进制值;然后,这个精确的数值在概念上被转换为“无限精确”的二进制值,然后通过IEEE 754浮点运算的通常的舍入到最接近的规则舍入为double类型[...]

此外,此值仍在long值的范围内,这仍将正确表示整数值。

long l2 = 1234567879123456789L;
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(df.format(l2));

此输出

1234567879123456789

答案 1 :(得分:0)

你的文字有19个十进制数字,但双精度只有15.9十进制数字。