为什么浮点数与无穷大的比较有效?
Why does comparison of floating-point to infinity work?
任何知识渊博的人都知道,您无法使用简单的逻辑运算符比较两个浮点数并期望得到逻辑结果。
那么,为什么当数字实际上是 INFINITY
时,与 INFINITY
的逻辑 EQUAL TO 比较总是 return 为真?
PS: 我尝试了与 NAN
相同的比较,但似乎只有 INFINITY
可以可靠地检测为等于另一个相同值的数字。
(编辑)这是我的实现(GCC)对 INFINITY
和 NAN
的定义:
# define INFINITY (__builtin_inff ())
# define NAN (__builtin_nanf (""))
You cannot compare two floating-point numbers with simple logic operators and expect a logical result.
比较两个浮点数存在陷阱,因为由于缺乏精度而导致舍入误差,它们可能与您的预期不完全相同。有时,一个数字非常接近但不完全符合我们的预期。这就是导致问题的原因。
此问题不适用于 +Inf。 +Inf 不会意外地存储为非常接近 +Inf 的某个数字。 +Inf 是一个特定的位模式。这不是 INT_MAX 之类的东西;这是处理器本身的特殊值。
-Inf 也一样。
As anyone knowledgeable enough will know, you cannot compare two floating-point numbers with simple logic operators and expect a logical result.
这在 IEEE 754 标准或我所知道的任何其他浮点行为规范中没有任何依据。不幸的是,这是浮点运算的常见错误陈述。
事实上,相等性比较是浮点数中的完美运算:当且仅当两个操作数表示相同的数字时,它才会产生 true。平等比较永远不会有任何错误。
另一种错误说法是浮点数近似于实数。根据 IEEE 754,除 NaN 之外的每个浮点值都代表一个数字,并且它准确地代表该数字。
事实是浮点数字是精确的,而浮点运算近似于实数;正确舍入的操作会产生最接近的可表示值(在任何方向或选定方向上最接近,具有各种关系规则)。
这种区别对于理解、分析、设计和编写有关浮点运算的证明至关重要。
Why then, does a logical EQUAL TO comparison to INFINITY always return true when the number is, in fact, INFINITY?
如上所述,当且仅当其操作数表示相同的数字时,相等性比较才会产生 true。如果 x
为无穷大,则 x == INFINITY
returns 为真。如果 x
为三,则 x == 3
returns 为真。
人们有时 运行 会因为不明白数字中的值而陷入困境。例如,在 float x = 3.3;
中,人们有时没有意识到 C 将 double
3.3
转换为 float
,因此 x
不包含与 x
相同的值3.3
。这是因为转换操作近似于其结果,而不是因为 x
的 value
不是其特定赋值。
I tried the same comparison with NAN
,…
NaN 不是一个数字,因此,在比较相等时,它永远不会满足“两个操作数表示相同的数字”,因此比较结果为 false。
任何知识渊博的人都知道,您无法使用简单的逻辑运算符比较两个浮点数并期望得到逻辑结果。
那么,为什么当数字实际上是 INFINITY
时,与 INFINITY
的逻辑 EQUAL TO 比较总是 return 为真?
PS: 我尝试了与 NAN
相同的比较,但似乎只有 INFINITY
可以可靠地检测为等于另一个相同值的数字。
(编辑)这是我的实现(GCC)对 INFINITY
和 NAN
的定义:
# define INFINITY (__builtin_inff ())
# define NAN (__builtin_nanf (""))
You cannot compare two floating-point numbers with simple logic operators and expect a logical result.
比较两个浮点数存在陷阱,因为由于缺乏精度而导致舍入误差,它们可能与您的预期不完全相同。有时,一个数字非常接近但不完全符合我们的预期。这就是导致问题的原因。
此问题不适用于 +Inf。 +Inf 不会意外地存储为非常接近 +Inf 的某个数字。 +Inf 是一个特定的位模式。这不是 INT_MAX 之类的东西;这是处理器本身的特殊值。
-Inf 也一样。
As anyone knowledgeable enough will know, you cannot compare two floating-point numbers with simple logic operators and expect a logical result.
这在 IEEE 754 标准或我所知道的任何其他浮点行为规范中没有任何依据。不幸的是,这是浮点运算的常见错误陈述。
事实上,相等性比较是浮点数中的完美运算:当且仅当两个操作数表示相同的数字时,它才会产生 true。平等比较永远不会有任何错误。
另一种错误说法是浮点数近似于实数。根据 IEEE 754,除 NaN 之外的每个浮点值都代表一个数字,并且它准确地代表该数字。
事实是浮点数字是精确的,而浮点运算近似于实数;正确舍入的操作会产生最接近的可表示值(在任何方向或选定方向上最接近,具有各种关系规则)。
这种区别对于理解、分析、设计和编写有关浮点运算的证明至关重要。
Why then, does a logical EQUAL TO comparison to INFINITY always return true when the number is, in fact, INFINITY?
如上所述,当且仅当其操作数表示相同的数字时,相等性比较才会产生 true。如果 x
为无穷大,则 x == INFINITY
returns 为真。如果 x
为三,则 x == 3
returns 为真。
人们有时 运行 会因为不明白数字中的值而陷入困境。例如,在 float x = 3.3;
中,人们有时没有意识到 C 将 double
3.3
转换为 float
,因此 x
不包含与 x
相同的值3.3
。这是因为转换操作近似于其结果,而不是因为 x
的 value
不是其特定赋值。
I tried the same comparison with
NAN
,…
NaN 不是一个数字,因此,在比较相等时,它永远不会满足“两个操作数表示相同的数字”,因此比较结果为 false。