计算机系统基础关于浮点数的运算

天下无贼大杰
  • 72
#incude <stdio.h>
double f(int x) {
    return 1.0/x;
}
void main(){
    double a,b;
    int i;
    a=f(10);
    b=f(10);
    i=a==b;
    printf("%d\n", i);
}


void main(){
    double a,b,c;
    int i;
    a=f(10);
    b=f(10);
    c=f(10);
    i=a==b;
    printf("%d\n", i);
}

结果是第一个main函数输出结果为0,第二个main函数输出结果为1。书中的解释:a=f(10)被写入存储单元,而b=f(10)没有被写入,因此比较a,b,其实是比较浮点寄存器栈顶的值与精度丢失后的a的值,输出结果为0;第二个main函数多了c=f(10),因此a=f(10),b=f(10)都被写入存储器,精度都丢失,比较时再次读入浮点寄存器栈中,结果就是相等。

我的问题是:为什么第一个main函数的b=f(10);没有写入内存啊,这里就是开辟出64位的空间,然后将运算结果写入这个开辟的64位空间中,从80位浮点寄存器中到64位,b的精度丢失了啊。。。。。。

回复
阅读 2.5k
4 个回答

1、多数情况下,讨论c语言最后都变成编译器之争,所以,先说明你的编译环境。
2、永远不要用==比较2个浮点数。

我编译运行(Win7 + Cygwin + clang)的结果是没差,两个main都输出1。

我用了GCC,在x86环境下都是一样的1。
因为编译器没有理由不按照你写的代码,把数值老实赋给每个变量再比较,一般是开启了过度的优化比如-o3优化,另外很多编译器还是可以选择不同的浮点数模型(MSVC的/fp),不同的模型在简化浮点运算时会有不同的策略。
这个还和处理器结构有关,有的处理器的浮点数寄存器精度并不是一样,甚至有专门的栈,所以你的书上的结论不是绝对的,不能一概而论。
所以不要用等号比较。

永远不用使用 == 去比较浮点数。
任何解释都不是普适可靠的。

宣传栏