gpt4 book ai didi

c - 将浮点值舍入为例如单精度

转载 作者:太空宇宙 更新时间:2023-11-04 01:00:43 25 4
gpt4 key购买 nike

C 和 C++ 提供多种宽度的 float 据类型,但未指定精度。编译器可以自由使用理想化算术来简化表达式,使用 double 来计算 float 值的表达式,或者使用 double 寄存器来保持 float< 的值 变量或公共(public)子表达式。

如果我错了请纠正我是错误的,请参阅编辑,但是将内存中的float提升到 double 寄存器中甚至是合法的,因此存储一个值然后将其加载回来不一定会截断位。

将数字转换为较低精度的最安全、最便携的方法是什么?理想情况下,它也应该是高效的,在 SSE2 上编译为 cvtsd2ss。 (因此,虽然 volatile 可能是一个答案,但我更喜欢更好的东西。)

编辑:总结一些评论和发现……

  • 提高中间结果的精度总是公平的。
  • 在 C++ 中允许表达式简化,在 C 中给定 FP_CONTRACT on
  • 不允许对单精度float 使用 double (在 C 或 C++ 中)。

但是,某些编译器(尤其是 x86-32 上的 GCC)会非法忘记某些精度转换。

编辑 2:一些人对未能缩小中间结果的一致性表示怀疑。

  • C11 §5.2.4.2.2/9(与答案中引用的 C99 引用文献相同)具体说明了“删除所有额外的范围和精度”,因为它指定了如何以更宽的精度完成其他计算。在几个符合要求的替代精度中,有一个是“不确定的”,对我来说这意味着没有任何限制。

  • C11 §7.12.2 和 §6.5/8 定义了 #pragma STDC FP_CONTRACT on,它使编译器能够尽可能使用无限精度。

    The intermediate operations in the contracted expression are evaluated as if to infinite range and precision, while the final operation is rounded to the format determined by the expression evaluation method. A contracted expression might also omit the raising of floating-point exceptions.

  • C++14 同样明确放弃了对中间结果的有限精度和范围的限制。 N4567 §5/12:

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

注意允许恒等式x - x = 0a + b - b + c简化为a + c不是与使加法可交换或结合相同。 a + b + c 仍然不同于 a + c + ba + (b + c),当 CPU提供带有两个加数和一个四舍五入结果的加法。

最佳答案

C99 5.2.4.2.2p8 明确表示

assignment and cast [..] remove all extra range and precision

因此,如果您想将范围和精度限制为 float ,只需转换为 float,或分配给 float 变量即可。

你甚至可以做类似 (double)((float)d) 的事情(用额外的括号来确保人们正确阅读它),将变量 d 限制为float 精度和范围,然后将其转换回 double。 (标准 C 编译器不允许对其进行优化,即使 ddouble;它必须将精度和范围限制为 float.)

我已经在实际实现中使用了它,例如Kahan summation algorithm ,它可用于允许 C 编译器进行非常积极的优化,但没有失效的风险。

关于c - 将浮点值舍入为例如单精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40784135/

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