gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 10:14:42 25 4
gpt4 key购买 nike

在运行 32 位 GCC 7.3.0 的特定在线判断中,这个:

#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 ,但我看不出它们中的任何一个如何应用于此示例。以下是我考虑的一些事情:
  • 过度精确和收缩:我正在做一个计算并将结果分配给 float ,这应该强制将两个值四舍五入为 float精确。
  • 编译时计算:threesevenvolatile所以这两个计算都必须在运行时完成。
  • 浮点标志:计算是在同一个线程中几乎紧随其后完成的,所以标志应该是相同的。

  • 这是否必然表明在线评判系统不符合 IEEE 754?

    此外,删除声明打印 x ,添加语句打印 y , 或制作 y volatile all 改变结果。这似乎与我对 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++ 中的事物如何绑定(bind)(连接)到 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。但是,除了绑定(bind)问题,我在 C++ 标准中没有看到使 8 [expr] 13 无效的语句(“ float 操作数的值和 float 表达式的结果可能以比这更高的精度和范围表示类型需要;类型不会因此而改变。”) 当 is_iec559是真的。尽管强制转换和转换运算符确实必须“执行它们的特定转换”(脚注 64),但这会强制 float y = three / seven;为了产生正确的 IEEE-754 binary32 结果,即使使用 binary64 或 Intel 的 80 位浮点进行除法,如果只使用了一点额外的精度,它可能不会强制它产生正确的结果。 (如果使用至少 48 位精度,则在舍入到 binary32 格式的 24 位时,除法不会出现双舍入错误。如果使用的多余位较少,可能会出现双舍入错误。)

    我相信 is_iec559 的意图是表示一个合理的绑定(bind),问题中显示的行为确实违反了这一点。特别是,问题中显示的缺陷是由于未能将除法中使用的超额精度四舍五入到实际 float类型;它不是由上述假设使用的过度精度不足引起的。

    关于c++ - 执行两次时产生不同结果的相同浮点计算是否表明不符合 IEEE 754?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62353629/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com