# How can we multiply two 2-digit BCD numbers?

I am designing a PIC18F4520 microcontroller based system. By using this system I want to multiply two numbers. Each number is a 2-digit BCD number. Such as 73*27 and I want to see results as 2715 at a 4 digit seven segment display. I have a problem creating algorithms while multiplying those numbers. How can we multiply those numbers?

• (a) a digit at a time, the way you learned at school, or (b) convert to binary, mul, convert back.
– user16324
Commented Jun 7, 2020 at 20:46

The obvious answer is most certainly the most viable here

1. Convert BCD digits to binary numbers, multiply the upper digit with 10, add them.
2. Do that to both BCD numbers. You get both BCD numbers represented as binary, the way computers actually deal with them.
3. Multiply them.
4. Convert the result back to BCD.

This is a pretty dated microcontroller, but it can multiply (binary) numbers.

There's really no reason to do anything but the obvious, trivial.

I'll be honest: that schools and universities still teach BCD is an anachronism. There's no practical reason. Conversion to BCD is such a marginal problem that there'd be so many better topics to teach in a basics of digital logic class... it always makes me a bit sad.

As @jonk correctly points out, you can do "hand multiplication", of course, with your digits, should you feel the desire to do this in decimal!

But it would teach you something that is not clever: doing decimal computation on a binary computer.

An incredibly easy way of converting a two-digit BCD to binary is putting the two 4-bit digits into one 8-bit Byte (higher_bcd_digit<<4 | lower_bcd_digit) and using that as index into a 256-entry-table containing the binary representation of the number. That is how I would implement the BCD-to-binary conversion.
I think (not sure) on PIC18 that would result in a single-cycle 2-digit-BCD-to-binary conversion: Impossible to beat.

Sure, 156 of your 256 possible entries would be entries you don't care about. But you've got 32 kB of program memory, so that's not really a bottleneck.

It gets worse: because there's so much free space in that table, you can fill the larger "don't care" table "gaps" with your program code to save space. Just needs a bit of manual positioning of code, something you do anyway, according to your "" tag.

So, there you go, maybe four cycles (i.e. about 0.4 µs) to convert your two BCD numbers to binary. A multiplication, and a conversion back to BCD.

That conversion would take longer (can't do the trick you can do for an 8 bit table on the harvard architecture of the PIC18, so can't simply store all possible products in a table in program memory), but again, the conversion is so simple on CPUs like this one, since they support multiplication and subtraction out of the box.

• A couple of possible "uses": (1) There are some display systems that still include BCD-7Seg ICs. Might be useful for those, I suppose; and, (2) Computation using BCD can be important when decimals are involved and binary cannot exactly represent them; and, (3) When scaling by "10" may be important. That said, I agree with your answer about how to proceed. But another approach is to just implement the "hand-method" taught to children learning multiplication. If the OP wants to keep things in BCD for their application, I mean. Might add that to your answer?
– jonk
Commented Jun 7, 2020 at 21:18
• @jonk re: (1) that was what I meant with "marginal problem": compare human reading speed to even the least efficient BCD conversion algortihm; (2) and (3): the situation where decimal digit precision is important would be basically physical floating point calculations, right? And in reality I'd expect these are usually done with "overdimensioned" binary floating point, and then rounded to decimal in the end – but, truth be told, never saw that! Interesting! Maybe financial math? Commented Jun 7, 2020 at 21:25
• Yes. Financial math is a great example. Do you know how much money you can make with "round-down" if you are using binary FP computations and are writing software for banking?? Billions of dollars a year! In your pocket by collecting fractional bits of a penny from every transaction. You cannot represent 0.30 in binary FP. Not exactly. (Everything is easier if you just use integers with an implied decimal point. But there are situations where dynamic range complicates the scenario and you are back to BCD FP notation.)
– jonk
Commented Jun 7, 2020 at 21:34
• not disagreeing in general, but I don't see any banks doing large-style money transfer on a 16 bit data word MCU ;) I'd also agree, if I were to calculate financial stuff where after-decimal-point-precision matters, it'd be simply in 64-bit fixed-point representation with the implied point somewhere between the 33rd and 38th bit, depending on use case :) But, yes, pretty sure that the abundance of processors that supported performant 64 bit integer math is a pretty new development, and that I can see why I'd rather implement BCD-style multiplication than that. Commented Jun 7, 2020 at 21:46
• Well, time for that +1, I think. ;)
– jonk
Commented Jun 7, 2020 at 22:37

The PIC has a decimal adjust instruction so it supports (more or less) multi-byte BCD addition.

Horrifying as it may be to some, you could simply repeatedly add one number to a 2 byte BCD accumulator while you decrement the other (clear it first and check for zero before each addition). Worst case it would take 99 two byte additions, which may be perfectly fine in a situation where the number will be displayed on a 7-segment display.