You need to decide what the actual scaling factor for your fractional part is. For your particular example, it looks like an appropriate factor might be 1/1000, or 0.001. What this means is that 56.789 is represented as 56 + 789 × 0.001. But it means that 123.4 will be represented as 12 + 400 × 0.001. That is, you had a mistake in your question: a_frx
will be 400, not 4.
I don't know Karatsuba's algorithm, and I suspect it's not really applicable to this problem anyway. I only know what I earned in elementary school.
Let's represent the scaling factor by sc
. So our multiplication is actually
( a_fxd + a_frx * sc ) * ( b_fxd + b_frx * sc )
Multiplying this out, we get
a_fxd * b_fxd + a_fxd * b_frx * sc + a_frx * b_fxd * sc + a_frx * b_frx * sc * sc
Collecting terms, we have
a_fxd * b_fxd + (a_fxd * b_frx + a_frx * b_fxd + a_frx * b_frx * sc) * sc
So if we represent the product as p_fxd
and p_frx
, it looks like we'll have
p_fxd = a_fxd * b_fxd
p_frx = a_fxd * b_frx + a_frx * b_fxd + a_frx * b_frx * sc
Let's plug in the actual values:
p_fxd = 123 * 56 = 6888
p_frx = 123 * 789 + 400 * 56 + 400 * 789 * 0.001 = 119762.600
But there's an additional wrinkle, because p_frx
is really supposed to be an integer in the range 0..999. So we need to discard the .600, and carry the 119. So our final result is
p_fxd = 6888 + 119 = 7007
p_frx = 762
And this corresponds to the correct result, 123.4 × 56.789 = 7007.762.
...Well, actually, the correct correct result is 7007.7626, or rounded to three digits, 7007.763. So strictly speaking we shouldn't have thrown away that .600 we ended up with in p_frx
, we should have rounded.
There may also be some extra wrinkles to take care of when we consider the possibility of negative numbers.
Finally, there's the choice of scaling factor. In practice, the 0.001 I've used here isn't really a realistic value. For a general-purpose algorithm you'd probably use something more like 1/10000, or 1/1000000000, or 1/32768, or 1/65536, or something like that. (Using powers of two makes for larger ranges and typically more efficient calculations, but less-obvious fractional parts and less-efficient conversions to and from decimal representations. For example, if you used a scaling factor of 1/32768, a_frx
would be 13107, and b_frx
would be 25853 or 25854.)