7

Is a conversion from an int to a float always possible in C without the float becoming one of the special values like +Inf or -Inf?

AFAIK there is is no upper limit on the range of int.

I think a 128 bit int would cause an issue for a platform with an IEEE754 float as that has an upper value of around the 127th power of 2.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Willy Wonka
  • 155
  • 5
  • 1
    int does have a max value: https://stackoverflow.com/questions/94591/what-is-the-maximum-value-for-an-int32 – Chris Jun 30 '17 at 12:46
  • No, that's an int32. I'm talking about a pure `int`. – Willy Wonka Jun 30 '17 at 12:46
  • 3
    @chris int is not guaranteed to be 32 bits, just equal to or larger than 16 bits. – Retired Ninja Jun 30 '17 at 12:47
  • @WillyWonka it doesn't matter, every int has a max and min value. `int8, int16, int32, int64` whatever. – Timothy Groote Jun 30 '17 at 12:47
  • @RetiredNinja: is that comment directed at me? – Willy Wonka Jun 30 '17 at 12:47
  • int, usually, is a 32 bit value. If you are talking about the mathematical definition of int, then c 'int' is definitely not that. It will have some maximum value if it has some maximum amount of bits. – Chris Jun 30 '17 at 12:47
  • "pure" int has a fixed bit-width. It is not standardized, but it is there – king_nak Jun 30 '17 at 12:47
  • @TimothyGroote I like your "`int23`" – Siguza Jun 30 '17 at 12:48
  • @Siguza that would be something if it existed :p fixed the typo. – Timothy Groote Jun 30 '17 at 12:48
  • 3
    @WillyWonka Whatever data type you're dealing with, there will be limits (simply because this is the real world, and not an infinite Turing machine). –  Jun 30 '17 at 12:49
  • So adjusting for your modified question: If there will someday be a 65536 bit int, why shouldn't there be a 4294967296 bit float? But in a IEEE-754 single precision floating point, values below -2^128 or above 2^128 will round to -/+Inf: https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limits_on_integer_values – king_nak Jun 30 '17 at 12:52
  • @WillyWonka Since you say "more often than not" a `float` will be an IEEE754 type, it's worth pointing out that also "more often than not" an `int` will not have the 128 bits or more required to exceed the float minimum or maximum. – Siguza Jun 30 '17 at 12:54
  • 1
    Sorry I went too high. I think a 128 bit `int` is enough. Have edited the question. I'm new here, is there anything I can do to stop the downvotes? – Willy Wonka Jun 30 '17 at 12:55
  • @DavidBowling: I think you might be. Looking at the decent comments above (as opposed to the childish ones), it looks like that a large 128 bit `int` could give me an +Inf value in my float. Please do put an answer, I will accept it. (I've read the Stack Overflow etiquette pages). – Willy Wonka Jun 30 '17 at 13:05
  • 1
    @Chris of course int will have some upper limitation. But the OP is asking about when int's limit is above float's limit, like a platform with 128-bit int and IEEE-754 single-precision float – phuclv Jun 30 '17 at 13:40

4 Answers4

8

Short answer to your question: no, it is not always possible.

But it is worthwhile to go a little bit more into details. The following paragraph shows what the standard says about integer to floating-point conversions (online C11 standard draft):

6.3.1.4 Real floating and integer

2) When a value of integer type is converted to a real floating type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined. ...

So many integer values may be converted exactly. Some integer values may lose precision, yet a conversion is at least possible. For some values, however, the behaviour might be undefined (if, for example, an integer value would not be able to be represented with the maximum exponent of the float value). But actually I cannot assume a case where this will happen.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
3

Is it always possible to convert an int to a float?

Reasonably - yes. An int will always convert to a finite float. The conversion may lose some precision for great int values.

Yet for the pedantic, an odd compiler could have trouble.


C allows for excessively wide int, not just 16, 32 or 64 bit ones and float could have a limit range, as small as 1e37.

It is not the upper range of int or INT_MAX that should be of concern. It is the lower end. INT_MIN which often has +1 greater magnitude than INT_MAX.

A 124 bit int min value could be about -1.06e37, so that does exceed the minimal float range.

With the common binary32 float, an int would need to be more than 128 bits to cause a float infinity.


So what test is needed to detect this rare situation?

Form an exact power-of-2 limit and perform careful math to avoid overflow or imprecision.

#if -INT_MAX == INT_MIN
  // rare non 2's complement machine
  #define INT_MAX_P1_HALF (INT_MAX/2 + 1)
  _Static_assert(FLT_MAX/2 >= INT_MAX_P1_HALF, "non-2's comp.`int` range exceeds `float`");
#else
  _Static_assert(-FLT_MAX <= INT_MIN, "2's complement `int` range exceeds `float`");
#endif
rofrol
  • 14,438
  • 7
  • 79
  • 77
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
2

The standard only requires floating point representations to include a finite number as large as 1037 (§5.2.4.2.2/12) and does not put any limit on the maximum size of an integer. So if your implementation has 128-bit integers (or even 124-bit integers), it is possible for an integer-to-float conversion to exceed the range of finite representable floating point numbers.

rici
  • 234,347
  • 28
  • 237
  • 341
0

No, it not always possible to convert an int to a float, due to how floats work. 32 bit floats greater than 16777216 (or less than -16777216) need to be even, greater than 33554432 (or less than -33554432) need to be evenly divisibly by 4, greater than 67108864 (or less than -67108864) need to be evenly divisibly by 8, etc. The IEEE-754 float standard defines round to nearest even as the default mode, but other modes exist depending upon implementation.

Also, the largest 128 bit int = 2^128 - 1 is greater than the largest 32 bit float = 2^127 x 1.11111111111111111111111 = 2^127 x (2-2^-23) = 2^127 x (2^1-2^-23) = 2^(127+1) - 2^(127-23) = 2^(127+1)-2^(127-23) = 2^(128) - 2^(104)

Andrew
  • 1
  • 4
  • 19
  • 1
    The does not ask whether an `int` can be converted to the same value in `float`, without any change from rounding. It asks whether an `int` can be converted to `float` without producing one of the special values, notably the infinities. – Eric Postpischil Nov 10 '22 at 00:45
  • @Eric Postpischil No, an int cannot always be converted to float without producing one of the special values, notably the infinities, since the largest 128 bit int = 2^128-1 is greater than the largest 32 bit float = 2^127 x 1.11111111111111111111111 = 2^127 x (2-2^-23) = 2^127 x (2^1-2^-23) = 2^(127+1) - 2^(127-23) = 2^(127+1)-2^(127-23) = 2^(128) - 2^(104). (just edited my answer to include this) – Andrew Nov 10 '22 at 01:29