【发布时间】:2015-05-14 16:15:59
【问题描述】:
我了解浮点数存在舍入错误,但我想知道是否存在不适用该错误的某些情况,例如乘以零。
零乘以任何数字是否等于所有浮点数为零?
【问题讨论】:
-
除了像 NaN、Infinity 或 -Infinity 这样的特殊值之外,您可以正确地假设任何正常数乘以精确的零产生精确的零。
标签: c++ c floating-point
我了解浮点数存在舍入错误,但我想知道是否存在不适用该错误的某些情况,例如乘以零。
零乘以任何数字是否等于所有浮点数为零?
【问题讨论】:
标签: c++ c floating-point
错误:
0f * NAN == NAN
0f * INFINITY == NAN
和...
0f * -1f == -0f (negative 0f), with 0f == -0f :-)
(在 Intel、VC++ 上,并且可能在任何使用 IEEE 754-1985 浮点的平台上)
ideone 上的示例(可能在某些 Intel 兼容平台上使用 GCC)
【讨论】:
0f == -0f的意义上仍然是"0",但是例如如果将-0f * INFINITY相乘并打印结果,则得到-NaN,所以它仍然是@987654329 @ 但它的符号可以使用/提取。 ideone.com/L6MQlQ
–NaN 这样的东西,–0 * inf 也不能保证产生“–NaN”(它可以产生任何安静的 NaN 值) .不过,–0 的符号位可以通过其他方式提取。
**and print the result**, you obtain",在英特尔上的 GCC 上该操作的打印结果是...... :-)
0 的符号:1./0. => Infinity 和 1./-0. => -Infinity。还要注意f 数字后缀:它指定float 值,而不是double。
除了@xanatos 很好的答案,考虑一下 OP 的一些中间问题:
我想知道是否在某些情况下(舍入)错误不适用
候选人包括some_double_y = some_double_x * 1.0 和some_double_y = some_double_x + 0.0 可能永远不会产生舍入错误。
然而,考虑到FLT_EVAL_METHOD == 2,其中“将所有操作和常量评估为long double 类型的范围和精度”,编译器可能会以更高的精度评估double。在这种情况下,中间的some_double_x 可能以long double 的形式存在,与0.0 或1.0 的明显double 值不同。
【讨论】:
double x = some_small_double(); if (x / 1.0e300) ... 可能会或可能不会采用if() 路径。使用 double 数学计算的 x / 1.0e300 肯定是 +/-0.0。使用long double 数学计算的x / 1.0e300(即使操作数都是double)可能是一个非零数。
-0.0 不同于加零。 -0.0 + 0.0 通常有 +0.0 的总和。 Sometimes 差异很重要。我认为 *1 通常是无操作的,但如果是无操作的,为什么要编码呢?