And*_*nck 12 c++ floating-point double
今天早上我有一个小型的WTF时刻.WTF可以概括为:
float x = 0.2f;
float y = 0.1f;
float z = x + y;
assert(z == x + y); //This assert is triggered! (Atleast with visual studio 2008)
Run Code Online (Sandbox Code Playgroud)
原因似乎是表达式x + y
被提升为double并与之中的截断版本进行比较z
.(如果我更改z
为double
断言未触发).
我可以看到,出于精确原因,在将结果转换为单精度之前,以双精度执行所有浮点算术是有意义的.我在标准中找到了以下段落(我想我已经知道了,但在这种情况下不是这样):
4.6.1.
"类型的右值float
可以转换为类型的右值double
.值不变"
我的问题是,x + y
保证会被提升为双倍,还是由编译人员自行决定?
更新:由于许多人声称不应该使用==
浮点数,我只是想说在我正在使用的特定情况下,确切的比较是合理的.
浮点比较是棘手的,这里有一个关于这个主题的有趣链接,我认为还没有提到.
moo*_*dow 14
您通常不能假设==
它将按预期的方式运行浮点类型.比较舍入值或使用abs(a-b) < tolerance
相反的结构.
升级完全由编译器自行决定(并取决于目标硬件,优化级别等).
在这种特殊情况下发生的事情几乎可以肯定,值以比存储器更高的精度存储在FPU寄存器中 - 通常,现代FPU硬件在程序员要求的精度内部以双精度或更高精度工作,编译器生成代码在将值存储到内存时进行适当的转换; 在未经优化的构建中,结果x+y
仍然是z
在进行比较时的寄存器中,但是已经存储到内存中并被取回,因此被截断为浮点精度.
归档时间: |
|
查看次数: |
3301 次 |
最近记录: |