views:

1658

answers:

4

We are doing some 32bit * 32bit multiplication using the following algorithm

Let us we want to multiply a (32 bit) with b (32 bit), both signed,

a = ah * 2^16 + al [ah - Higher 16 bits, al - Lower 16 bits]

b = bh * 2^16 + bl [bh - Higher 16 bits, bl - Lower 16 bits]

We are effectively doing

Result = (al * bl) + (((ah * bl) + (al * bh)) * 2^15) + ((ah * bh) * 2 ^ 31) ~~~


My question,

Is their any better way to do this?

+2  A: 

The answer is no there isn't a better way of doing things, apart from using bit shifting and and masks instead of 2^n. Namely:

a * 2^n <=> a << n

Secondly, are your ints signed or unsigned? If they're signed then that changes things.

Third, I'm not sure your 2^15 is right. If it's unsigned at least, you want to shift bits by 16 not 15.

Lastly, you have to watch out for integer overflow in the low order int. If you add together numbers in the low order int that overflow it's capacity you need to correctly increment the high order int.

cletus
+1 I guess 2^15 is a mistake. Sad, that this is the best method~~~
Alphaneo
+1  A: 

You need to know (specify) how the 64-bit value is to be stored - presumably, it is a pair of 32-bit values, possibly two elements of an array, or two elements of a structure. You also need to consider how the sign information is going to be stored in the result.

Mechanically, you probably want to convert both signed values to unsigned, and then do the split and reassemble along the lines you showed, being careful to ensure that carries from the low order 32-bit value are managed properly in the high order 32-bit value.

Depending on your initial design decisions, you may also need to fettle the representation of the sign of the result, and maybe even all the other bits.

Similar comments apply to multiplying two 16-bit numbers without any 32-bit results, something that was once important but most people don't have to worry about.

Jonathan Leffler
+5  A: 

In any mainstream compiler, the emulation of 64-bit ints on a 32-bit platform will be about as efficient as doing the mutli-step math yourself. But it will be much more reliably correct.

When doing simple arithmetic with values large enough to overflow, even the most highly tuned math library that I've seen just uses int64.

Alan
+1  A: 

Google "Karatsuba multiplication".

OIh, and in your code, change the constant 2^15 (it appears twice) to 2^16.

Robert L