在最新的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;
}
答案 0 :(得分:38)
与关系运算符不同,这些宏实际上只返回一个布尔值,并且不会引发任何浮点异常。
简而言之:您只需处理true
/ false
而无需处理任何其他内容。
引用:
Open Group 描述(不是C或C ++标准,但在Unix / Linux世界中高度相关,几乎总是与标准类似):
C ++ 标准:
C Library [c.math]:
分类/比较函数的行为与C宏相同,其中相应的名称在7.1标准中的7.12.3,分类宏和7.12.14,比较宏中定义。对于三种浮点类型,每个函数都被重载,如下[...]
C 标准:
7.12.14比较宏
[...]对于任何有序的数值对,恰好是其中之一 关系 - 更少,更大,更平等 - 是真实的。关系运营商可能会提升 当参数值为NaN时,''invalid''浮点异常。 对于NaN和a 数值,或两个NaN,只是无序关系是真的。 以下子条款提供了关系运算符的安静(非浮点异常提升)版本的宏,以及其他比较宏,这些宏有助于编写有效代码来解释NaN而不会遇到“无效”浮点异常即可。在 本子条款中的概要,real-floating表示参数应为a 真实浮动类型的表达。
答案 1 :(得分:13)
isgreater
等。从C99合并到C ++ 11中。它们被定义为在x
和/或y
发出NaN
值信号时不会引发无效的浮点异常。
给出的理由是:
此宏是关系运算符的安静(非浮点异常提升)版本。它有助于编写考虑NaN的高效代码,而不会遇到无效的浮点异常。
NaN
上的宏的数值与始终相同; NaN
值将false与所有其他值(包括所有关系运算符和新宏下的NaN
值)进行比较。