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...
So how many “normal” non-zero numbers are there between 0 and 1? The negative exponents range from -1 all the way to -126. In each case, we have 223 distinct floating-point numbers because the mantissa is made of 23 bits. So we have 126 x 223 normal floating-point numbers in [0,1).
Floating-point representations are not necessarily unique. For example, both 0.01 × 101 and 1.00 × 10-1 represent 0.1. If the leading digit is nonzero (d0 0 in equation (1) above), then the representation is said to be normalized. The floating-point number 1.00 × 10-1 is normalized, while 0.01 × 101 is not.
As 0.1 cannot be perfectly represented in binary, while double has 15 to 16 decimal digits of precision, and float has only 7 . So, they both are less than 0.1 , while the double is more close to 0.1 .
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.
It's 7 significant digits, that is, when writing it in exponential notation you ignore the exponent.
0.0000000000000000001234567 has the same number of significant digits as 12345670000000000000, just with a different exponent. That's the magic that allows floating-point numbers to store really small and really large numbers.
As for exactly how many possible numbers there are for a float
in (0, 1) I cannot say exactly right now. You have a 23-bit mantissa, so 223 possible states of it. Then there is an 8-bit exponent and if I'm not terribly mistaken about half of its possible values will result in a number between 0 and 1. Which should leave you with about 223 + 7 = 230 possible values in that range. If anything that's perhaps an upper bound and not the exact value. I would need to consult documentation about the finer details to know exactly (and probably rethink the math above which might miss a few points).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With