views:

657

answers:

2

I have a large (12 digit) BCD number, encoded in an array of 6 bytes - each nibble is one BCD digit. I need to multiply it by 10^x, where x can be positive or negative.

I know it can be done by shifting left or right by nibble instead of bit, but it's a horrible implementation - especially in Javacard, which is what I'm using. Is there a better way?

A: 

You don't have to use bit-shifting (although that is probably the most efficient way of doing it).

For your 12-digit BCD number, provided there won't be any overflow, assume that b[5] through b[0] holds your bytes from most significant to least significant, and that mod is the modulus (remainder) operation and div is integer division, the following pseudo-code would multiply by 10:

for i = 5 to 1
    b[i] = (b[i] mod 16) * 16 + b[i-1] div 16
b[0] = (b[0] mod 16) * 16

To be honest, that's probably uglier than your bit-shifting solution but, as long as you encapsulate either of them in a function, it shouldn't really matter.

I would suggest having a function along the lines of:

BcdArray mult10 (BcdArray ba, int shiftAmt);

which would return a modified array by applying that power of 10.

Any even power of ten is a simple copy of bytes (since two nybbles is a byte) whilst only the odd powers of ten would need the tricky bit-shifting or remainder/division code.

paxdiablo
Good point! Never thought about that, but multiplication with 10^x has the same effect as shifting left by x*4 in BCD. Now all you need is a data-type that can hold a 6 byte number and cast a bit.
Nils Pipenbrinck
nah - bullshit. Forget everything I wrote :-)
Nils Pipenbrinck
+1  A: 

Shifting by nibbles is the most efficient way.

If performance is not your problem and you want to have the most readable version you may want to convert your BCD-number to a string and move the decimal point around.

In case you don't have a decimal point (e.g. your number is an integer) you can concat zeros if x > 0 or delete the last -x characters if x < 0.

Afterwards convert the string back to BCD. Watch out for overflows and and cases where you delete all characters and end up with an empty string.

Nils Pipenbrinck