在当前的C++和Java中,double类型和float类型:if(x == 0.0)是否正确?

Zha*_*nan 5 c++ java floating-point double

在我以前的知识中:当我们想要检查double或float是否等于0.0时,
我们不应该这样写:

double x = 0.0;
if (x == 0.0) System.out.println("yes");
else System.out.println("no");
Run Code Online (Sandbox Code Playgroud)

但几分钟前,我再次尝试过,在Java(1.7)C++(Apple LLVM 6.0版)下,编写这样的问题没有问题!我分别在Java和C++下尝试过"double"类型和"float"类型.

我的问题:

  • 我错过了什么,或者我们真的可以在当前的Java和C++下检查double或float.
  • 如果可以的话,我们是否可以在Java和C++的早期版本下完成它?


结论(基于所有帮助):
我们不应该使用"float == float或double == double"来检查两个浮点数或两个双精度数是否相等(如果我们想得到正确的答案),原因在于所有答案和评论如下.


版(第一次):非常
感谢您的帮助!
但是一分钟前,我只是在Java(1.7)下尝试这些,都显示" ",
看来我们真的可以在当前的Java下做到!

float x = 0.0f;
if (x == 0) System.out.println("yes");
else System.out.println("no");

float y = 100.0f - 50.0f*2.0f + 45.0f*3 - 135.0f;
if (y == 0.0f) System.out.println("yes");
else System.out.println("no");

if (100.0f - 50.0f*2.0f + 45.0f*3 - 135.0f == 0.0f) System.out.println("yes");
else System.out.println("no");
Run Code Online (Sandbox Code Playgroud)


版本(第二次):
但我试过这个,Java也显示" ",(在Java(1.7)下).
我尝试消除编译器的"预计",并将计算分成几个步骤.

float a = 100.0f;
float b = 50.0f;
float c = 2.0f;
float bc = b * c;
System.out.println("b*c = " + bc);

float d = 45.0f;
float e = 3.0f;
float de = d * e;
System.out.println("d*e = " + de);

float f = 135.0f;

float g = a - bc + de - f;
float h = 0.0f;
if (g == h) System.out.println("yes");
else System.out.println("no");
Run Code Online (Sandbox Code Playgroud)


版(第3次):
谢谢你@ DiegoBasch的反例(浮法==浮动):
这一次的Java(1.7)显示" ".

float m = 0.37f - 0.36f;
float n = 0.01f;
if (m - n == 0.0f) System.out.println("yes");
else System.out.println("no");
Run Code Online (Sandbox Code Playgroud)

ajb*_*ajb 6

代码是合法的.问题在于,当您进行涉及浮点数的计算时,会出现舍入错误,因此在许多情况下检查0(或检查两个数字是否相等)将不起作用.

此代码适用于任何语言,因为您没有做任何会导致舍入的事情:

double x = 0.0;
if (x == 0.0) System.out.println("yes");
else System.out.println("no");
Run Code Online (Sandbox Code Playgroud)

但是,这段代码可能不错:

double a1 = ...something...;
double a2 = ...something...;
double a3 = a1 / a2;
double a4 = a3 * a2;
double a5 = a4 - a1;
if (a5 == 0.0) ...
Run Code Online (Sandbox Code Playgroud)

尽管在数学上a5应该为0,但实际上==操作可能false因为舍入而返回.

这需要了解计算机中浮点的处理方式; 它与任何语言或语言版本无关.一个参考是每个计算机科学家应该知道的浮点数.

  • [本网站](http://floating-point-gui.de/)经常被引用为"可消化形式的Goldberg论文". (4认同)