Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saturation behavior upon floating-point to signed integer conversion in C11 or C99?

I'm just wondering what guarantees, if any, either C11 or C99 provides in this regard.

Empirically, it seems that when I convert a floating-point value (regardless of its precision) to a signed integer, I get "nice" saturation whenever the floating-point value isn't representable in that signed integer range, even in the event that the floating-point value is plus or minus infinity (but I don't know or care about the NaN case).

There's a subtle issue here, which is that differences in rounding behavior could cause saturation in some cases but not in others, particularly when we're right on the edge of the a saturation boundary. I'm not concerned about that. My question is whether, once the floating-point machinery has decided upon the integer that it needs to output (which is platform-dependent), but in the event that said integer lies outside of the target signed integer range (which is platform-independent), whether or not saturation is guaranteed by the spec.

My default understanding is that what I'm seeing is merely a convenience of the underlying hardware, and that such behavior is not guaranteed because signed overflow is undefined. I hope I'm wrong, because I hate signed overflow and am trying to avoid it. So yes I'm also interested in the case of conversion to unsigned integers.

While I'm at it, what about negative 0? Is this value guaranteed to convert to integer zero, even though in some sense you could think of it as negative epsilon, which conventionally would round to -1?

like image 423
Veiokej Avatar asked Jan 22 '13 13:01

Veiokej


People also ask

Which converts an integer to a floating point number?

When converting an integer to a floating point number, it's just shifted until the mantissa is within the right range, i.e. 1 < m < 2, and the exponent is just how many steps it shifts. The number 1010 for example is shifted until it is 1.010 and the exponent is 3 as that is how many bits it was shifted.

What happens when unsigned int overflows?

When an unsigned arithmetic operation produces a result larger than the maximum above for an N-bit integer, an overflow reduces the result to modulo N-th power of 2, retaining only the least significant bits of the result and effectively causing a wrap around.


2 Answers

6.3.1.4 Real floating and integer

When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.)

like image 191
Sebastian Mach Avatar answered Nov 02 '22 23:11

Sebastian Mach


phresnel has already done a nice job answering the main thrust of your question. Some other details to keep in mind:

So yes I'm also interested in the case of conversion to unsigned integers.

The situation for unsigned isn't any nicer. Footnote 61 in C11 (the same footnote is present in C99):

The remaindering operation performed when a value of integer type is converted to unsigned type need not be performed when a value of real floating type is converted to unsigned type. Thus, the range of portable real floating values is (−1, Utype_MAX+1)

Fortunately, this is easily remedied for both signed and unsigned conversions; simply clamp your input before converting if you need saturation.

While I'm at it, what about negative 0? Is this value guaranteed to convert to integer zero, even though in some sense you could think of it as negative epsilon, which conventionally would round to -1?

Yes, it is guaranteed to convert to integer zero. First, the value of -0 is exactly zero, not negative epsilon (contrary to the rumors you read on the internet). Second, conversions from floating-point to integer truncate the value, so even if the value were "negative epsilon" (whatever that means), the result would be zero because "negative epsilon" lies in the interval (-1, 1).

like image 39
Stephen Canon Avatar answered Nov 03 '22 00:11

Stephen Canon