何时使用 C 浮点比较函数?

Posted

技术标签:

【中文标题】何时使用 C 浮点比较函数?【英文标题】:When to use C float comparison functions? 【发布时间】:2012-08-06 10:15:16 【问题描述】:

在最新的 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;

【问题讨论】:

【参考方案1】:

与关系运算符不同,这些宏实际上只返回一个布尔值,从不引发任何浮点异常。

简而言之:您只需要处理 true/false 即可。


参考文献

The Open Group 描述(不是 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 而不会遭受“无效”浮点异常。在 本小节中的概要,实浮点数表示参数应为 真正的浮动类型的表达式。

【讨论】:

即除了相当无用的isunordered 之外,我们仍然没有std::set&lt;float&gt; 的有效谓词。 (见***.com/questions/4816156/…为什么) @MSalters:我也喜欢宏,不合适。 这不是宏问题(它们甚至不是 C++ 中的宏)。这些函数未能为NaN 定义严格的弱排序。他们只是删除了异常,但这并没有使结果足够有用。 是的,错过了关于 C++ 中的函数的部分:P 但我也意识到了排序问题。【参考方案2】:

isgreater 等。从 C99 并入 C++11。当x 和/或y 发出NaN 值时,它们被定义为不会引发无效的浮点异常。

给出的理由是:

此宏是关系运算符的安静(非浮点异常引发)版本。它有助于编写有效的代码来解释 NaN,而不会遭受无效的浮点异常。

NaN上的宏的数值和往常一样; NaN 值与所有其他值比较 false,包括所有关系运算符和新宏下的 NaN 值。

【讨论】:

以上是关于何时使用 C 浮点比较函数?的主要内容,如果未能解决你的问题,请参考以下文章

关于浮点型误差的解决方法

C:无序浮点比较不会引发 FE_INVALID

php随机浮点数都有哪些?比如从0.1到3.0中随机一个浮点数出来?

C语言字符串类型转换为整型或浮点怎么做

宏和函数的比较(C/C++)

何时使用 trunc() 而不是 int() 将浮点类型数转换为整数更好?