为什么在 Java 中比较浮点数不一致?

新手上路,请多包涵
class Test{
    public static void main(String[] args){
        float f1=3.2f;
        float f2=6.5f;

        if(f1==3.2){
            System.out.println("same");
        }else{
            System.out.println("different");
        }
        if(f2==6.5){
            System.out.println("same");
        }else{
            System.out.println("different");
        }
    }
}

输出:

 different
same

为什么输出是这样的?我预计 same 作为第一种情况的结果。

原文由 PSR 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 471
2 个回答

不同之处在于 6.5 可以用 float 和 double 精确表示,而 3.2 不能用任何一种类型精确表示。并且两个最接近的近似值不同。

float 和 double 之间的相等比较首先将 float 转换为 double,然后比较两者。所以数据丢失。


您不应该比较浮点数或双精度数是否相等;因为您不能真正保证分配给 float 或 double 的数字是准确的。

_这种舍入误差是浮点计算的一个特征_。

将无限多的实数压缩成有限的位数需要近似表示。尽管整数有无穷多个,但在大多数程序中,整数计算的结果可以用 32 位存储。

相反,给定任何固定位数,大多数实数计算将产生无法使用那么多位数精确表示的量。因此,浮点计算的结果通常必须四舍五入以适应其有限表示。这种舍入误差是浮点计算的特征。

检查 每个计算机科学家应该了解的有关浮点运算 的更多信息!

原文由 Abimaran Kugathasan 发布,翻译遵循 CC BY-SA 4.0 许可协议

它们都是 IEEE 浮点标准 不同部分的实现。 A float 是 4 字节宽,而 double 是 8 字节宽。

根据经验,在大多数情况下,您应该更喜欢使用 double ,并且只有在有充分理由时才使用 float 。 (使用 float 而不是 double 的一个很好的理由是“我 知道 我不需要那么多精度,我需要在内存中存储一百万个精度.“) 还值得一提的是,很难证明您不需要 double 精度。

此外,在比较浮点值是否相等时,您通常希望使用类似 Math.abs(a-b) < EPSILON 的东西,其中 ab 值是被比较的浮点值 EPSILON 是一个小的浮点值,如 1e-5 。这样做的原因是浮点值很少编码它们“应该”的确切值——相反,它们通常编码一个非常接近的值——所以当你确定两个值是否相同时你必须“眯着眼睛”。

编辑:每个人都应该阅读下面发布的@Kugathasan Abimaran 链接: 每位计算机科学家都应该了解的浮点运算了解更多!

原文由 sigpwned 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题