I am trying to make a calculator that can do fixed point calculations but I don't know how to display them in decimal (BCD). People have told me to use reverse double dabble but I am looking for another solution. How can I convert fixed point binary numbers to BCD without using reverse double dabble? Help is very appreciated.
-
1So why you want another solution when such a simple and efficient algorithm already exists. – Mitu Raj Apr 15 '18 at 17:55
-
And, what is that "simple and efficient algorithm", @MITURAJ? – Konrad Zuse Apr 15 '18 at 18:31
-
The one you have mentioned in the question – Mitu Raj Apr 15 '18 at 18:32
-
Are you sure there is no more efficient solution? For example, you can convert numbers from binary to BCD by just adding 9 to any number bigger than 9. And most people use double dabble, I don't know why. – Konrad Zuse Apr 15 '18 at 18:36
-
Cz it takes the smallest no. of gates . However latency is high – Mitu Raj Apr 15 '18 at 18:38
-
Divide by ten repeteadly, and use the remainder to get each digit. You can't beat the simplicity. Relies on divide+modulo, however, which is usually slow (on most low-end MCUs, it is implemented in software). – dim Apr 15 '18 at 19:04
-
1Real pocket calculators save time by doing *all* the calculations in BCD, then you don't have to convert back. – pjc50 Apr 15 '18 at 20:47
-
2"Are you sure there is no more efficient solution?" requires that you specify efficient for what. Time? Energy? Opcodes? Rom Space? Ram Usage? Accuracy? Average Time? Maximum Time? Transistor count? Total code size or incremental increase in code size? Every one of these has a different answer. – Henry Crun Apr 16 '18 at 00:21
1 Answers
Where to start? I will assume that you intend to do CPU maths, not try and do it with gates.
- use bcd maths in the first place. That is what calculators did. Binary can NOT give correct decimals if you want to do that.
- make the math core switchable i.e. you can switch * + between bcd/binary. This is pretty easy - at the expense of a few extra cycles you can use/not-use the decimal adjust at each step.
You have not stated what you really want. - packed BCD - multiple bytes of 2 digits per byte - single bcd - 1 digit per byte e.g to write ascii, convert to 7seg etc
I want the latter - single digits I can write to display or terminal, so I do it digit by digit. This lets me insert decimal points in the display where I want, as I output it.
I use a routine that subtracts a constant k (eg 100) from N until zero. Then I have that digit, and can output it.
while (N>0) {
N=N+k; //constant is negative so + is actually subtract
Digit:=Digit+1;
}
Repeat for each digit, putting the fixed decimal where you want it e.g. 25.1
push N
-10000 Add2Zero PrintDigit
-1000 Add2Zero PrintDigit
-100 Add2Zero PrintDigit
PrintDecimalPoint
-10 Add2Zero PrintDigit
PrintDigit
You will notice that this is using a stack and is RPN (reverse polish notiation) style. If you are implementing a calculator this is a far more efficient way to do your maths. You just have to implement a small stack, and basic functions in C then call them in order like RPN or calculator keystroke programming.
A small stack (3-4 numbers is sufficient) and one or two storage registers, and a couple of functions (push,dup,roll) allows a lot of complex calculations to be done. Note that the only maths functions you really need are * + and negate. For a lot of (16bit) uses successive subtraction is OK for division.
Calculators used a lot inefficient looping algorithms since they have 1 second to do each calculation.
If you are doing a calculator look at what the Sinclair Scientific does and marvel.

- 5,273
- 11
- 12