【问题标题】:Is imprecision of a double value guaranteed to be consistent on the same machine?双精度值的不精确性是否保证在同一台机器上保持一致?
【发布时间】:2016-04-13 17:01:08
【问题描述】:

我们知道doubles 会随着您增加小数点数而降低其值的精度。但是,如果我在同一台机器上两次使用相同的 double 值,我是否会保证具有相同的不精确性?例如:

double d1 = 123.456;//actually becomes 123.45600001
double d2 = 123.456;//is guaranteed to become 123.45600001?

为简单起见,我们只使用 C++。

【问题讨论】:

  • 大多数 C++ 实现符合 IEEE 浮点标准。所以,是的。
  • @callyalater,不,它没有。
  • @SergeyA 你是对的。我的意思是说most implementations are
  • 请注意,比较从相同文字初始化的两个值的答案与比较从任何其他来源初始化的两个值的答案非常不同。 .2 几乎永远不会等于 .1+.1
  • 当精确相等很重要时,我有时会尝试通过只创建一次值并在各个地方引用它来避免这个问题,即使我必须将其设为全局。当然,这样做的决定将取决于整个程序的各种细微差别。

标签: c++ floating-point double floating-accuracy


【解决方案1】:

不,您没有此保证。 C++ 实现不受 IEEE 标准约束,可以选择任何他们想要的二进制表示。

虽然他们不太可能只是自己发明,但他们通常会在如何表示“不可表示”的数字方面存在波动(即使在同一供应商内部)——它们可以用更大或更小的数字表示——而这种表示变化(我相信,即使是 same gcc 的不同浮动数学选项也会影响这一点。

【讨论】:

  • 我很确定 d1 在 OP 的示例中必须等于 d2。我不认为你可以有一个实现将相同的文字转换为两个不同的值。这是真的,虽然123.456 不必等于123 + .456
  • @NathanOliver,我并没有从字面上理解这个问题,而是认为那里的那些等式只是为了说明。然而,不难想象实现这两个变量的比较不同 - 想象它使用一个 FPU 芯片,它根据随机值向上或向下舍入 - 以减少偏差/
  • 随机舍入不是允许的 IEEE 754 舍入模式之一。它们是:1. 舍入到最近,连到偶数,2. 舍入到最近,从零开始,3. 向零舍入,4. 向 +∞ 舍入,5. 向 -∞ 舍入 在所有这些模式中,四舍五入当两个值与给定值距离相等时应用。在任何情况下,编译器都不应选择比另一个合法值更远离给定十进制常量的表示形式。
  • @SteveHollasch,但 C++ 实现不需要遵循 IEEE 标准。
【解决方案2】:

在您的情况下,d1 == d2 将返回 true,并且它几乎在任何正常运行的编译器/架构上总是返回 true。即使编译器/架构不符合 IEEE 标准,为 123.456 提供相同的符号也极不可能在多次调用时返回不同的值。

但是,如果您有以下代码:

double d1 = 123.456;
double d2 = get_123_456_from_network_service(service);

这种保证将不复存在。 123.456 在您的计算机上始终完全相同,但如果另一台计算机尝试使用相同的符号,并且不符合 IEEE(或者如果您的不符合),那么这些值很有可能会与众不同。

【讨论】:

    【解决方案3】:

    如果您的编译器符合 IEEE 754 (IEC 559) 标准,它们应该是相同的。您可以检查它是否符合 IEEE 与 std::numeric_limits<T>::is_iec559。大多数实现都符合 IEEE 标准,但这不是保证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 2017-01-19
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多