何时使用 C 浮点比较函数
When to use C float comparison functions?
在最新的C++标准中,我注意到以下宏:
bool isgreater(float x, float y);
bool isgreaterequal(float x, float y);
bool isless(float x, float y);
bool islessequal(float x, float y);
bool islessgreater(float x, float y);
bool isunordered(float x, float y);
这些宏来自 C(7.12.14 和 7.12.14)。
那么,为什么有人会使用这些宏而不是运算符呢?这些宏有什么特别之处(例如检查inf
),还是它们与相应的运算符相同?
C++示例:
#include <iostream>
#include <cmath>
int main()
{
float x=0.2;
float y=0.5;
std::cout << x << " < " << y << " : " << std::boolalpha << std::islessequal( x, y ) << std::endl;
std::cout << x << " < " << y << " : " << std::boolalpha << ( x <= y ) << std::endl;
}
与关系运算符不同,这些宏实际上只返回布尔值,并且从不引发任何浮点异常。
简而言之:您只需要处理true
/false
,而不需要其他任何事情。
参考资料:
开放组的描述(不是C或C++标准,但在Unix/Linux世界中高度相关,几乎总是与标准相似):
- http://pubs.opengroup.org/onlinepubs/009695399/functions/islessgreater.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/isgreater.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/isgreaterequal.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/isless.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/islessequal.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/islessgreater.html
- http://pubs.opengroup.org/onlinepubs/009695399/functions/isunordered.html
C++标准:
C 库 [c.math]:
分类/比较函数的行为与 C 标准中 7.12.3 分类宏和 7.12.14 比较宏中定义的相应名称的 C 宏相同。对于三种浮点类型,每个函数都重载,如下所示 [...]
C标准:
7.12.14 比较宏
[...]对于任何有序的数值对,恰好是其中之一 关系——更少、更大、平等——是真实的。关系运算符可能会提高 参数值为 NaN 时的浮点异常"无效"。对于 NaN 和 数值,或者对于两个 NaN,只有无序关系为真。 以下子句提供了关系运算符的安静(非浮点异常引发)版本的宏,以及其他有助于编写考虑 NaN 的高效代码而不会遭受"无效"浮点异常的比较宏。在 本子句中的提要,实浮表示该论点应为 真实浮型的表达式。
isgreater
等人从C99并入C++11。 它们被定义为在x
和/或y
发出NaN
值信号时不引发无效的浮点异常。
给出的理由是:
此宏是关系运算符的安静(非浮点异常引发)版本。它有助于编写考虑 NaN 的高效代码,而不会遭受无效的浮点异常。
NaN
上的宏的数值与往常相同; NaN
值将 false 与所有其他值进行比较,包括所有关系运算符和新宏下的NaN
值。
- C++自定义比较函数
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- 为什么 std::stable_sort() 的比较函数的参数必须是设置常量?
- 如何定义集合数组的比较函数?
- 根据比较函数C++对数组进行排序
- 使用自定义比较函数在类内进行列表排序
- 如何更改 std::set 的比较函数?
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果
- std::映射服装比较函数和函数/lambda错误
- 在C++排序中为比较函数指定参数
- 使用右值的比较函数
- 为什么比较函数类型需要指定为模板参数?
- 我应该将 lambda 或函子用于比较函数吗?
- 比较函数模板中的 VARTYPE 和 typeid().name / typename
- 如何键入定义一个专门的 std::set 模板,使用特定的比较函数实例化
- 无法在 std::sort 中使用 cdef 函数作为比较函数
- 关联容器,比较函数不是元素类型的一部分吗?
- 标准::lower_bound的比较函数
- 关于如何在 std::sort 和 std::p riority_queue 中使用自定义比较函数的困惑