我有一个算术表达式,例如:
float z = 8.0
float x = 3.0;
float n = 0;
cout << z / (x/n) + 1 << endl;
为什么我得到等于 1 的正常答案,而它应该是“nan”、“1.#inf”等?
我有一个算术表达式,例如:
float z = 8.0
float x = 3.0;
float n = 0;
cout << z / (x/n) + 1 << endl;
为什么我得到等于 1 的正常答案,而它应该是“nan”、“1.#inf”等?
我假设您正在使用浮点运算(尽管无法确定,因为您没有告诉我们)。
IEEE754 浮点语义适用于扩展实数线,并在两端包括无穷大。这使得对于任何(非 NaN)分母的非零分子除法都得到了很好的定义,“符合”(即连续扩展)通常的算术规则:x / n
无穷大,z
除以无穷大为零——就像你已经简化了一样表达式为n * z / x
。
唯一真正未定义的量是 0/0 和 inf/inf,它们由特殊值 NaN 表示。
IEEE 754 指定3/0 = Inf
(或任何积极的而不是 3)。 8/Inf
给出 0。如果你加 1,你会得到 1。这是因为0
表示“0 或非常接近它的东西”和Inf
“无穷大或非常大的数字”。它还允许对限制执行一些操作,因为它有效地将实数扩展到无穷大。NaN
当限制无法实现(或通过简单的实现不容易计算)时, 's 被保留。
作为副作用,您会产生一些奇怪的效果,例如0 == -0
but1/0 == Inf
和1/-0 == -Inf
. 重要的是要记住 FP 算术是不正常的 - 例如cos(x) * cos(x) + sin(x) * sin(x) - 1 != 0
即使x != NaN && x != Inf && x != -Inf
. 对于浮点数,x == 1
结果是-5.9604645e-8
. 因此,并非所有期望都可以轻松转移到它 - 在这种情况下例如除以 0。
虽然 C/C++ 不要求 IEE 754 规范将用于浮点数,但它是目前的规范,并且几乎可以在任何硬件上实现,因此大多数 C/C++ 实现都使用该规范。