I'm no expert but I came across this question whilst trying to figure this out for myself and think I've got a handle on it.
The binary representation of any number can be uniquely determined because if you take any number and apply:
if (n >= 2)
n /= 2
else if (n < 1)
n *= 2
you will end up with a number n, with 1 <= n < 2.
- If you divide 2.0 by 2 you get 1.0 which will break.
- If you take 0.9999... * 2, you end up with something slightly less than 2 and break again.
So a break condition always exists.
- If you multiply any number 1 <= n < 2 by 2, we get something greater than or equal to 2.
- If you divide any number 1 <= n < 2 by 2, we get something less than 1.
This means the number is also unique.
The number of times you divide or multiply by 2 will determine the power of two (exponent).
If you take the resulting number 1 <= n < 2, it can always be uniquely expressed as 1 + a(1/2) + b(1/4) + c(1/8) + d(1/16) + ... where each factor is either 1 or 0. (It may ultimately be recurring.)
Think of a circle. Split it in two - now there are two halves. Split one half in two and you now have 1/2 + 1/4 + 1/4. Split one quarter in two and you have 1/2 + 1/4 + 1/8 + 1/8. Effectively, but doing this indefinitely, you end up with the sequence Sum1->infinity = 1.
If we take any given number, we can decide whether to include each segment of that circle (or expression in the sequence). Take the float 1.85 for example.
- We start with 1 (1.)
- 0.85 > 0.5 (1/2) so we include 1/2 (1.1), leaving 0.35
- 0.35 > 0.25 -> include 1/4 (1.11), leaving 0.1
- 0.1 < 0.125 -> don't include 1/8 (1.110)
- 0.1 > 0.0625 -> include 1/16 (1.1101), leaving 0.0375
- 0.0375 > 0.03125 -> include 1/32 (1.11011), leaving 0.00625
- 0.00625 < 0.015625 -> don't include 1/64 (1.110110)
- 0.00625 < 0.0078125 -> don't include 1/128 (1.1101100)
And so on until you've used up all available bits.
This should be pretty easy to implement in code. There may well be more efficient ways to do it though - I haven't seen any implementations or played around with it myself! Have fun.