Converting binary to BCD

Hi, the table above shows how to convert the binary numbers into BCD, anyone can explain what it does? Why do we need to add 3 in some steps? What does the header 100's 10's and 1's mean? Thanks

The number 162 has a hundreds digit, a tens digit and a ones digit.

<< means shift left.

With some effort, can you figure the rest out? What happens if you don't add 3?

PS: there are better ways of doing this conversion.

https://my.eng.utah.edu/~nmcdonal/Tutorials/BCDTutorial/BCDConversion.html

Do you know what BCD (binary-coded decimal) is, and what it is used for?
What are you doing that uses binary-coded decimal?

How familiar are you with binary? Do you understand the difference between binary-coded decimal and just plain binary?

There are other ways to convert binary to BCD, that are easier to understand.

Yes, I know what BCD is. since this method is used in my lect note, I need to understand it. But I'd like to know what's the better way to do this, is there a name for the method? Many thanks :slight_smile:

If I don't add 3, it will end up with '102', but I still don't get why we need to add 3, what's the magic behind?

That explains a lot.

This is a kind of "gatekeeper" question. So who is going to go in, you or me? A practical question - how long a time do you have to find an answer to this question?

Consider the binary number 00001001. Notice that it has a decimal value of 9, and therefore, in BCD, it will convert to 00001001: that is, it will remain exactly the same.

Next, consider the binary number 00001010. It has a decimal value of 10, and therefore, in BCD, it will convert to 00010000, which is definitely not the same as 00001010.

Try converting both of these binary numbers (00001001 and 00001010) to BCD using the algorithm you were given. In one of these conversions, you will need to add 3, but in the other conversion, you won't need to add anything. See what "magic" happens when you add 3. What is the purpose of this magic, and what problem does it solve? Think about it.

@marcussyl

1. I am familiar with the following methods (attached File) for converting Binary Number into BCD (Binary Coded Decimal and NOT Normal Decimal) Number except the method of your post #1.
ch6(p343-P406)final.pdf (710.8 KB)

1. Counting Method
2. Horner Rule (requires da/daa instruction which ATmega328P has dropped)
3. Modulus/Division Method (not included in the attached file)

byte myDigit[4];
int i = 0;

void setup()
{
  Serial.begin(9600);
  unsigned int y = 162;//0001 0110 0010
  do
  {
    myDigit[i] = y % 10;
    y = y / 10;
    i++;     //0, 1, 2     3
  }
  while (y != 0);
  
  unsigned int bcdNum = myDigit[i-1]<<8|myDigit[i-2]<<4|myDigit[i-3];
  Serial.println(bcdNum, HEX);
}

void loop() {}

4. Please, give a reference or link where yo have found the method of post #1. It is really interesting. I am giving below the UNO sketch for that ( shift-and-add-3 algorithmic) method.
....pending. post #23 , #26.

If a "digit" is going to be greater than 9, we need to carry its value into the next digit. so a binary 0000 1010 (10) would become 0001 0000 (which is binary 16.) Binary 1111 (15) would become 0001 0101 (21.) So we've added 6 to the value to move the bits over, and correct the remaining bits.
This should sort-of make sense since a group of 4bit has 16 possible values, but our BCD digits only have 10 possible values. 16-10 is 6.

But the algorithm says "3"...

This is because Shifting left is multiplying by 2. Comparing each digit with "5" before the shift, and adding 3 if greater than 5, is mathematically the same as comparing with 10 after the shift and adding 6.

This is not a particularly good algorithm for the AVR, IMO, since it wants to use 4bit (or perhaps 24bit) shifts. I think you could do better by brute-force extraction of the hundreds digit, followed by a simpler 2digit conversion on the remainder (guaranteed to be less than 100.)

I’m starting to LOVE this thread :hugs:

That is called the double dabble algorithm.
https://en.wikipedia.org/wiki/Double_dabble

I would think that would be a bit cumbersome to implement on an arduino, because of the need to check each bcd digit for the needed correction.

If you keep each bcd digit in its own byte, the checks become easier, and the shifting becomes weirder, but not difficult.

Given:

 BCD1  = 78      : 0111 1000
+ BCD2 = 09      : 0000 1001
---------------------------------------
BCD3    = 81      : 1000 0001  (incorrect)
+        06      (adjustment)
------------------------------------------------------
BCD  =   87       : 1000 0111  (correct)

In the above, two BCD numbers (BCD1 and BCD2) are added; the result is incorrect (nor wrong!).

Here, neither the lower 4-bit nor the upper 4-bit of the incorrect BCD3 result is greater than 9 to add 6 for getting the correct BCD result.

However, from observation, it is clear that 06 has to be added with the incorrect BCD3 result to get correct BCD result.

To allow such addition of 06, someone (in the past that is certainly before my birth) discovered that 06 was to be added to adjust the incorrect BCD result if there is a generation of auxiliary/half carry (AC/HC).

Unfortunately, there is no way to access AC from C Language. Perhaps, this is the reason that prevents high level programmers from talking about BCD numbers.

Oh for heavens sake... here we go with another coding contest. :slight_smile:

Post #3.

Each left shift is like a multiply by 2. Adding 3 and then shifting left is like shifting left and adding 6. I think the '6' is part of the conversion from Base 10 to Base 16.

Note that the second "add 3" is done on the second digit so it is actually "add 0x30".

There are well established rules (which might be having relation with base-10 and base-16) behind the addition of 6 (in the for 06 or 60) that goes to the realm of non-programmable Digital Electronics.

Rule-1 : After the addition of two BCD numbers, let us check if the lower 4-bit is greater than 9 and then add 06 with the incorrect BCD result to get the correct (adjusted) BCD.

Rule-2 : After the addition of two BCD numbers, let us check if the upper 4-bit is greater than 9 and then add 60h with the incorrect BCD result to get the correct (adjusted) BCD.

Rule-3 : After the addition of two BCD numbers, let us check if there has occurred an auxiliary carry and then add 06 with the incorrect BCD result to get the correct (adjusted) BCD.

Rule-4: After the addition of two BCD numbers, let us check if there has occurred any full carry and then add 60h with the incorrect BCD result to get the correct (adjusted) BCD.

how to convert binary to bolt circle diameter?