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

时间:2013-01-22 13:29:07

标签: c floating-point integer overflow

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

根据经验,似乎当我将浮点值(无论其精度如何)转换为有符号整数时,只要浮点值在该有符号整数范围内无法表示,我就会得到“漂亮”的饱和度,甚至如果浮点值为正或负无穷大(但我不知道或不关心NaN情况)。

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

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

虽然我在这,但负0怎么样?这个值是否可以保证转换为整数零,即使在某种意义上你可以把它想象为负epsilon,它通常会舍入到-1?

3 个答案:

答案 0 :(得分:10)

  

6.3.1.4实数浮点数和整数

     

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

答案 1 :(得分:3)

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

  

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

无符号的情况并不好。 C11中的脚注61(同一脚注出现在C99中):

  

当实数浮点类型的值转换为无符号类型时,无需执行将整数类型的值转换为无符号类型时执行的剩余操作。因此,便携式实际浮动值的范围是(-1,Utype_MAX + 1)

幸运的是,对于签名和无符号转换,这很容易解决;如果您需要饱和,只需在转换前将输入钳位。

  

虽然我在这,但负0怎么样?这个值是否可以保证转换为整数零,即使在某种意义上你可以把它想象为负epsilon,它通常会舍入到-1?

是的,保证转换为整数零。首先,-0的值恰好为零,而非负epsilon(与您在互联网上阅读的谣言相反)。第二,从浮点转换为整数截断该值,所以即使该值为“负epsilon”(无论这意味着什么),结果也将为零,因为“负epsilon”位于区间内(-1,1)。

答案 2 :(得分:1)

  

虽然我在这,但负0怎么样?这个值是否保证   转换为整数零,即使在某种意义上你可以想到   它作为负epsilon,通常会舍入到-1?

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