I',尝试这个简单的代码。它显示了无法用float表示的前10个整数:
int main(){
int i, cont=0;
float f;
double di, df;
for(i=10000000, f=i; i<INT_MAX; i++, f=i, df=f, di=((float)i)){
if(i!=f){
printf("i=%d f=%.2f df=%.2lf di=%.2lf\n", i, f, df, di);
if(cont++==10) return 0;
}
}
return 1;
}
di 是一个双变量,但我把它设置为(float)i ,所以它应该等于df,但它不是。
例如,数字16777217由 f 和 df 表示为16777216,但 di 仍为16777217,忽略 (浮动)施放。
这怎么可能?
**我使用的是:gcc(Ubuntu 4.4.3-4ubuntu5)4.4.3
答案 0 :(得分:2)
与您的问题相关的是the C99 standard中的6.3.1.8:2:
浮动操作数的值和浮动的结果 表达式可以表示为更高的精度和范围 类型所要求的;因此,类型不会改变。
特别是脚注52:
仍需要使用转换和赋值运算符执行6.3.1.4和6.3.1.5中所述的指定转换。
阅读脚注,我会说你已经在编译器中发现了一个错误。
您可能已在编译器中发现了两个错误:i!=f
比较是在浮点数之间完成的(请参阅标准同一页面上的促销规则),因此它应始终为false。虽然在后一种情况下,我认为可以允许编译器使用更大的类型进行6.3.1.8:2的比较,也许使得比较等同于(double)i!=(double)f
,因此有时也是如此。第6.3.1.8:2段是我最讨厌的标准中的段落,我仍然试图理解严格的别名。
答案 1 :(得分:2)
这篇文章解释了发生了什么:
http://www.exploringbinary.com/when-floats-dont-behave-like-floats/
基本上可以在机器上存储额外的精度以进行不同的表达式评估,使得相等的浮点数不相等。