如果 foo 属于float类型,则以下表达式是有效/推荐的吗?
(0.0f == foo * float(0))
无论foo的值如何,它都具有预期的(数学)值吗?
C ++标准是定义行为还是特定于实现?
答案 0 :(得分:3)
嗯,首先,它不是C ++标准的问题。相反,问题在于您的浮点模型标准(很可能是IEEE)。
对于IEEE浮点数,这可能是安全的,因为float(0)
应该得到与0.0f相同的数字,并且乘以任何其他数字也应该是0.0f。
不安全的是做其他浮点运算(例如:用非整数加法和减法)并用0.0f检查它们。
答案 1 :(得分:2)
AFAIK,不一定,也可能最终非常接近0。
通常最好与epsilon进行比较。我使用这样的函数进行这样的比较:
float EpsilonEqual( float a, float b, float epsilon )
{
return fabsf( a - b ) < epsilon;
}
答案 2 :(得分:2)
NaNs和Infinites可能会像其他人已经提到的那样搞砸了这种比较。
然而,还有一个陷阱:在C ++中,你不能依赖float类型的编译时表达式,比较等于在运行时计算的相同表达式。
原因在于C ++允许以任何方式无限制地扩展fp计算的精度。例如:
#include <iostream>
// This provides sufficent obfuscation so that g++ doesn't just inline results.
bool obfuscatedTrue() { return true; }
int main()
{
using namespace std;
double const a = (obfuscatedTrue()? 3.0 : 0.3);
double const b = (obfuscatedTrue()? 7.0 : 0.7);
double const c = a/b;
cout << (c == a/b? "OK." : "\"Wrong\" comparision result.") << endl;
}
使用一个特定编译器的结果:
C:\test> g++ --version | find "++"
g++ (TDM-2 mingw32) 4.4.1
C:\test> g++ fp_comparision_problem.cpp & a
"Wrong" comparision result.
C:\test> g++ -O fp_comparision_problem.cpp & a
OK.
C:\test> _
干杯&amp;第h。,
- Alf
答案 3 :(得分:1)
使用该特定语句,您可以非常确定结果将是0
并且比较为true
- 我认为C ++标准实际上没有规定它,但任何合理的浮动实现点类型将0
像这样工作。
但是,对于大多数其他计算,结果不能完全等于数学上正确结果的字面值:
为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而且 相反,我得到一个奇怪的结果,如 0.30000000000000004吗
因为在内部,计算机使用a 格式(二进制浮点) 无法准确表示一个数字 像0.1,0.2或0.3一样。
编译代码时 解释,你的“0.1”已经存在 四舍五入到最接近的数字 格式,这导致一个小的 甚至在之前的舍入错误 计算发生了。
阅读The Floating-Point Guide以获取详细说明以及如何正确执行comparisons with expected values。
答案 4 :(得分:0)
我刚刚在msdn中阅读了有关VisualStudio中/ fp选项的这篇文章 link text
表达式优化 对特殊值无效(NaN, + infinity,-infinity,+ 0,-0)将不被允许。优化x-x =&gt; 0,x * 0 =&gt; 0,x-0 =&gt; x,x + 0 =&gt; x,和 0-x =&gt; -x对各种都无效 原因(见IEEE 754和C99 标准)。