简体   繁体   English

将值为0.0f的浮点数转换为布尔值是否安全?

[英]Is it safe to cast a float with value 0.0f to boolean?

I know that due to precision errors, a float varibale should be checked to equal a value always with some tolerance . 我知道由于精度错误,应检查float变量,使其等于一个始终具有一定容差的值。 But what's is that even the case if I manually set the float variable to 0.0f ? 但是,如果我手动将float变量设置为0.0f甚么?

For example there is a function returning a distance. 例如,有一个返回距离的函数。

float distance()
{
    float value;
    if(/* ... */)
    {
        // ...
        return value;
    }
    else return 0.0f;
}

Can I cast the result to bool safely? 我可以安全地将结果转换为bool吗?

if(distance())
{
   // ...
}

When you write: 当你写:

if(distance())

you are checking whether the float is zero or not. 你正在检查浮子是否为零。

Your code is equivalent to 你的代码相当于

if(distance() != 0)

This is perfectly safe to do, and only you can determine whether or not it has the meaning that you require. 这样做非常安全,只有您可以确定它是否具有您需要的含义。

If you have an exact value that you expect, there's absolutely no reason not to compare against that exact value. 如果你有一个你期望的确切值,那么绝对没有理由不与那个确切的值进行比较。 It's only when you perform a computation and get an inexact result that it's unsafe to compare against an exact value. 只有当你执行一个计算并获得一个不精确的结果时,才能与一个精确的值进行比较是不安全的。 And you generally want to assume that any floating point computation will give an inexact result. 而且您通常希望假设任何浮点计算都会产生不精确的结果。

In your case, you're returning a constant, so it's safe to compare to a constant. 在你的情况下,你返回一个常量,所以比较常量是安全的。

Another time you'd want to compare against an exact value is to avoid singularities. 另一次你想要与精确值进行比较是为了避免奇点。 For example, x == 0.0 ? 1.0 : sin(x)/x 例如, x == 0.0 ? 1.0 : sin(x)/x x == 0.0 ? 1.0 : sin(x)/x . x == 0.0 ? 1.0 : sin(x)/x

Basically, you're asking if you can assume that the following line won't fire. 基本上,你问你是否可以假设以下行不会触发。

assert(0.0f); 

Yes. 是。 You can assume that. 你可以认为。

Technically, yes; 从技术上讲,是的; 0.0f is representable by the IEEE 754 standard . 0.0f可由IEEE 754标准表示 However, the question is that will it be always zero, when you expect it to be and not the next floating point number. 但问题是,当你期望它而不是下一个浮点数时,它总是为零。

I wouldn't do it, though. 不过,我不会这样做。

You're correct to worry about floating-point inaccuracy, but you're also correct to suppose that it isn't a problem in this case. 你担心浮点不准确是正确的,但你也可以认为在这种情况下它不是问题。

The likelihood of your computer storing 0.0f as anything other than precisely zero is astronomical, and a conversion of precisely floating-point zero to boolean is well-defined. 计算机将0.0f存储为精确零以外的任何其他可能性是天文数字,并且精确浮点零到布尔值的转换是明确定义的。

It is safe to do it if you know that it will be exactly 0.0. 如果您知道它将精确到 0.0,那么这样做是安全的。 ie not a result of float arithmetic. 即不是浮点运算的结果。

However, there is no reason to do it. 但是,没有理由这样做。 the equality on floats makes no sense in general, and you should use abs(x) <= epsilon . 浮点数的相等性一般没有意义,你应该使用abs(x) <= epsilon

An even better way to handle this case will be: 处理这种情况的更好方法是:

bool distance(float* d)
{
    if( ! /* ... */)
        return false
    // ...
    *d=value
    return true;
}

... ...

if(distance(&d))
{
   // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM