这个与浮点数字的比较是否有效? [英] Is this comparison to floating point literal zero valid?

查看:100
本文介绍了这个与浮点数字的比较是否有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从N3337(C ++ 11草稿)第3.9.1.8节:

From N3337 (C++11 draft) section 3.9.1.8:


浮点类型的值表示形式是implementation-

The value representation of floating-point types is implementation-defined.

这是否适用于float类型的任何和所有用法,不管它是否是字面值?这是导致我一些关注的例子:

Does this apply to any and all usage of a float type, regardless of if it is a literal or not? Here is the example that is causing me some concern:

float foo{0.0f};
if (foo == 0.0f)
{
    // Am I always guaranteed to get here?
}

如果我们假设 0.0f 对于实现并不真正为真,但是一些未定义的数字,这个比较在技术上是否仍然有效,因为两个操作数都是通过常量获得的,即使我不知道它的真实值,他们仍然是相同的吗?

If we assume that 0.0f is not really true 0 as far as the implementation is concerned, but some undefined number, would this comparison still technically be valid since both operands were obtained via constants and even though I may not know its true value, they will both still be the same?

与这样的浮点文字的平等比较总是有代码气味,我只是想确保没有某些用例,这是有意义的,

Equality comparisons with float literals like this always have a code smell and I just want to make sure there aren't certain use cases where this makes sense or is valid.

推荐答案

是的,你有保证到那里。浮点不精确在对相关数字进行处理操作后发生。

Yes you are guaranteed to get there. Float imprecision occures after processing operations on concerned numbers. Constants are safe in your case.

但是,如果通过提供太多的小数来超过浮点数精度或者使用另一种数据类型初始化浮点数,它可能会得到解释不同。

However, if you exceed floating-point number precision by providing too much decimals or you initialize the float with another data type, it might get interpreted differently.

例如,这可能不会:

float foo{2.1234321f};
if (foo * 6.1234321f / 0.1234321f == 105.3428750f)
{
    // Am I always guaranteed to get here? Not at all.
}

如果你想比较浮点数时是安全的,近似的结果。请参阅下面的代码。

If you want to be safe when comparing floating-point numbers, you should "approximate" the result. See the code below.

#include <limits>
#include <type_traits>

using namespace std;

class exact{};
class approx{};

template<class> struct tolerance;

template<>
struct tolerance<float>
{
    static constexpr float value() { return 0.00001; }
}

template<class T>
bool close_enough(T a, T b, exact)
{
    return a == b;
}

template<class T>
bool close_enough(T a, T b, approx)
{
    return abs(a - b) <= tolerance<T>::value();
}

template<class T>
bool close_enough(T a, T b)
{
    return close_enough(a, b,
        conditional<numeric_limits<T>::is_exact, exact, approx>::type{});
}

int main()
{
    float a = 2.1234321f, b = 105.3428750f;

    if (close_enough(a * 6.1234321f / 0.1234321f, b))
    {
        // Am I always guaranteed to get here? Yes!
    }
    else
    {
        // ...
    }
}

这篇关于这个与浮点数字的比较是否有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆