C float直译

C float literal translation

我们有两个嵌入式项目:一个使用 cosmic 编译器,另一个使用 GCC。两者都遵守 ISO/IEC 9899:1990.

当我们用文字 14.8f 初始化浮点数时,它在 cosmic 编译器上被翻译成 0x416CCCCC 的二进制表示,GCC 被翻译成 0x416CCCCD

第 6.3.1.4 章第 2 项浮动类型 中的 IEC 标准指出:

If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower value, chosen in an implementation-defined manner.

因为我们使用这些数字作为阈值,这显然会有所不同。

cosmic 编译器声明它使用向下舍入实现。
由于 GCC 相当复杂,我想知道它是否有一个允许在编译时选择行为的编译器标志。到目前为止我只发现你可以选择 FE_DOWNWARD,但那是与 运行-time 有关,而不是编译时。

有人知道编译时转换的标志吗?

仅供参考,relevant chapter in GCC's manual 声明:

How the nearest representable value or the larger or smaller representable value immediately adjacent to the nearest representable value is chosen for certain floating constants (C90 6.1.3.1, C99 and C11 6.4.4.2).

C99 Annex F is followed.

在我的 C99 标准草案中,附件 F 说:

F.7.2 Translation

During translation the IEC 60559 default modes are in effect:

— The rounding direction mode is rounding to nearest.
— The rounding precision mode (if supported) is set so that results are not shortened.
— Trapping or stopping (if supported) is disabled on all floating-point exceptions

所以这似乎清楚地表明

  • GCC 使用四舍五入到最接近的值。
  • 你不能改变它。

使用十六进制语法来获得所需的确切 float 似乎是这里的正确解决方案,并且(我猜)语法存在的原因。

如果想以一种在 C89 编译器上产生匹配行为的方式编写代码,请将浮点常量编写为可精确表示的整数除以 2 的幂,例如(15518925.0f/1048576.0f) 应该在所有常见的浮点实现上产生明确的结果,无论舍入模式如何。通常没有任何方法可以控制编译时常量表达式的舍入方式,但是如果使用上述形式编写此类表达式,则可以使此类问题变得毫无意义。