noc*_*lux 1 c++ floating-point comparison
我目前正在尝试深入了解浮点表示,所以我玩了一下.在这样做的时候,我偶然发现了一些奇怪的行为; 我无法确定正在发生的事情,我会非常感激一些见解.抱歉,如果这已经得到解答,我发现谷歌很难!
#include <iostream>
#include <cmath>
using namespace std;
int main(){
float minVal = pow(2,-149); // set to smallest float possible
float nextCheck = static_cast<float>(minVal/2.0f); // divide by two
bool isZero = (static_cast<float>(minVal/2.0f) == 0.0f); // this evaluates to false
bool isZero2 = (nextCheck == 0.0f); // this evaluates to true
cout << nextCheck << " " << isZero << " " << isZero2 << endl;
// this outputs 0 0 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
基本上发生的事情是:
发生了什么 - 我会认为它们是相同的?编译器是否试图变得聪明,说除了任何数字都不可能产生零?
谢谢你的帮助!
原因isZero并且isZero2可以评估为不同的值,并且isZero可能是错误的,是允许C++编译器实现中间浮点运算,其精度高于表达式所指示的类型,但必须在赋值时删除额外的精度. .
通常,在为387历史FPU生成代码时,生成的指令适用于80位扩展精度类型,或者,如果FPU设置为53位有效数字(例如,在Windows上),则为奇怪的浮点数输入53位有效数字和15位指数.
无论哪种方式,minVal/2.0f都要进行精确评估,因为指数范围允许表示它,但是将其指定为将其nextCheck舍入为零.
如果您正在使用GCC,则还有一个-fexcess-precision=standard尚未针对C++前端实现的问题,这意味着g ++生成的代码并未完全实现标准建议的内容.
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |