How many representable floats are there between 0.0
and 0.5
? And how many representable floats are there between 0.5
and 1.0
? I'm more interested in the math behind it, and I need the answer for floats
and doubles
.

- 24,651
- 6
- 70
- 114

- 6,641
- 4
- 29
- 61
-
1hint: how many bits are used to represent that fractional range? – Mitch Wheat Jan 16 '12 at 02:00
-
1I don't remember the proof offhand, but you may find the answer in http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html or http://floating-point-gui.de/ . – Crashworks Jan 16 '12 at 02:01
-
don't forget to count -0.0 :-) – franji1 Jan 16 '12 at 02:02
-
this will depends totally of how many bits you have to represent. – Gustavo F Jan 16 '12 at 02:05
-
possible duplicate of [Finding the "discrete" difference between close floating point numbers](http://stackoverflow.com/questions/6188822/finding-the-discrete-difference-between-close-floating-point-numbers). See also http://stackoverflow.com/questions/2978930/how-many-double-numbers-are-there-between-0-0-and-1-0 – Nemo Jan 16 '12 at 02:20
-
0.5 to 1.0 would be fairly easy to figure. 0.0 to 0.5 -- not so easy. – Hot Licks Jan 16 '12 at 02:24
-
Also (very) closely related: http://stackoverflow.com/questions/5015133/generating-random-floating-point-values-based-on-random-bit-stream – Nemo Jan 16 '12 at 02:33
5 Answers
For IEEE754 floats, this is fairly straight forward. Fire up the Online Float Calculator and read on.
All pure powers of 2 are represented by a mantissa 0
, which is actually 1.0
due to the implied leading 1. The exponent is corrected by a bias, so 1 and 0.5 are respectively 1.0 × 20 and 1.0 × 2−1, or in binary:
S Ex + 127 Mantissa - 1 Hex
1: 0 01111111 00000000000000000000000 0x3F800000
+ 0 + 127 1.0
0.5: 0 01111110 00000000000000000000000 0x3F000000
+ -1 + 127 1.0
Since the floating point numbers represented in this form are ordered in the same order as their binary representation, we only need to take the difference of the integral value of the binary representation and conclude that there are 0x800000 = 223, i.e. 8,388,608 single-precision floating point values in the interval [0.5, 1.0).
Similarly, the answer is 252 for double
and 263 for long double
.

- 464,522
- 92
- 875
- 1,084
-
4...and there are `0x3F000000` representable single-precision floats between `0.0` and `0.5`, which is over 1 billion. Nice! – Arlen Jan 16 '12 at 03:33
A floating point number in IEEE754 format is between 0.0 (inclusive) and 0.5 (exclusive) if and only if the sign bit is 0 and the exponent is < -1
. The mantissa bits can be arbitrary. For float
, that makes 2^23
numbers per admissible exponent, for double
2^52. How many admissible exponents are there? For float
, the minimal exponent for normalised numbers is -126, for double
it's -1022, so there are
126*2^23 = 1056964608
float
values in [0, 0.5)
and
1022*2^52 = 4602678819172646912
double
values.

- 181,706
- 17
- 308
- 431
Kerrek gave the best explanation :)
Just in case here is the code to play with other intervals too
http://coliru.stacked-crooked.com/a/7a75ba5eceb49f84
#include <iostream>
#include <cmath>
template<typename T>
unsigned long long int floatCount(T a, T b)
{
if (a > b)
return 0;
if (a == b)
return 1;
unsigned long long int count = 1;
while(a < b) {
a = std::nextafter(a, b);
++count;
}
return count;
}
int main()
{
std::cout << "number of floats in [0.5..1.0] interval are " << floatCount(0.5f, 1.0f);
}
prints
number of floats in [0.5..1.0] interval are 8388609

- 21
- 1
For 0.0..0.5: you need to worry about exponents from -1 down to as low as possible, and then multiply how many you get time the number of distinct values you can represent in the mantissa.
For every value in that range, if you double it, you get a value in the range of 0.5..1.0. And doubling it means just bumping up the exponent.
You also need to worry about unnormalized numbers, where the mantissa isn't used to represent 1.x, but 0.x, and thus will all be in your lower range, but can't be doubled by bumping up the exponent (since a particular value of the exponent is used to indicate that the value is unnormalized).

- 48,888
- 12
- 60
- 101
-
"For every value in that range, if you double it, you get a value in the range 0.5..1.0." eh no you need to *add* 0.5 which means that all numbers below `ulp(0.5)` will all become the same (0.5), for the 0.5..1 range all exponents are -1 – ratchet freak Jan 16 '12 at 02:14
-
Oops -- I was thinking about it in the other direction (going from the 0.5..1.0 range, and halving everything, which WOULD all map into the lower range). – Scott Hunter Jan 16 '12 at 02:21
-
-
Never said it was, but nice characterization of where the gap is. – Scott Hunter Jan 16 '12 at 02:28
This isn't an answer per-se, but you might get some milage out of the nextafter
function. Something like this ought to help you answer your question, though you'll have to work out the math yourself:
float f = 0;
while(f < 0.5)
{
print("%f (repr: 0x%x)\n", f, *(unsigned *)&f);
f = nextafterf(f, 0.5);
}

- 73,191
- 16
- 130
- 183
-
before you go attempting this **half** of the representable numbers in floating point are between -1 and 1 for a float that is 2 billion (or 1 billion between 0 and 1) for a double it that number *squared* if you start counting you'll be waiting for a while – ratchet freak Jan 16 '12 at 04:18
-
@ratchetfreak - True, but if you don't know the underlying math (like me) you can probably start piecing together the pattern from the first twenty at most, and then all you really need to know is the start and end points. But yes, it's better if you know the math behind it. – Chris Lutz Jan 16 '12 at 04:36