Can someone please help me understand how to calculate how many integers (a whole number, not a fractional number) can be represented with floating point in IEEE-754 with single precision?
-
1What do you mean by how many integers ? – Guillaume Gris Nov 13 '17 at 17:09
-
1How many mantissa bits and exponent bits are there? What does that translate into in terms of number of values? How do we determine which of those exponents would translate into fractional values? – Oliver Charlesworth Nov 13 '17 at 17:19
-
From [the Wikipedia page on IEEE-754](https://en.wikipedia.org/wiki/Single-precision_floating-point_format): *All integers with 6 or fewer significant decimal digits can be converted to an IEEE 754 floating-point value without loss of precision, and any number that can be written as 2^n such that n is a whole number from -126 to 127 can be converted to an IEEE 754 floating-point number without a loss of precision.* (Amazing what you can find on the internet with a quick Google search, isn't it ?) – Paul R Nov 13 '17 at 17:27
-
@PaulR In addition the good start of all integers with 6 or fewer significant decimal digits (about 2 million) and various powers of 2 (about 256), there are many more values (about 900 times more) integers that can be represented. – chux - Reinstate Monica Nov 13 '17 at 18:41
-
@chux yes presumably most of those 6 or fewer signficant digit numbers can be multiplied by various powers of 2. – Paul R Nov 13 '17 at 18:48
2 Answers
I am lazy, so I coded up a brute-force search as follows (this assumes float
maps to the IEEE-754 binary32
floating-point type):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
int main (void)
{
volatile union {
float f;
uint32_t i;
} num;
uint32_t count = 0;
num.i = 0;
do {
if ((num.f == floorf (num.f)) && !isinf (num.f)) count++;
num.i++;
} while (num.i);
printf ("count = %u\n", count);
return EXIT_SUCCESS;
}
On a reasonably fast PC, after less than a minute, the program spits out:
count = 1778384896
If you want to treat -0 as redundant with +0, subtract one. It is advisable to compile this code with the maximum IEEE-754 compliance offered by one's C compiler. I used the Intel compiler version 13 on Windows and specified /fp:strict
.

- 23,970
- 4
- 78
- 130
-
1A good direct approach for binary32. Might take a fraction of a [wee bit longer](https://en.wikipedia.org/wiki/Terasecond_and_longer) with binary64. ;-) – chux - Reinstate Monica Nov 13 '17 at 23:36
-
@chux No doubt about it. I mostly posted to demonstrate that most questions related to `float` can be answered by exhaustive search these days (obvious exception would be two-input operations, for example). – njuffa Nov 14 '17 at 00:00
How many integers can be represented with floating point in IEEE-754 with Single precision?
There are various ways to determine this.
IEEE-754 with Single precision or binary32 can encode all integer values 0 to 224 - the encoding has 24 bits of precision (23 explicitly encoded + 1 implied). So with negatives (and not -0),
(- 2^24 ... 2^24) is 0x2000000 - 1 different integer values
All finite FP values 224 and higher are also whole numbers or "integers".
From function to retrieve the number of available distinct values within a range? is the following no-so-portable C code that returns a sequence number for each float
which is often binary32.
#include <stdint.h>
#include <string.h>
// Return a sequence number for each `float` value.
// Numerically sequential `float` values will have successive (+1) sequence numbers.
uint32_t float_sequence(float x) {
uint32_t u32;
memcpy(&u32, &x, sizeof u32);
if (u32 & 0x80000000) {
u32 ^= 0x80000000;
return 0x80000000 - u32;
}
return u32 + 0x80000000;
}
With float_sequence(FLT_MAX) - float_sequence(1 << 24) + 1
, we have the number of finite float
>= 224.
int main(void) {
int32_t imax = 1L << 24;
printf("%" PRIx32 "\n", float_sequence(FLT_MAX) - float_sequence((float)imax) + 1);
printf("%" PRIx32 "\n", (uint32_t) (imax - -imax) - 1);
printf("%" PRIx32 "\n", float_sequence((float) -imax) - float_sequence(-FLT_MAX) + 1);
return 0;
}
Output
34000000
1ffffff
34000000
So a total of 0x69FFFFFF or 1,778,384,895 integer values or about 41% of all possible binary32 bit patterns.
One more if -0 is to be consider different than +0.
Note that the maximum finite binary32 (with a sign) would need a 128 bit integer to store it as an integer.
If one limited the integers to 64-bit 2's complement ones, the set count would be 0x29FFFFFE or 704,643,070.

- 143,097
- 13
- 135
- 256