它是安全的,当在Java中比较2个浮点/双精度直接? [英] Is it safe when compare 2 float/double directly in Java?

查看:76
本文介绍了它是安全的,当在Java中比较2个浮点/双精度直接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

它是安全的,如果我用的比较是这样的(一个为int,b和c是浮点/双精度):

  A == b
b ==Ç
 

这可能听到可笑,但在我的老的编程语言,有时是1 + 2 = = 3是假的(因为左侧返回2.99999999999 ...)。而且,你看这个:

 的Math.sqrt(二)==的Math.sqrt(C)
B / 3 = = 10/3 //如果B = 10,它返回true?
 

解决方案

在一般情况下,不,它是不是安全,由于如此多的十进制数字不能psented为<$ C $ precisely重新$ P $ C>浮动或值。在经常说的解决方法是测试如果号码之间的差值小于一些小值(通常表示为在数学文献中的希腊小量字符)。

然而 - 你需要怎么做测试要小心一点。举例来说,如果你写的:

 如果(Math.abs(A  -  B)&LT; 0.000001){
    通信System.err.println(相等);
}
 

其中, A B 被认为是相同的,你正在测试的绝对错误的。如果你这样做,你可以进入麻烦,如果 A B 是(say_ 1,999,999.99 2,000,000.00 分别。这两个数字之间的差值小于最小的重presentable值的在那个尺度浮动,但它是不是我们的选择小量大得多。

可以说,更好的办法是使用的相对误差的;例如codeD(防守)为

 若(a == b ||
    Math.abs(一 - 二)/ Math.max(Math.abs(a)中,Math.abs(二))≤; 0.000001){
    通信System.err.println(足够接近等于);
}
 

但是,即使这是不完整的答案,因为它没有考虑到的方式,某些计算导致错误累积到不可收拾的地步。看看这个维基百科链接了解更多详情。

底线是比乍看之下,处理在浮点计算错误,是一个很大的困难。


另外一点需要注意的是(如其他人解释)整数运算的行为非常不同,以浮点运算在几个方面的:

  • 在整数除法将截断如果结果不是整数
  • 在整数加法减法和乘法会溢出。

这两个发生没有任何警告,无论是在编译或运行时。

Is it safe if I use comparision like this (a is int, b and c is float/double):

a == b
b == c

It may hear ridiculous, but in my old programing language, sometimes 1 + 2 == 3 is false (because left side returns 2.99999999999...). And, what about this:

Math.sqrt(b) == Math.sqrt(c)
b / 3 == 10 / 3 //In case b = 10, does it return true?

解决方案

In general, no it is not safe due to the fact that so many decimal numbers cannot be precisely represented as float or double values. The often stated solution is test if the difference between the numbers is less than some "small" value (often denoted by a greek 'epsilon' character in the maths literature).

However - you need to be a bit careful how you do the test. For instance, if you write:

if (Math.abs(a - b) < 0.000001) {
    System.err.println("equal");
}

where a and b are supposed to be "the same", you are testing the absolute error. If you do this, you can get into trouble if a and b are (say_ 1,999,999.99 and 2,000,000.00 respectively. The difference between these two numbers is less than the smallest representable value at that scale for a float, and yet it is much bigger than our chosen epsilon.

Arguably, a better approach is to use the relative error; e.g. coded (defensively) as

if (a == b ||
    Math.abs(a - b) / Math.max(Math.abs(a), Math.abs(b)) < 0.000001) {
    System.err.println("close enough to be equal");
}

But even this is not the complete answer, because it does not take account of the way that certain calculations cause the errors to build up to unmanageable proportions. Take a look at this Wikipedia link for more details.

The bottom line is that dealing with errors in floating point calculations is a lot more difficult than it appears at first glance.


The other point to note is (as others have explained) integer arithmetic behaves very differently to floating point arithmetic in a couple of respects:

  • integer division will truncate if the result is not integral
  • integer addition subtraction and multiplication will overflow.

Both of these happen without any warning, either at compile time or at runtime.

这篇关于它是安全的,当在Java中比较2个浮点/双精度直接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆