我知道由于精度错误,应检查float
varibale是否等于总是且具有一定容差的值。但是,如果我手动将float
变量设置为0.0f
,情况会怎样?
例如,有一个返回距离的函数。
float distance()
{
float value;
if(/* ... */)
{
// ...
return value;
}
else return 0.0f;
}
我可以安全地将结果转换为bool吗?
if(distance())
{
// ...
}
答案 0 :(得分:10)
当你写:
if(distance())
您正在检查浮动是否为零。
您的代码等同于
if(distance() != 0)
这是绝对安全的,只有你可以确定它是否具有你需要的含义。
答案 1 :(得分:3)
如果您有一个预期的确切值,那么绝对没有理由不与该确切值进行比较。只有当你执行一个计算并获得一个不精确的结果时,才能与一个精确的值进行比较是不安全的。而且您通常希望假设任何浮点计算都会产生不精确的结果。
在你的情况下,你返回一个常数,所以可以安全地比较常数。
另一次你想要与精确值进行比较是为了避免奇点。例如,x == 0.0 ? 1.0 : sin(x)/x
。
答案 2 :(得分:2)
基本上,你问你是否可以假设以下行不会被激活。
assert(0.0f);
是的。您可以认为。
答案 3 :(得分:2)
技术上,是的; 0.0f可由IEEE 754 standard表示。但问题是,当你期望它而不是下一个浮点数时,它总是为零。
但是,我不会这样做。答案 4 :(得分:1)
你担心浮点不准确是正确的,但你也可以认为在这种情况下它不是问题。
计算机将0.0f
存储为精确零以外的任何其他内容的可能性是天文数字,并且精确浮点零到布尔值的转换是明确定义的。
答案 5 :(得分:-1)
如果您知道正好 0.0,那么这样做是安全的。即不是浮点运算的结果。
但是,没有理由这样做。浮点数的相等性一般没有意义,你应该使用abs(x) <= epsilon
。
处理这种情况的更好方法是:
bool distance(float* d)
{
if( ! /* ... */)
return false
// ...
*d=value
return true;
}
...
if(distance(&d))
{
// ...
}