C++ c+中的浮点比较+;11

C++ c+中的浮点比较+;11,c++,c++11,floating-point,C++,C++11,Floating Point,我习惯于将浮点与以下函数进行比较。 但是,我只是检查一下c++11是否提供了一些浮点比较函数,如isgreaterequal。 我的问题是我是否应该用标准中的函数替换它 bool isEqual(double lhs, double rhs, double epsilon = /std::numeric_limits<double>::epsilon()) { if (lhs == rhs) { return true; } retu

我习惯于将浮点与以下函数进行比较。 但是,我只是检查一下c++11是否提供了一些浮点比较函数,如
isgreaterequal
。 我的问题是我是否应该用标准中的函数替换它

bool isEqual(double lhs, double rhs, double epsilon = /std::numeric_limits<double>::epsilon())
{
    if (lhs == rhs)
    {
        return true;
    }

    return fabs(lhs - rhs) <= ( (fabs(lhs) > fabs(rhs) ? fabs(rhs) : fabs(lhs)) * epsilon);
}
bool isEqual(双左、双右、双ε=/std::numeric_limits::epsilon())
{
如果(lhs==rhs)
{
返回true;
}
返回晶圆厂(lhs-rhs)晶圆厂(rhs)?晶圆厂(rhs):晶圆厂(lhs))*epsilon;
}
根据:

使用
isgreaterequal
,如果任一参数为
NaN
,则比较结果为false

使用
=
,如果任一参数为
NaN
,则将引发
FE\u INVALID
异常

因此,我认为您应该保持函数的原样,因为您可能想知道您的参数之一是否为
NaN


p、 516第F.9.3节关系运算符

x, ≥) 虽然数字 相等,由于副作用,这些表达式不相等 当x或y为NaN且FENV_访问布拉格的状态为 “”上的“”。此转换,如果需要额外的代码 是导致“”的“”无效“”浮点异常所必需的 无序的情况下,可以执行,前提是 FENV_ACCESS pragma处于“关闭”状态

根据:

使用
isgreaterequal
,如果任一参数为
NaN
,则比较结果为false

使用
=
,如果任一参数为
NaN
,则将引发
FE\u INVALID
异常

因此,我认为您应该保持函数的原样,因为您可能想知道您的参数之一是否为
NaN


p、 516第F.9.3节关系运算符

x, ≥) 虽然数字 相等,由于副作用,这些表达式不相等 当x或y为NaN且FENV_访问布拉格的状态为 “”上的“”。此转换,如果需要额外的代码 是导致“”的“”无效“”浮点异常所必需的 无序的情况下,可以执行,前提是 FENV_ACCESS pragma处于“关闭”状态


无论如何,这不是比较浮点数的正确方法。首先,它以增加误报为代价来减少误报。其次,在缺乏前面计算的具体知识的情况下,没有理由期望误差与左侧成比例。第三,单个误差ε是不寻常的对于除最简单的计算以外的任何计算。第四,错误容忍度存在巨大的不连续性;当
lhs
下降到
rhs
以下时,容忍度从几乎
rhs*epsilon
跳到
rhs
,增加了约2**52。@EricPostchill 1。这是有限精度算法。2-3。因此
epsilon
i这是一个可变参数。4.检查参数;
lhs
rhs
中较小的一个乘以
epsilon
@Potatoswatter:4.你是对的。1.精度是有限的这一事实并不意味着这是正确的。应该使用其他方法。2:传递非默认值epsilon不会改变它是s乘以以与比较的值成比例。3:默认值太小。无论如何,这不是比较浮点数的正确方法。首先,它以增加误报为代价来减少误报。其次,在缺乏前面计算的具体知识的情况下,没有理由期望错误to与左手边成比例。第三,除了最简单的计算外,一个误差ε对于任何计算都是不寻常的。第四,误差容差存在巨大的不连续性;当
lhs
下降到
rhs
以下时,容差从几乎
rhs*epsilon
跳到
rhs
,大约增加2**52。@EricPostpischil 1.这是有限精度的算术。2-3.因此,
epsilon
是一个可变参数。4.检查参数;
lhs
rhs
中较小的一个乘以
epsilon
@Potatoswatter:你大约是对的。1:精度是有限的事实并不说明这是正确的。其他方法应该e使用。2:传递非默认值epsilon不会改变它与比较的值成比例相乘的事实。3:默认值太小。
的规范isgreaterequal
等人说,
FE\u INVALID
=
提出,但它不是指定
=/code>的正确位置。在我在英特尔
FE_INVALID
上的经验从未从NaN中产生过,但我甚至不知道C在哪里指定可以提高它。最多,依赖信令比较是不可移植的。显示了同样的事情,但我要测试它。好的,我测试了它,没有出现异常。我只使用C11规范,草案出版物N1570。谢谢,我在上找到了它。
的规范isgreaterequal
等人说
FE\u INVALID
是由
=
提出的,但它不是指定
=
的正确位置。根据我的经验,在英特尔
上,FE\u INVALID
从来都不是由NaN产生的,但我看不到C甚至指定它可能被提出的地方。最好的情况是依赖信号比较是不可移植的。显示了相同的内容,但我要测试它。好的,我测试了它,没有出现异常。我只是按照C11规范,草案出版物N1570。谢谢,我在上找到了它。