能否用!islessgreater判断非NaN浮点数a与b是否相等?
能否用C++11的
islessgreater()判断浮点数相等? 答案是可以,但得先搞清楚它的适用场景和需要注意的细节。
首先,先明确islessgreater(x, y)的行为:这个C++11标准函数会返回true当且仅当x严格小于y,或者x严格大于y。和直接写x < y || x > y相比,它的核心优势是能安全处理NaN值——不会因为操作数是NaN而触发未定义行为,这是标准库专门设计的浮点比较函数的特性。
回到你的问题:要判断float a == float b,你的示例代码逻辑是完全正确的:
#include <iostream> #include <cmath> using namespace std; int main() { float a = 1E-10; float b = 1.001E-10; bool res = !isnan(a) && !isnan(b) && !islessgreater(a, b); std::cout << std::boolalpha; if (res) std::cout << "a == b" << endl; else std::cout << "a != b" << endl; return 0; }
这里的逻辑可以拆解为两步:
!isnan(a) && !isnan(b):必须先排除NaN的情况,因为NaN不等于任何值(包括它自己)。如果跳过这一步,当a或b是NaN时,!islessgreater(a,b)会返回true,直接导致错误的判断结果。!islessgreater(a, b):取反后就表示a既不小于b也不大于b,对于非NaN的浮点数来说,这就等价于a == b。
几个关键注意事项:
- 这是精确相等的判断:和我们平时常用的“近似相等”(比如判断两个数的差值小于某个epsilon)不同,这个方法只会在两个浮点数的二进制表示完全相同时返回
true。如果你的需求是判断两个浮点数是否在可接受的误差范围内相等,那这个方法不适用,还是得用差值比较的方式。 - 编译器版本要求:
islessgreater是C11引入的,所以要确保你的编译器支持C11及以上标准,编译时可能需要添加-std=c++11(或更高版本,比如-std=c++17)的编译参数。 - NaN处理是硬性要求:一定要先检查两个数都不是NaN,否则会得到违背常识的结果——比如
islessgreater(NAN, 0.0f)会返回false,取反后是true,但NaN和0.0f显然不相等。
举个精确相等的例子:如果把代码里的b改成1E-10,那么islessgreater(a,b)会返回false,取反后res为true,程序会输出a == b,完全符合预期。
总的来说,如果你的需求是判断两个非NaN浮点数的精确相等,那么这个方法是完全符合C++11标准且安全的;但如果是近似相等的场景,还是得用传统的误差范围判断方式。
内容的提问来源于stack exchange,提问作者James Liu
相关产品推荐
相关产品推荐

