How many unique values are there between 0 and 1 of a standard float?

c#, floating-point, ieee-754

Solution

How many unique values are there between 0 and 1 of a standard float?

This is not really the question you want an answer for, but the answer is, not including `0` and `1` themselves, that there are `2**23 - 1` subnormal numbers and `126 * 2**23` normal numbers in this range, for a total of `127 * 2**23 - 1`, or `1,065,353,215`.

But note that these numbers are not evenly distributed on the interval between `0` and `1`. Using a "delta" of `1f / 1065353215f` in a loop from `0f` to `1f` will not work for you.

If you want to step from 0.0 to 1.0 with eqally long steps of the (decimal) form 0.00...01, maybe you should use `decimal` instead of `float`. It will represent numbers like that exactly.

If you stick to `float`, try with `0.000001` (ten times greater than your proposed value), but note that errors can build up when performing very many additions with a non-representable number.

Also note: There are a few "domains" where you can't even count on the first seven significant decimal digits of a `float`. Try for example saving the value `0.000986f` or `0.000987f` to a `float` variable (be sure the optimization doesn't hold the value in a "wider" storage location) and write out that variable. The first seven digits are not identical to `0.0009860000` resp. `0.0009870000`. Again you can use `decimal` if you want to work with numbers whose decimal expansions are "short".

Edit: If you can use a "binary" step for your loop, try with:

float delta = (float)Math.Pow(2, -24);

or equivalently as a literal:

const float delta = 5.96046448e-8f;

The good thing about this delta is that all values you encouter through the loop are exactly representable in your `float`. Just before (under) `1f`, you will be taking the shortest possible steps possible for that magnitude.

Problem

I guess another way of phrasing this question is what decimal place can you go to using a `float` that will only be between 0 and 1? I've tried to work it out by looking at the MSDN. Which says the precision is 7 digits. I thought that meant it could only track changes of `0.0000001`. However if I do: ``` float test = 0.00000000000000000000000000000000000000000001f; Console.WriteLine(test); ``` It writes out `9.949219E-44` If I add any more zeroes, it will output `0`. I'm pretty sure I'm missing something here as that degree of accuracy seems massively wrong. Mainly as a float is 32bits in size, and just from 0-1 at that level of accuracy contains 1e+44 possible numbers...

Original source