0
\$\begingroup\$

This question already has an answer here:

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.

\$\endgroup\$

marked as duplicate by Harry Svensson, Michel Keijzers, Finbarr, laptop2d, Community Apr 17 '18 at 15:26

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    \$\begingroup\$ So why you want another solution when such a simple and efficient algorithm already exists. \$\endgroup\$ – Mitu Raj Apr 15 '18 at 17:55
  • \$\begingroup\$ And, what is that "simple and efficient algorithm", @MITURAJ? \$\endgroup\$ – Konrad Zuse Apr 15 '18 at 18:31
  • \$\begingroup\$ The one you have mentioned in the question \$\endgroup\$ – Mitu Raj Apr 15 '18 at 18:32
  • 1
    \$\begingroup\$ Real pocket calculators save time by doing all the calculations in BCD, then you don't have to convert back. \$\endgroup\$ – pjc50 Apr 15 '18 at 20:47
  • 2
    \$\begingroup\$ "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. \$\endgroup\$ – Henry Crun Apr 16 '18 at 0:21
0
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Thanks! I will now use BCD based systems for the calculators :D! \$\endgroup\$ – Konrad Zuse Apr 17 '18 at 15:25
  • \$\begingroup\$ What kind of calculator are you trying to make and why? \$\endgroup\$ – Henry Crun Apr 18 '18 at 0:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.