java - 为什么结果不一样?浮动与双倍
问题描述
System.out.println(0.1F + 0.2F); // 0.3
System.out.println(0.1D + 0.2D); // 0.30000000000000004
我理解 0.1D + 0.2D ~= 0.30000000000000004。
但我猜这些结果是一样的,但事实并非如此。
为什么结果不一样?
解决方案
为什么结果不一样?
在一般意义上:
- 因为 和 的二进制表示
float
是double
不同的。 - 因此,十进制和二进制浮点表示之间的差异(错误)在
float
与double
. - 当各个数字的表示误差不同时,计算后的误差容易不同。
在将十进制数转换为二进制、进行算术运算以及将二进制转换回十进制以打印出数字时,错误可能会蔓延和/或复合。对于实际计算机上涉及实数和有限数字表示的所有计算,它们是固有的/不可避免的。
如需更广泛的处理,请阅读:浮点数学是否损坏?
现在,如果您愿意,可以在此处检查数字的二进制表示,并准确计算出此处发生错误的位置:
- 在十进制 -> 二进制浮点转换
- 在浮点运算中
- 在二进制浮点转换->十进制转换中,
- 或以上一项以上。
如果您真的想深入研究它,我建议您看一下Float.floatToRawBits
方法及其double
类比。这些将允许您检查二进制浮点表示。然后,您可以手动将它们转换为精确的实数,并计算出与“理想”十进制表示相比的错误。
这很乏味。
推荐阅读
- apache-spark - 在选择语句期间,S3 上的火花读取镶木地板读取多少数据是正常的?
- oracle - 去掉 PL/SQL 函数末尾的逗号 [Oracle PL/SQL]
- android - 无法解析android中的方法addsnapshot listener
- mongodb - golang中如何构造动态的mongo查询
- ios - ViewController中将UIViewController修改为UIcollectionViewContorller时出错?[迅速]
- json - 在颤动中无限加载json数据
- sockets - GPRS 上具有最小(est)开销的协议
- angular - 发布现有的 NX 角度库
- javascript - 有没有人知道这段代码是做什么的?
- javascript - 如何在 NodeJS 中一次在多个函数上调用 Prometheus Histogram.observe()