- 论坛徽章:
- 2
|
回复 1# pmerofc
你的意思是不是:
#define F ...
float f = F;
double d1 = f * f;
double d2 = (double)f * (double)f;
double d3 = F * F;
double d4 = (double)F * (double)F;
d2与d4应该相同, d1与d3应该相同?
而实际结果是 d2与d4与d1相同, d3与它们不同?
但 d1 与 d3 应该相同的根据又是什么?
F * F 是一个常量表达式,允许在编译时求值(由编译器), 但 f * f不是常量表达式, 要在运行时求值(由被编译出的程序)。
我这里的一些测试结果(F是 1+1/2^12,你给的1.234567f计算太麻烦了……)是 d1,d2,d4 是按double计算的,没有丢失精度(但printf输出时丢失了)。
而d3是按float计算的……
也许标准想表达的是:
1. float*float 应该只期待它有float的精度
也许换个平台 f*f, F*F 就都会丢失精度
2. float*float 也允许按更高精度计算,只是这应该作为bonus。
如果确实需要double*double,应该(double)f * f 或者 (double)F * F。
例如我这里测试的运行时就是这样的行为, f * f没有丢失精度。
3. 我测试的编译器对编译时计算就没有这样的bonus…… 于是 F * F 就丢失精度了。
但编译器也有一些选项可以保持精度。 VC6有个/Op , VC8+有 /fp:
|
|