-4

Why does arithmetic in C saturate float but not integers? Is it the underlying processor itself?

nobody
  • 19,814
  • 17
  • 56
  • 77
Milind
  • 415
  • 8
  • 24
  • 3
    What does "saturate" mean? – Thilo May 21 '15 at 01:01
  • 2
    @Thilo Apparently [this](http://en.wikipedia.org/wiki/Saturation_arithmetic). – Frxstrem May 21 '15 at 01:02
  • In C, there is no saturation for `float` either. For floating point types and signed integers, overflow/underflow behavior is undefined. – jxh May 21 '15 at 01:07
  • Floating point does not overflow in the C sense of overflow. Assuming Annex F/IEEE semantics, all floating point operations have well-defined results for all operands/arguments. There is no undefined behavior. – R.. GitHub STOP HELPING ICE May 21 '15 at 01:09
  • @Milind: It's not quite clear what you're asking. The closest thing to "saturating" that takes place in floating point arithmetic is operations involving non-finite inputs (infinities and nans). Unless you can clarify what you're asking, the question is likely to be closed. – R.. GitHub STOP HELPING ICE May 21 '15 at 01:10
  • @R..: `NaN` is considered a represented value? – jxh May 21 '15 at 01:11
  • 1
    @jxh: No, but plus and minus infinity may be representable, and if the implementation supports IEEE-754, then they must be. – rici May 21 '15 at 01:15
  • 1
    Related question: http://stackoverflow.com/q/17588419/315052 – jxh May 21 '15 at 01:33

2 Answers2

2

It doesn't. From 6.5/5:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

So, doing a float calculation that would result in a value larger than FLT_MAX causes undefined behaviour.

When the behaviour is undefined, anything can happen. What you are seeing is your compiler generating a CPU or FPU instruction that works for well-defined sums and does not care about overflows.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 4
    This answer is incorrect. The range of representable values for IEEE floating point is `[-INF,INF]` **including** the endpoints. `FLT_MAX` is the maximum finite value. – R.. GitHub STOP HELPING ICE May 21 '15 at 01:07
  • The C language discussion of floating point types does not explicitly discount that floating point exceptions may result in an exceptional condition, although it does provide a facility to query and manipulate the floating point environment flags (including clearing, raising, and detecting floating point exceptions). – jxh May 21 '15 at 01:31
  • @R..: Support for Annex F is optiional. – Keith Thompson May 21 '15 at 01:36
  • 1
    @KeithThompson: Yes, but the way the answer is written it states that a value larger than `FLT_MAX` causes UB. That's generally not correct. A value outside the range of representable values results in UB, but that range is either implementation-defined or defined by IEEE 754 depending on whether Annex F is supported. The C standard has basically nothing to say about floating point behavior when Annex F is not supported. – R.. GitHub STOP HELPING ICE May 21 '15 at 02:28
  • 1
    @R.. if you write a better answer I'll remove mine – M.M May 21 '15 at 06:46
0

Yes, the native hardware instructions for FP add, sub, mul, div saturate to +-Inf on overflow, i.e. when the exact result would have a magnitude above FLT_MAX. That's how IEEE FP math is defined to work, and most C implementations these days are for CPUs with FP math that's more or less IEEE.

But integer math instructions are normally just binary integer operations which wrap (like the well-defined behaviour of C unsigned integer math.) For example, most ISAs have an instruction called add which does this.

A few architectures have saturating-add integer instructions (such as ARMv7 qadd, otherwise it's something compilers have to implement out of multiple instructions. Such as for Rust i32.saturating_add, or C making you hand-roll it in a way that avoids actually causing signed-integer overflow UB.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847