Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在当前的C++;Java、双精度类型和浮点类型:如果(x==0.0)正确?_Java_C++_Floating Point_Double - Fatal编程技术网

在当前的C++;Java、双精度类型和浮点类型:如果(x==0.0)正确?

在当前的C++;Java、双精度类型和浮点类型:如果(x==0.0)正确?,java,c++,floating-point,double,Java,C++,Floating Point,Double,根据我的老知识:当我们想检查double或float是否等于0.0时, 我们不应该这样写: double x = 0.0; if (x == 0.0) System.out.println("yes"); else System.out.println("no"); 但是几分钟前,我又试了一次,在Java(1.7)和C++(Apple LLVM 6.0版)下,这样写是没有问题的!在java和C++环境下,我分别尝试了“双”类型和“浮点”类型。 我的问题: 我错过什么了吗,或者我们真的可以检查

根据我的老知识:当我们想检查double或float是否等于0.0时,
我们不应该这样写:

double x = 0.0;
if (x == 0.0) System.out.println("yes");
else System.out.println("no");
但是几分钟前,我又试了一次,在Java(1.7)C++(Apple LLVM 6.0版)下,这样写是没有问题的!在java和C++环境下,我分别尝试了“双”类型和“浮点”类型。 我的问题:

  • 我错过什么了吗,或者我们真的可以检查双精度或浮点数 在当前的java和C++中.
  • 如果我们能,我们能在早期版本的java和C++ +< /LI>下做吗?

结论(基于所有帮助):
我们不应该使用“float==float或double==double”来检查两个float或两个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");

版本(第二次):
但我已经尝试过了,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");

版本(第三次):
感谢@DiegoBasch的反例(对于float==float):
这次Java(1.7)显示“no


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

这段代码在任何语言中都很好,因为您没有做任何会导致舍入的操作:

double x = 0.0;
if (x == 0.0) System.out.println("yes");
else System.out.println("no");
但是,此代码可能不好:

double a1 = ...something...;
double a2 = ...something...;
double a3 = a1 / a2;
double a4 = a3 * a2;
double a5 = a4 - a1;
if (a5 == 0.0) ...
即使在数学上
a5
应该是0,但实际上
=
操作可能会因为四舍五入而返回
false


这需要了解计算机中如何处理浮点运算;它与任何语言或语言版本无关。一个参考是。

为了补充ajb的答案,这里有一个数字错误的例子。你不需要太多的计算就可以实现

    double a = 0.37 - 0.36; // 0.010000000000000009
    double b = 0.01;
    System.out.println (a - b == 0.0); // false

x
正好是
0
,所以它是正常的。问题是当
x
是一系列运算的结果,这些运算在数学上会产生
0
,但由于数字原因不会产生
0.0
。要详细说明@juanchopanza所说的话,在你的例子中,这将被评估为真,但是你不能保证
100.0-50.0*2.0==0.0
,即使在数学上它应该是这样。浮点通常被描述为“近似”值,这是误导性的。浮点数有一个精确的值,只是由于精度有限,这个值可能与您期望的不完全相同。因此,如果要将其与预期值进行比较,则不应问“它们是否完全相同”,而应问“它们是否足够接近”。
0.0
1.3
3.14159
在这个意义上没有什么不同。@Cyber实际上,您可以保证表达式是相等的,因为所涉及的数字可以精确地表示出来。有些数字可以<代码>1.3和
3.14159不能。要更好地了解浮动是如何表示的,请参阅我的网站;试着输入
100.0
1.3
3.14159
等,看看这些数字是如何表示为
float
double
。这里
如果((0.1+0.2-0.3)==0)
。编译器甚至知道后面的任何内容都是死代码。经常被引用为“可消化形式的戈德堡论文”。你好@ajb,非常感谢你的帮助,但我只是在Java(1.7)下用一些计算尝试了一下。它可以工作……请看我的版本,似乎我们现在真的可以在Java下完成它。@Zhaonan请看我对你编辑的评论<代码>=
将与一些数字一起使用,这一直都是这样。它不会在所有情况下都起作用。这与Java版本无关。@Hi ajb,非常感谢,我认为Diego Basch找到了一个反例,你是对的,它不会在所有情况下都起作用。Hi@Diego Basch,非常感谢你的反例,现在我相信“float==float”不会在所有情况下都起作用。
    double a = 0.37 - 0.36; // 0.010000000000000009
    double b = 0.01;
    System.out.println (a - b == 0.0); // false