c - 在 C11 或 C99 中浮点到有符号整数转换时的饱和行为



我只是想知道 C11 或 C99 在这方面提供了什么保证(如果有的话)。

从经验上讲,似乎当我将浮点值(无论其精度如何)转换为有符号整数时,只要浮点值在该有符号整数范围内不可表示,即使浮点值是正负无穷大(但我不知道也不关心 NaN 的情况),我就会获得"不错"的饱和度。

这里有一个微妙的问题,即舍入行为的差异在某些情况下可能会导致饱和,但在其他情况下则不会导致饱和,尤其是当我们正好处于饱和边界的边缘时。我不担心这个。我的问题是,一旦浮点机制决定了它需要输出的整数(取决于平台),但如果所述整数位于目标有符号整数范围之外(与平台无关),规范是否保证饱和。

的默认理解是,我所看到的只是底层硬件的便利,并且不能保证这种行为,因为签名溢出是未定义的。我希望我错了,因为我讨厌签名溢出并试图避免它。所以是的,我也对转换为无符号整数的情况感兴趣。

当我在的时候,负0呢?这个值是否保证转换为整数零,即使在某种意义上你可以把它想象成负 epsilon,通常四舍五入为 -1?

6.3.1.4 实浮点数和整数

当实浮点类型的有限值转换为 _Bool 以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果值为整数部分不能由整数类型表示,行为未定义。

Phresnel已经很好地回答了你问题的主要内容。 要记住的其他一些细节:

所以是的,我也对转换为无符号整数的情况感兴趣。

未签名的情况也好不到哪里去。 C11中的脚注61(C99中也有相同的脚注):

当整数类型的

值转换为无符号类型时,不需要执行整数类型的值转换为无符号类型时执行的余下操作。因此,可移植实际浮点值的范围为 (−1, Utype_MAX+1)

幸运的是,对于有符号和无符号转换,这都很容易补救;如果您需要饱和,只需在转换前夹紧输入即可。

当我在的时候,负0呢?这个值是否保证转换为整数零,即使在某种意义上你可以把它想象成负 epsilon,通常四舍五入为 -1?

是的,保证转换为整数零。 首先,-0的值正好为零,而不是负 epsilon(与您在网上看到的谣言相反)。 其次,从浮点到整数的转换会截断该值,因此即使该值是"负 epsilon"(无论这意味着什么),结果也将为零,因为"负 epsilon"位于区间 (-1, 1) 中。

当我在的时候,负0呢?此值是否保证 转换为整数零,即使从某种意义上说你可以想到 它作为负 epsilon,通常四舍五入为 -1?

它被截断,因此趋向零 - 这意味着小于 1.0 且大于 -1.0 的任何值都变为 0。就"典型"平台而言,负零变成了零。我不完全确定这是否由标准保证,但我相信在实践中你可以依靠它,即使标准没有定义它[除非你计划让你的代码在极其"奇怪"的设备上运行,比如DSP或GPU]。

最新更新