PVS-Studio抱怨浮点比较
PVS-Studio complaining about float comparison
我用PVS Studio分析仪扫描了我的代码,我对为什么会出现此错误以及如何解决此问题感到困惑。
V550 一个奇怪的精确比较:* dest == 值。最好使用具有定义精度的比较:fabs(A - B( <Epsilon。>
bool PipelineCache::SetShadowRegister(float* dest, uint32_t register_name) {
float value = register_file_->values[register_name].f32;
if (*dest == value) {
return false;
}
*dest = value;
return true;
}
我猜要像这样更改代码:
bool PipelineCache::SetShadowRegister(float* dest, float* epsilon uint32_t register_name) {
float value = register_file_->values[register_name].f32;
return fabs(dest - value) < epsilon;
}
无论谁想知道,我们都在谈论这段代码。
我将尝试解释 PVS 工作室开发人员试图通过此消息实现的目标。引用他们对V550的参考:
请考虑以下示例:
double a = 0.5; if (a == 0.5) //OK x++; double b = sin(M_PI / 6.0); if (b == 0.5) //ERROR x++;
第一个比较 'a == 0.5' 是正确的。第二个比较 'b == 0.5' 可能既正确又错误。'b == 0.5' 表达式的结果取决于处理器、编译器的版本和所使用的设置。例如,当我们使用 Visual C++ 2010 编译器时,'b' 变量的值为
0.499999999999994。
他们想说的是,比较浮点数是棘手的。如果您只是分配浮点数,请存储它并在内存中移动它,以便稍后在此函数中与自身进行比较 - 请随时关闭此错误消息。
如果你想执行一些位表示检查(老实说,我认为你正在这样做(,见下文。
如果您正在对浮点数进行大量计算,并且您是游戏开发人员,正在计算敌方战列巡洋舰的坐标 - 此警告是您最好的朋友之一。
无论如何,让我们回到你的案例。正如PVS-Studio通常发生的那样,他们没有看到确切的错误,但他们为您指出了正确的方向。您实际上想比较两个浮点值,但您做错了。问题是,如果您正在比较的两个浮点数都包含 NaN(即使在相同的位表示中(,您也会得到*dest != value
,并且您的代码将无法以您想要的方式工作。
在这种情况下,最好将float *
下的内存重新解释为uint32_t
(或任何整数类型与目标上的float
大小相同的整数类型(并进行比较。
例如,在您的特定情况下,register_file_->values[register_name]
属于xe::gpu::RegisterFile::RegisterValue
类型,它已经支持uint32_t
表示。
作为副作用,这会将警告引开:)
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么比较运算符如此快速
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 为什么Visual Studio没有对逻辑比较错误进行热身?
- PVS-Studio抱怨浮点比较
- 在Linux上使用Cmake时,我该如何告诉PVS-Studio忽略第三方库中的所有文件
- PVS-Studio 是否了解远期申报的必要性?
- 在PVS Studio中的BOOST_REQIRE之后,将变量标记为非NULL
- PVS Studio抱怨危险的宏观表达
- 误报警告PVS Studio:V808类型的对象是创建但未使用的
- 如何在 Visual Studio 中基于字符串比较设置条件断点
- Visual Studio 2010 与 2012 编译时性能和稳定性比较,适用于C++用户
- Visual Studio调试与发布版本:比较int和float不匹配
- Visual Studio C++ 字符串比较而不带声明
- 有没有办法比较Visual Studio中的obj文件
- 关于 VC++ 和 Sun Studio 中的字段初始化顺序、签名比较和未使用的变量的警告
- Visual Studio 2010 - 为什么字符串文本比较是C++中实现定义的行为
- 在Visual Studio Express中使用c++比较两个目录