执行两次时产生不同结果的相同浮点计算是否表示不符合 IEEE 754?

Does the same floating-point calculation producing different results when performed twice indicate IEEE 754 non-conformance?

具体在网上判断运行 32-bit GCC 7.3.0, this:

#include <iostream>

volatile float three = 3.0f, seven = 7.0f;

int main()
{
    float x = three / seven;
    std::cout << x << '\n';
    float y = three / seven;
    std::cout << (x == y) << '\n';
}

产出

0.428571
0

对我来说,这似乎违反了 IEEE 754,因为该标准要求正确舍入基本操作。现在我知道有几个原因导致 IEEE 754 浮点计算成为非确定性的,如 here 所讨论的那样,但我看不出它们如何适用于这个例子。以下是我考虑的一些事情:

这是否一定说明在线评判系统不符合IEEE 754?

此外,删除语句打印 x、添加语句打印 y 或使 y 易变都会更改结果。这似乎与我对 C++ 标准的理解相矛盾,我认为 C++ 标准需要赋值来舍入任何多余的精度。

感谢 geza 指出这是 known issue。不过,我仍然想要一个关于这是否符合 C++ 标准和 IEEE 754 的明确答案,因为 C++ 标准似乎需要赋值来舍入过高的精度。这是 N4860 草案中的引述 [expr.pre]:

The values of the floating-point operands and the results of floating-point expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.50

50) The cast and assignment operators must still perform their specific conversions as described in 7.6.1.3, 7.6.3, 7.6.1.8 and 7.6.19.

Does this necessarily indicate that the online judge system doesn't conform to IEEE 754?

是的,但有一些小警告。

第一,C++ 不能只是“符合”IEEE 754。必须有一些规范说明 C++ 中的事物如何绑定(连接)到 IEEE 754,例如声明 float 格式是 IEEE- 754 binary32,即 x / y 使用 IEEE-754 除法,依此类推。 C++ 2017 草案 N4659 引用了 LIA-1,但我没有看到它明确要求使用 LIA-1,即使 std::numeric_limits<float>::is_iec559 报告为真,并且 LIA-1 apparently only suggests language bindings.

C++ 标准告诉我们 std::numeric_limits<float>::is_iec559 报告 true 意味着 float 类型符合 ISO/IEC/IEEE 60559,这实际上是 IEEE 754-2008。但是,除了绑定问题之外,我在 C++ 标准中没有看到使 8 [expr] 13 无效的语句(“浮动操作数的值和浮动表达式的结果可能以比它更高的精度和范围表示类型需要;类型不会因此改变。”)当 is_iec559 为真时。尽管转换和转换运算符确实必须“执行它们的特定转换”(脚注 64),并且这迫使 float y = three / seven; 产生正确的 IEEE-754 binary32 结果,即使 binary64 或 Intel 的 80 位浮点用于除法,如果只使用一点点超精度,它可能不会强制它产生正确的结果。 (如果至少使用 48 位精度,则当四舍五入到 binary32 格式的 24 位时,除法不会出现双舍入错误。如果使用较少的多余位,可能会出现双舍入错误的情况。)

我相信 is_iec559 的意图是表明一种合理的绑定,而问题中显示的行为确实违反了这一点。特别地,问题中显示的缺陷是由于未能将除法中使用的多余精度四舍五入到实际的 float 类型造成的;它不是由上面提到的假设使用不够多的精度引起的。