Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.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 平等性检验与机器精度_C - Fatal编程技术网

C 平等性检验与机器精度

C 平等性检验与机器精度,c,C,我在第174页找到了这个代码片段,这是一本关于艾拉·波尔的C-Al Kelley的书 int main() { int cnt=0; double sum=0.0,x; for( x=0.0 ;x!= 9.9 ;x+=0.1) { sum=sum +x; printf("cnt = %5d\n",cnt++); } return 0; } 正如书中所说,它变成了一个无限循环。它没有提到确切的原因,只是说这与机器的精度有关 我修改了代码以检查 x=9.9 将成为现实,即通

我在第174页找到了这个代码片段,这是一本关于艾拉·波尔的C-Al Kelley的书

int main()
{
 int cnt=0; double sum=0.0,x; 
 for( x=0.0 ;x!= 9.9 ;x+=0.1)
 {
   sum=sum +x;
   printf("cnt = %5d\n",cnt++);
 }
 return 0;
}

正如书中所说,它变成了一个无限循环。它没有提到确切的原因,只是说这与机器的精度有关

我修改了代码以检查 x=9.9 将成为现实,即通过添加以下行,x达到9.9

 diff=x-9.9;
 printf("cnt =10%d  \a x =%10.10lf  dif=%10.10lf \n",++cnt,x,diff);
我在输出中得到了以下几行

 cnt =1098   x =9.7000000000  dif=-0.2000000000 
 cnt =1099   x =9.8000000000  dif=-0.1000000000 
 cnt =10100   x =9.9000000000  dif=-0.0000000000 
 cnt =10101   x =10.0000000000  dif=0.1000000000 
 cnt =10102   x =10.1000000000  dif=0.2000000000 

如果x正好达到9.9的值,为什么它仍然是一个无限循环?

您可以放心地假设两个浮点数永远不会“完全”相等(除非一个是另一个的副本)。

问题是大多数浮点数实现都基于IEEE 754。看

问题是,数字是用基数2(二进制格式)构建的

数字9.9绝对不能用基2构建

David Goldberg GV的“数值计算指南”对此作了准确的说明:

提出了几种不同的实数表示法, 但到目前为止,最广泛使用的是浮点表示法。 浮点表示法有一个基数b(通常假定为 是均匀的)和一个精确的p。如果b=10,p=3,则数字0.1为 表示为1.00×10^-1。如果b=2,p=24,则小数点 数字0.1无法精确表示,但近似为 1.10011001×2^-4


你只是简单地以太低的精度打印数字,以至于没有注意到它不准确。试着这样做:

#include <stdio.h>

int main()
{
  double d = 9.9;

  if(d == 9.9)
  {
    printf("Equal!");
  }
  else
  {
    printf("Not equal! %.20f", d);
  }
}

这本书可能是想教你永远不要使用==或!=运算符来比较浮点变量。同样出于同样的原因,千万不要将浮点用作循环迭代器。

计算机使用二进制和浮点运算,换句话说,使用基数2。就像基数10一样,基数2也有它无法构建的数字。例如,试着把分数10/3写在基数10中。你将得到无限的3。在二进制中,你甚至不能用二进制写0.1(十进制),你还会得到一个循环模式0.000110011。。。(二进制)


本视频将更好地解释从哪里来的
X
。。。???你是说
sum!=9.9
循环条件下的
。这是许多类似问题的重复。底线-双精度不能准确地表示
0.1
,因此您将得到
99*0.1!=9.9
Not equal! 9.90000000000000035527