## Explanation needed for HEX to BCD

9 posts / 0 new
Author
Message

I need explanation about Hex to BCD conversion, my code is below:

```unsigned int HexToBCD(unsigned int number)
{
unsigned char i=0;
unsigned int k = 0;
while(number)
{
k = ( k ) | ((number%10) << i*4);
number = number / 10;
i++;
}
return(k);
}```

Regards,

Last Edited: Thu. Jul 11, 2019 - 09:33 AM

Sorry are you asking someone else to explain the code you wrote yourself to you??

Anyway %10 will give you the lowest digit so if you have a number 123 then 124 % 10 is 3 so say this was processing 123 then the first time through k (that starts at =0) get "3 << i *4". First time i is 0 so this does not shift at all. The it does number = number /10. because this is integer maths it loses any remainder/fraction so 123  /10 is 12. then it loops back. This time 12 % 10 is 2 so k (which already has 3 in the lower 4 bits) get "2 << i * 4". This time i is 1. So it does 2 << 4 which moves it into the next 4 bits up. Then it does it all again. What's left is 1, "1 << i * 4" with i now =2 is "1 << 8". So this gets the 1 in the next 4 bits.

So you end up with (binary):

0001 0010 0011

which has 1 then 2 then 3 split into 4 bit groups.

Note that the "<<i * 4" could be an "expensive" operation in computational terms. There are potentially better ways to do this.

PS this is where COMMENTS might be a good idea:

```unsigned int HexToBCD(unsigned int number)
{
unsigned char i=0; // will count the 4 bit groups
unsigned int k = 0; // the final result to be built up
// while the number still has digits to go..
while(number)
{
// shift the bottom digit into the right 4 bit group
k = ( k ) | ((number%10) << i*4);
// lose the lower digit
number = number / 10;
// move to the next 4 bit group
i++;
}
return(k);
}```

There seems to be more () in this than actually needed. While () are a good protection when you aren't sure about order of preference they can obfuscate code when over-used.

Also not that because k is "unsigned int" (16 bits) it only has room for 4 digits split into 4 bit groups. As such this routine would fail for any input over 9999. So really it should be keeping count (of i) and stopping when it increments to 5.

Last Edited: Thu. Jul 11, 2019 - 10:39 AM

Somehow I don't think hex is involved here. Maybe you want itoa() - integer to ascii. Converting the ascii back to bcd just requires a mask to knock off the bias of 48 (0x30).

Thank you very muh Cliff,

The code is not mine. I am just a beginner and trying to learn by doing something.

Regards,

clawson wrote:
Note that the "<<i * 4" could be an "expensive" operation in computational terms. There are potentially better ways to do this.

And %10 is also expensive, basically a division. Divisions, other than divisions by powers of 2, should be avoided whenever possible.

edit: there is also an actual division by 10. If the compiler is "smart" it will merge number%10 and number/10 into a single division, because you always get the result and remainder anyway. If the compiler is dumb, it will repeat the same calculations twice.

Last Edited: Thu. Jul 11, 2019 - 05:59 PM

Note, from a semantics perspective, this is more of an integer to bcd...if you were supplying "hex", you'd probably be supplying individual digits like "6" and "F" and "3", or perhaps as a string to represent 0x6F3.  (1779 decimal , or  0001,  0111, 0111, 1001 bcd binary)

An integer inherently is a series of hex digits already formed together as groups of 4 bits  (and those groups of 4 bit are not bcd).

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Thu. Jul 11, 2019 - 10:16 PM

I suggest using itoa() and then converting each ASCII character of the resulting string into BCD.

The problem with the code above as written is that it is not obviously clear (except to advanced experienced C programmers) what it is doing. In the 20th century, this was considered a plus because computer efficiency has always had a higher priority than ease-of-human-comprehension  of the code.  But the blinding speed and super-cheap cost of modern computer power makes ease-of-use and ease-of-understanding equally worthwhile to the processing speed of the algorithm.

If this code were inside a function and you didn't know that it did integer to BCD, how long would it take to decipher its function for a non-professional programmer?  Multiply that time by hundreds of lines of code and you begin to understand why even experienced professional coders can only produce 20-30 lines of code a day on average.

Simonetta wrote:
If this code were inside a function and you didn't know that it did integer to BCD, how long would it take to decipher its function for a non-professional programmer?
If I came across a "professional programmer" who could not understand

```unsigned int HexToBCD(unsigned int number)
{
unsigned char i=0; // will count the 4 bit groups
unsigned int k = 0; // the final result to be built up
// while the number still has digits to go..
while(number)
{
// shift the bottom digit into the right 4 bit group
k = ( k ) | ((number%10) << i*4);
// lose the lower digit
number = number / 10;
// move to the next 4 bit group
i++;
}
return(k);
}```

I'd sack him. All it needed were a few comments.

(however my previous comments about computational inefficiency still apply - there are "better" ways to achieve the same result - that should have been caught during the design phase).

If you know my whole story, you're an accomplice. Keep your mouth shut. 