为什么String.valueOf(5.6d + 5.8d)
和String.format("%f", 5.6d + 5.8d)
的值不同?
String.valueOf(5.6d + 5.8d)
将显示“ 11.399999999999999”。
String.format("%f", 5.6d + 5.8d)
将打印“ 11.400000”。
为什么会这样?
编辑:问题与Is floating point math broken?不同,因为String.format()
向上取整(请参阅答案)
答案 0 :(得分:3)
摘自String#format的格式字符串文档:
如果精度小于分别由Float.toString(float)或Double.toString(double)返回的字符串中小数点后出现的位数,则将使用四舍五入舍入该值向上算法。
默认情况下,String.format("%f", ...)
使用6
精度的十进制数字;因为该位数比Double.toString(double)
使用的数字少(相当于String.valueOf(double)
),所以该值按上述舍入。
答案 1 :(得分:3)
解释分为两部分。
由于二进制浮点表示,精度和舍入问题,5.6d + 5.8d
的结果并不完全11.4
;请参阅Is floating point math broken?,以了解为什么会这样。 (而且不,它没有损坏!)
对于相同的String.valueOf
值,String.format
和double
输出不同答案 的原因归结为各自的规范:
对于valueOf
:
“ m或a的小数部分必须打印多少个数字?必须至少有一个数字来表示小数部分,并且除此以外,必须有尽可能多的位数,但只能是需要将参数值与double类型的相邻值唯一区分开。”
double
的值比11.399999999999999
更接近14.0
,因此输出为前者。
对于format
:
“如果转换为'e','E'或'f',则精度为小数点分隔符后的位数。如果未指定精度,则假定为6 。”
当您将11.399999999999999
的精度四舍五入到小数点后6位时,您得到11.40000000
。
(以上引号来自Java 9 javadocs。)