4

What is that actual value of f?

float f = std::numeric_limits<float>::max() + 1.0f;

For unsigned integral types it is well defined to overflow to 0, and for signed integral it is undefined/implementation specific if I'm not wrong. But how is it specified in standard for float/double? Is it std::numeric_limits<float>::max() or does it become std::numeric_limits<float>::infinity()?

On cppreference I didn't find a specification so far, maybe I missed it.

Thanks for help!

Paul R
  • 208,748
  • 37
  • 389
  • 560
Feuerteufel
  • 571
  • 5
  • 16

1 Answers1

1

In any rounding mode, max + 1 will simply be max with an IEEE-754 single-precision float.

Note that the maximum positive finite 32-bit float is:

                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------F23----------
          Binary: 0 11111110 11111111111111111111111
             Hex: 7F7F FFFF
       Precision: SP
            Sign: Positive
        Exponent: 127 (Stored: 254, Bias: 127)
       Hex-float: +0x1.fffffep127
           Value: +3.4028235e38 (NORMAL)

For this number to overflow and become infinity using the default rounding mode of round-nearest-ties-to-even, you have to add at least:

                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------F23----------
          Binary: 0 11100110 00000000000000000000000
             Hex: 7300 0000
       Precision: SP
            Sign: Positive
        Exponent: 103 (Stored: 230, Bias: 127)
       Hex-float: +0x1p103
           Value: +1.0141205e31 (NORMAL)

Anything you add less than this particular value will round it back to max value itself. Different rounding modes might have slightly different results, but the order of the number you're looking for is about 1e31, which is pretty darn large.

This is an excellent example of how IEEE floats get sparser and sparser as their magnitude increases.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Is C++ standard referring to IEEE-754 single-precision float or is it implementation specific (up to compiler) how floating point operations are handled? – Feuerteufel May 22 '20 at 19:28
  • You can check the value of `std::numeric_limits::is_iec559;` (and `std::numeric_limits::is_iec559;` to see if the compiler supports IEEE754 floats. If the value is `true` then, yes, it is IEEE754. So, the standard doesn't require it, but you'll find that almost all modern compilers in all modern architectures will use IEEE754. Furthermore, this remains largely true for most languages, not just C++. – alias May 22 '20 at 20:26