我正在尝试使用 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
。对于带小数部分的 double 值,我只想保留两位小数。
对出了什么问题有什么建议吗?
最佳答案
关于为什么解析值被 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 涵盖双重
文字:
The elements of the types float and double are those values that can be represented using the IEEE 754 32-bit single-precision and 64-bit double-precision binary floating-point formats, respectively.
The details of proper input conversion from a Unicode string representation of a floating-point number to the internal IEEE 754 binary floating-point representation are described for the methods valueOf of class Float and class Double of the package java.lang.
并引用 Double.valueOf
javadocs :
s is regarded as representing an exact decimal value in the usual "computerized scientific notation" or as an exact hexadecimal value; this exact numerical value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type double by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic [...]
此外,该值仍在 long
值范围内,仍将正确表示整数值。
long l2 = 1234567879123456789L;
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(df.format(l2));
这输出
1234567879123456789
关于java - 使用 DecimalFormat 格式化大双数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22028675/