BCD - dec2hex

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

BCD - dec2hex

Post by inflater »

Hi ;)
this is a lame question:
How I can convert decimal number to hexadecimal and vice-versa? :D

thanx, i need this for BCD decoding (time from CMOS).
inflater
User avatar
omin0us
Member
Member
Posts: 49
Joined: Tue Oct 17, 2006 6:53 pm
Location: Los Angeles, CA
Contact:

Post by omin0us »

well, if its an actual data value...its the same thing. hex and decimal are just different ways to represent data.
if you mean a string of hex to a decimal string, then it shouldn't be to hard to write a function to convert ascii hex to data.
http://ominos.sourceforge.net - my kernel
#ominos @ irc.freenode.net
http://dtors.ath.cx - my blog
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: BCD - dec2hex

Post by Brendan »

Hi,
inflater wrote:How I can convert decimal number to hexadecimal and vice-versa? :D
I'll assume you want to convert BCD to an integer and back again. For e.g. "00010010b" (BCD for 12) becomes "00001100b" (binary for 12).

If you can use the FPU and the BCD is 20 digits (zero extended), you can do something like this:

Code: Select all

    fbld tword [address_of_BCD]
    fistp qword [address_of_binary]

Code: Select all

    fild qword [address_of_binary]
    fbstp tword [address_of_BCD]
If you can't do this, then you could do generic routines like this:

Code: Select all

int convert_BCD_to_int(void *address) {
    unsigned char temp;
    int multiplier = 1;
    int value;

    for( i = 0; i < length; i++) {
        temp = *(unsigned char*)address;
        address++;
        value = value + multiplier * (temp & 0x0F);
        multiplier = multiplier * 10;
        value = value + multiplier * (temp >> 4);
        multiplier = multiplier * 10;
    }
    return value;
}

void convert_int_to_BCD(int value, void *address) {
    unsigned char temp;
    int i;

    while(value != 0) {
        temp = value % 10
        value = value / 10;
        temp = temp | ((value % 10) << 4);
        value = value / 10;
        ((unsigned char*)address)[i++] = temp;
    }
    while(i < length) {
        ((unsigned char*)address)[i++] = 0;
    }
}
This is incredibly slow though. For the CMOS you know each value fits in a byte and is only 2 digits. In this case you could do something like this:

Code: Select all

unsigned char convert_BCD_to_byte(unsigned char BCD) {
    return ((BCD >> 4) * 10) + (BCD & 0x0F);
}

unsigned char convert_byte_to_BCD(unsigned char value) {
    return (value % 10) | ( (value / 10) << 4);
}
Of course if you want the fastest possible method, you might consider using tables with 256 entries:

Code: Select all

unsigned char convert_BCD_to_byte(unsigned char BCD) {
    return BCD_to_byte_converstion_table[BCD];
}

unsigned char convert_byte_to_BCD(unsigned char value) {
    return byte_to_BCD_converstion_table[value];
}
This is fast, but predefining those 256 entry tables is a pain. Another alternative would be:

Code: Select all

convert_BCD_to_byte:
    mov ah,al
    shr ah,4
    and al,0x0F
    aad
    or al,ah
    ret

convert_byte_to_BCD:
    aam
    shl ah,4
    or al,ah
    ret
This is probably the fastest way that doesn't involve tables (as long as input values are valid and are in range).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I know the question has been answered, but another site I use, http://www.avrbeginners.net/, has a section called 'converting numbers'. Although the site is for AVR-based programs, I have always found it quite useful for number conversion algorithms.

HTH
Adam
Post Reply