【问题标题】:May C evaluate with multiple floating-point formats?C 可以使用多种浮点格式进行评估吗?
【发布时间】:2018-03-12 23:33:27
【问题描述】:

C 2011 [N1570] 5.2.4.2.2 9 说:

除了赋值和强制转换...,由具有浮动操作数的运算符产生的值和经过通常算术转换的值和浮动常量的值被评估为范围和精度可能大于类型要求的格式。

这是否意味着实现中的所有浮点运算都可以用一种格式进行评估,或者每个操作可以用一种格式进行评估具有更大的范围和精度?

如果A*B 以额外精度评估与A*B 以名义精度评估不同,后者将允许A*B == A*B 评估为假。

【问题讨论】:

  • @old_timer:IEEE 754 浮点乘法是可交换的。
  • @old_timer 您误解了 OP 的问题。 OP 正在询问 2 AB 是否可以不同。
  • @old_timer:IEEE 754 浮点乘法是可交换的。请不要分散注意力;它只是关于 C 语言对评估格式的要求,而不是关于浮点运算的属性。
  • @old_timer:显然,如果以不同的精度进行评估,表达式可能具有不同的值。那不是问题。问题是 C 标准是否允许使用不同的精度。
  • @liliscent:很容易构思一个可能混合精度的实现。考虑一个使用 x87 FPU 进行计算的编译器,它具有扩展的精度。 x87 FPU 在它的栈上只有 8 个空间,所以计算很容易溢出它。这将强制编译器将中间值存储到内存中,并且它可能会使用 double 而不是完整的 x87 FPU 表达式来做到这一点。 (通常,在这种情况下,我会选择将整个 x87 FPU 值存储到内存中,但在设计编译器时可能需要考虑一些复杂的因素。)

标签: c floating-point language-lawyer


【解决方案1】:

在 GCC 的 C 编译器中值得一读 the interpretation of Joseph S. Myers of the relevant parts of the standard,在 C11 5.2.4.2.2:9 中 FLT_EVAL_METHODdefinition 值得一读:

评估格式的使用的特点是 FLT_EVAL_METHOD 的实现定义值:

-1 无法确定;

0 仅根据范围和精度评估所有操作和常量 类型;

1 计算 float 和 double 类型的操作和常量 double 类型的范围和精度,计算 long double long double 的范围和精度的操作和常量 类型;

2 评估所有操作和常量的范围和精度 long double 类型。

FLT_EVAL_METHOD 定义为-1 的AC 编译器不需要对浮点计算的精度做任何特定的事情,但根据上述,将其定义为1 的编译器应该只评估float double 精度中的表达式,以及将其定义为 2 的表达式应该只计算 long double 精度中的 floatdouble 表达式。

该标准没有明确允许其他精度,也没有明确允许在编译器方便时舍入到标称精度。 (在 Joseph S. Myers 的补丁之前,GCC 正在做后者,而 x86 上的 clang -mno-sse2 -std=c99 也在做同样的事情 the last time I tried it,同时错误地将 FLT_EVAL_METHOD 定义为 0)。

根据对FLT_EVAL_METHOD 含义的这种严格解释,a * b 应该只有一个值,如果这个值不是 NaN,a * b == a * b 应该始终存在于使用定义了 @ 的编译器编译的 C 程序中987654339@ 到 0、1 或 2。

【讨论】:

  • 我认为该标准未能明确和明确这一点。
猜你喜欢
  • 2021-07-26
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 2014-05-19
  • 2011-08-08
  • 2019-09-06
  • 2010-12-31
  • 2015-06-22
相关资源
最近更新 更多