First, I should define what I mean by a fraction. I mean a finite number digits right of the radix point. For example, 0.875 is a fraction. 1.9 isn't, but that's OK, because we can deal with values left of the radix point easily.
For example, suppose you want to convert 0.875 from base 10 to base 2.
Here's one idea. Shift the decimal point to the right three places. That results in 875. Then convert that to base 2. The shift the radix point back left three places.
Only, it doesn't work.
Why not? The answer lies in what it means to shift a radix point to the right or left. When you shift the radix point of 0.875 to the right by three spots, you're really multiplying by 103.
However, once you convert 875 to base 2, and shift the radix point to the left, you are dividing by 23, which is clearly not the same as 103. You can't multiply by a number, then, divide by a different number and expect to get the same answer.
What's the right way to think about this?
It turns out to be more challenging than you might imagine, because the "solution" to this problem requires you to think differently.
Imagine that you have already converted the number to a different base. What would it look like? You may not know the digits, but you know the form.
We're going to apply the following algorithm to solve the problem.
For now, just assume that you can use negative indexes into arrays.
index = -1 ;
while ( num > 0 )
{
num = num * base ; // Shift radix point to right by 1.
if ( num >= 1 ) // Case 1: num is greater than or equal to 1
{
digit[ index ] = (int) num ; // keep only integer part
num -= (int) num ; // get rid of value left of radix point
}
else // num is less than 1
digit[ index ] = 0 ;
index-- ;
}
The key step is to realize what you're doing. You're multiplying
by the base, which is equivalent to shifting the radix point over by 1.
Let's imagine what this does:
So, the idea is to see what value is left of the radix point. In a program, we can cast a floating point value to an int, to get the value left of the radix point (i.e., to throw away the rest of the fraction).
That value will be di.
We know that if, after we multiply by K, num > 0, then di must be between 1 and K - 1. Once we determine what di is, and that it's value is greater than 1, then we need to get rid of the value left of the radix point. Otherwise, when we make the check whether num > 0 in the if-statement, once it's true, it will be always true. We don't want that to happen.
Unfortunately, this algorithm may not terminate. For example, if you try to convert 0.3 to base 2, you'll end in an infinite loop. Fortunately, since 0.3 is rational, there will be a repeated set of digits, so with careful coding, you can find stop the loop once you see a set of digits repeat.
The loop terminates once the value reaches 0.
So, let's apply this algorithm to convert 0.625 to base 2.
Fortunately, we can break it down into two cases.
Then, subtract off the integer part. Repeat until the number is 0. If the number is 0, it may simply be a repeated fraction.
To convert arbitrary floating point in base 10 to arbitrary bases, solve the problem by converting the integer part to base K and the fractional part to base K. Add the two parts together.