An algorithm to convert float number to binary representation

I want to know the algorithm of converting a given float (e.g, 3.14) to binary in the memory.

As you know; the floating number is calculated as:

$value = (-1)^ {sign} \times 2^{exponent-127} \times fraction$

where

$exponent = 2^2 + 2^3 + 2^4 + 2^5 + 2^6$

$fraction = 1 + 2^{-2}$

So, we can calculate the float number with given binary but how can we do the other way algorithmically?

-
In what way the input is given? – dtldarek May 19 '12 at 12:59
Your question is unclear and there is a serious risk of confusion. What is the input representation, among decimal [with fractional part] and IEEE single-precision floating-point ? What is the output representation, among binary integer and string of 0/1 [or other] ? – Yves Daoust Dec 28 '15 at 8:30

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:
while (true)
if (n >= 2)
n /= 2
else if (n < 1)
n *= 2
else
break

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.

• 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.

-

Example: Convert 50.75 (in base 10) to binary.

First step (converting 50 (in base 10) to binary):

1. We divide 50 by 2, which gives 25 with no remainder.
2. Next, we divide 25 by 2, which gives 12 with a remainder of 1.
3. We continue like this until we reach 0.
4. We read the result from bottom to top (as shown in the picture).

Second step (converting 0.75 (in base 10) to binary):

1. We multiply 0.75 by 2, which gives 1.5. We keep only the integer part, which is 1. Then, we do 1.5 - 1, which gives 0.5.
2. We multiply 0.5 by 2, which gives 1. We keep only the integer part, which is 1. Then we do 1 - 1, which gives 0.
3. We're done. We read from top to bottom (check picture).

This method can also be used to convert a float to octal or hexadecimal. Same methodology.

-
Can I get a comment with the down vote? – Georan Oct 18 '15 at 16:01

I'm not sure how familiar you are with binary representations: I assume you have some basic knowledge. If I'm not making sense, just ask. If you just want the fixed-point binary representation, you can just take the fraction, add the (hidden) most significant bit which is assumed to be 1.

If you just want the integer value (rounded towards zero), you can shift the result left by $\max(-24, \text{exponent} - 127)$ bits (this can be negative, so this might mean that you have to shift it to the right). Now negate the result if the sign bit is set.

If you want a fixed point binary representation, shift the result left by $\text{exponent}$ bits, and negate the result if the sign bit is set. Now you always have a fixed-point representation (the same way the fraction in the 24 bits is reprented, only in that case the MSB, which is one, is missing) of a maximum of 152 bits. The last 127 bits are bits 'after the dot'.

You might need quite some memory for this significantly more than for a normal 32 or 64-bit binary number.

-