我使用PVS Studio分析器扫描了我的代码,我对此错误以及如何解决此问题感到困惑。
V550奇怪的精确比较:* dest == value。使用具有定义精度的比较可能更好:fabs(A-B)<小量。
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;
}
答案 0 :(得分:1)
无论谁想,我们都在谈论this代码。
我将尝试解释PVS工作室开发人员试图通过此消息实现的目标。引用他们的reference关于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.49999999999999994。
他们想说的是,比较浮点数是很棘手的。如果您只是分配浮点数,请将其存储并在内存中移动以便稍后在此功能中与自身进行比较 - 随时关闭此错误消息。
如果您希望执行一些位代表检查(我真的认为您正在做),见下文。
如果您正在对浮点数进行一些大规模计算,并且您是游戏开发者,计算敌方战列巡洋舰的坐标 - 此警告是您最好的朋友之一。
无论如何,让我们回到你的案子。正如PVS-Studio经常发生的那样,他们没有看到确切的错误,但他们指出了正确的方向。您实际上想要来比较两个浮动值,但您正在执行错误。问题是,如果您要比较的两个浮点数都包含NaN(即使在相同的位表示中),您将获得*dest != value
,并且您的代码将无法以您希望的方式工作。
在这种情况下,您最好将float *
下的内存重新解释为uint32_t
(或者与目标上的float
大小相同的任何整数类型),然后将它们进行比较。
例如,在您的特定情况下,register_file_->values[register_name]
属于type xe::gpu::RegisterFile::RegisterValue
,已支持uint32_t
代表。
作为副作用,这将引出警告:)