【问题标题】:Is the output of a c++ program with floating point predictable? [duplicate]具有浮点的 c++ 程序的输出是否可预测? [复制]
【发布时间】:2019-04-04 17:15:18
【问题描述】:

我的 C++ 程序计算一些浮点数 x 并打印出来:

cout << x;

对我来说重要的是所有计算机的输出都相同。由于“所有”的含义非常广泛,所以让我们重点关注以下内容:

  • g++ 6/7/8、clang++ 5/6 中的不同编译器;
  • 不同的 Linux 系统 - Ubuntu 16.04/18.04;
  • 独立 Linux 与 Windows 子系统 Linux;
  • 不同的硬件 - Intel 与 AMD 的不同规格。

上述所有组合的输出是否保证相同?

如果不是,我可以通过降低精度来保证相同的输出,例如:

cout << setprecision(4) << x;

?如果没有,我还能做些什么来在机器之间获得一致的输出?

【问题讨论】:

  • printf with %.xf
  • 浮点数学就是要快速。获得精确指定的结果并不快。 Java 试图要求所有实现对double 使用 IEEE 64 位浮点;严重的用户反抗,因为它太慢了(英特尔硬件针对 80 位计算进行了调整,而 64 位双精度数扩大到 80 位进行计算),Java 现在有没有人使用的“严格”数学,以及严肃的普通数学FP 的人使用。
  • @Erel 我认为不能保证 跨平台 获得一致的结果,但这最终取决于浮点值的表示方式底层 FPU 架构。结论:永远不要依赖一致的 FP 表示。请改用 epsilon 近似
  • 这个问题是关于cout 是否保证在所有这些不同的系统上每次都以完全相同的方式打印完全相同的float,还是这个问题包括x 是否会被计算出来的所有值都完全相同?如果是后者,我们必须知道x 是如何计算的。但是,我已经可以告诉你,在这种情况下,答案几乎肯定是:不。

标签: c++ floating-point cross-platform precision


【解决方案1】:

上述所有组合的输出是否保证相同?

没有。

C++ 标准很少保证浮点表示。

我可以通过降低精度来保证相同的输出吗,例如:

cout << setprecision(4) << x;

没有。

如果计算的准确结果恰好在舍入方向的边界,那么计算之间的任意小差异都可能改变结果。四舍五入会放大计算之间的差异。

如果不是,我还能做些什么来在机器之间获得一致的输出?

  • 使用非硬件浮点数。软件浮点或定点算法。
  • 要么使用固定宽度的整数来实现该算法,这样一个系统就不会比另一个系统具有更高的精度,要么使用任意精度。
  • 如果不使用任意精度,则仅使用其评估顺序由语言定义的表达式,这样编译器之间的差异不会导致不同数量的错误。

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2023-03-29
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多