Python C++ float 学表示错误

标签 python c++ floating-point

在 C++ 中,

double x = 1.0; 
double y = x / 3.0; 
if (x == y * 3.0)
  cout << " They are equal!" ; 
else
  cout << " They are NOT equal." ;

将打印

‘They are NOT equal.’ 

正如预期的那样,由于 1/3 的非精确表示为有限大小尾数的(二进制)数。 但是在 Python 中(在 https://repl.it/repls/MessyJaggedMouse 上),

x = 1.0
y = x / 3.0
x == y * 3.0

打印

True

Python 何时以及为何偏离上述预期行为?编辑:Python 不会离开 - 请参阅下面我的回答。

最佳答案

只有当我在 C 中使用 x87 数学时才会发生这种情况。

正确舍入,使用 IEEE 754 double 运算,您将得到 true

但是,如果您以更高的精度计算中间值,则可能会得到 false。 C 不需要以 64 位精度计算所有中间值,并且在具有 x87 浮点指令的 32 位 x86 处理器上,您最终将使用较大的 80 位浮点类型作为中间值。根据启用的优化设置和编译器的详细信息,计算将以不同的方式完成(使用不同的中间值),您将得到略有不同的结果。

#include <cstdio>

int main() {
  double x = 1.0;
  double y = x / 3.0;
  std::printf("x == y * 3.0: %s\n", x == y * 3.0 ? "true" : "false");
  return 0;
}

使用 GCC,如果使用 -mfpmath=387 -O0 编译,我会看到 false。如果我在没有 -mfpmath=387 的情况下进行编译(在 AMD64 上这将默认为 SSE 而不是)或者如果我使用 -O2 进行编译,我会看到 true

您可以在 GodBolt 上使用 x87 指令查看它是如何编译的:https://godbolt.org/z/rf1Rir -- 尝试添加 -O2 或删除 -mfpmath=387 以查看它如何影响生成的代码。

请注意,(1.0/3.0) * 3.0 == 1.0 有点巧合。您可以在 Python 中测试以下代码,例如:

1.0 / 49.0 * 49.0 == 1.0

这应该给出 False

关于Python C++ float 学表示错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54424331/

相关文章:

python - 具有多个值的属性 setter

c++ - 卷积网络过滤器始终为负

c - 添加浮点值不正确

python - 替换 Beautiful Soup 中的所有智能引号

python - 如何从模板调用模型函数?

c++ - 你能解释一下下面多种操作数的混合吗? (C++)

c++ - 为什么使用 double 然后转换为 float?

sql - Oracle 中的数字精度

python - requests_cache 是否会在信息更新时自动更新缓存?

c++ - 使用 C 或 C++ 可以进行异步编程吗?