decimal to BCD for long int

G

Gopal

Hello:
Can anybody suggest a code or modify the following chunk of
code for converting a decimal to BCD and viceversa for unsigned long
integers. The following code works good for integers but fails for
unsigned long.

int bcd(int dec)
{
return ((dec/10)<<4)+(dec%10);
}

int decimal(int bcd)
{
return ((bcd>>4)*10)+bcd%16;
}


Thanks
Gopal
 
T

Tim Hagan

Gopal said:
Hello:
Can anybody suggest a code or modify the following chunk of
code for converting a decimal to BCD and viceversa for unsigned long
integers. The following code works good for integers but fails for
unsigned long.

int bcd(int dec)
{
return ((dec/10)<<4)+(dec%10);
}

int decimal(int bcd)
{
return ((bcd>>4)*10)+bcd%16;
}

How does it fail? Replacing each 'int' with 'unsigned long' in your functions
produces correct results for me. Of course, it only works for integers from 0
to 99.

Please provide a complete minimal program that demonstrates your problem.
 
A

August Derleth

Hello:
Can anybody suggest a code or modify the following chunk of
code for converting a decimal to BCD and viceversa for unsigned long
integers. The following code works good for integers but fails for
unsigned long.

int bcd(int dec)
{
return ((dec/10)<<4)+(dec%10);
}

As a stylistic note, don't put tabs in code posted to Usenet. They do
strange things to some newsreaders.

(I fixed tabs.)
int decimal(int bcd)
{
return ((bcd>>4)*10)+bcd%16;
}

The problem might be those bitwise operators in there. Shifts assume a
certain width and so will fail if the width varies (apparently,
unsigned longs on your system are wider than ints). A better (slower
but more portable) solution would be to process the number in a loop,
taking the lowest-order number, converting it, and dividing the result
by 10 (suitably cast to int, which should IIRC truncate the result to
an int), ending the loop when the number is zero.

#include <math.h> /* for pow() */

int bcd(int dec)
{
int result, i;

for(i = 0; dec;) {
result = (dec % 10) * (int) pow(10,i); /* Get and convert
lowest-order number. */
dec = (int) dec / 10; /* moved down here for clarity */
}

return(result);
}

int decimal(int bcd)
{
int result;

while(bcd) {
result += bcd % 10;
bcd = (int) bcd / 10;
}

return(result);
}

/* Note: untested code. I could be a dumbass, but it looks right. */
 
I

Irrwahn Grausewitz

The problem might be those bitwise operators in there. Shifts assume a
certain width and so will fail if the width varies (apparently,
unsigned longs on your system are wider than ints). A better (slower
but more portable) solution would be to process the number in a loop,
taking the lowest-order number, converting it, and dividing the result
by 10 (suitably cast to int, which should IIRC truncate the result to
an int), ending the loop when the number is zero.

#include <math.h> /* for pow() */

int bcd(int dec)
{
int result, i;

for(i = 0; dec;) {
result = (dec % 10) * (int) pow(10,i); /* Get and convert

Whilst i never changes it's value, (int) pow( 10, i /*==0*/ )
is one of the fanciest ways to yield 1 I've ever seen.
When dealing with BinaryCodedDecimals, using of floating point
math at all seems rather strange to me.
lowest-order number. */
dec = (int) dec / 10; /* moved down here for clarity */

What do you gain in casting the result of an integer division
to int? BTW, didn't the OP write something about troubles to
change his code to work with unsigned long?

/* Note: untested code.
Thought so... :)
I could be a dumbass, but it looks right. */
So could I, but still I have to ask: what do you want to
achieve with this code?

To OP:
Sorry, I cannot provide working code either right now, because
my brain is almost asleep. Maybe in 6 hours or so, if nobody
else is going to reply meanwhile.

Irrwahn
 
A

August Derleth

53:18p:

I still think this is a good way to do it. Am I wrong in that, or is my
basic idea sound?
Whilst i never changes it's value, (int) pow( 10, i /*==0*/ )
is one of the fanciest ways to yield 1 I've ever seen.
When dealing with BinaryCodedDecimals, using of floating point
math at all seems rather strange to me.

I am a dumbass. I forgot to increment i in the loop, and I left it out at
the top of the loop. i should be incremented each time the loop goes
through.

I posted it in haste, so I now repent at leisure.
What do you gain in casting the result of an integer division
to int? BTW, didn't the OP write something about troubles to
change his code to work with unsigned long?

I should have made both the inputs and outputs unsigned longs. Damn.

I shouldn't have cast. I'm not looking too good here, am I?

Anyway, the intended result is to strip off the lowest-order number.
Thought so... :)

So could I, but still I have to ask: what do you want to
achieve with this code?

I want to replace code that's sensitively dependent on the width of the
input with code that's slower, but is following a basically good algorithm
to achieve complete portability.
To OP:
Sorry, I cannot provide working code either right now, because
my brain is almost asleep. Maybe in 6 hours or so, if nobody
else is going to reply meanwhile.

Even in a sleep debt, you're better than I.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top