how do you manually convert a multi digit ascii string into the hex equilavent of a decimal integer with out using a C library function. For instance If I have a small program asking a user to type into the keyboard a decimal number and lets say they type in 64357, and if this number is base 10 or decimal, the characters that get sent out a standard uart port would be the ascii equilavent of 0x36, 0x34, 0x33, 0x35, 0x37, on the receiving side of this uart, i would then need a 5 byte (unsigned char) array how do I convert the received data into a hex representation, 0xFB65 of the decimal number 64357? meaning, If I take the hex value of the received data character, subtract the ascii offset and shift the character by 4 bits I can get the decimal value however it is in the wrong number base.

receive buffer[0]=0x36, buffer[1]=0x34, buffer[2]=0x33, buffer[3]=0x35, buffer[4]=0x37
example the 5 characters above 0x36, 0x34, 0x33, 0x35, 0x37 after subtracting 0x30
would become 0x06, 0x04, 0x03, 0x05, 0x07,
If I create a long unsigned int variable and I shift the bits 4 times to the right and add them together I get
7 + 50 + 300 + 4000 + 60000 = 64357, which is the intended decimal value,
HOWEVER because microprocessor registers only represent numbers in hex format:
the 64357 is actually the HEX representation of the decimal: meaning 64357hex = 410455dec
and I want 0xFB65hex which is the decimal equilavent of 64357

*******************************************************************
So How Do I Get 0xFB65 from the input string 64357???
*******************************************************************

the reason I do not want to use a C library and string functions and want to do manual conversion is that i have a preemptive operating system and do not want to delay the micro from computing other real time data while wating for a string or printf statement to complete, meaning a multi character uart operating in polled mode at 38400 baud will halt a processor for several miliseconds while doing string or printf statements.

Recommended Answers

All 4 Replies

I will try it and see what happens, thanks, I was unaware of atoi function, maybe it will work standalone, or I can maybe modify to suit my needs

atoi() should work. Note that the problem here is not converting to hexadecimal per se, it's converting a string to an integer. Once in memory there's no difference between decimal and hexadecimal, it's all just bit patterns. The difference in representation is for human consumption, so it's all about strings. If you have a string "64357", you don't need to worry about hexadecimal, just turn it into a decimal integer with the formula:

for each digit
    result = 10 * result + digit

Then the value is in memory and when you display it, that's when it needs to be converted to a hexadecimal string:

#include <stdio.h>

unsigned str_to_decimal(const char *s)
{
    const char *digits = "0123456789";
    int result = 0;

    for (; *s; ++s) {
        int digit_val;

        /* Find the index of the digit (equivalent to its numeric value) */
        for (digit_val = 0; digits[digit_val]; ++digit_val) {
            if (digits[digit_val] == *s)
                break;
        }

        /* Only process recognized digits */
        if (digits[digit_val])
            result = 10 * result + digit_val;
    }

    return result;
}

int main(void)
{
    printf("0x%X\n", str_to_decimal("64357"));
}

Or, by taking advantage of the guaranteed relationship of the decimal digits in all character sets (ie. they're contiguous), you can simplify by removing the search and using an arithmetic transformation:

#include <stdio.h>
#include <ctype.h>

unsigned str_to_decimal(const char *s)
{
    int result = 0;

    for (; *s; ++s) {
        /* Only process recognized digits */
        if (isdigit((unsigned char)*s))
            result = 10 * result + (*s - '0');
    }

    return result;
}

int main(void)
{
    printf("0x%X\n", str_to_decimal("64357"));
}

The former solution with a search over a known alphabet is better when you're converting from string representations that exceed the decimal digits. Obviously signedness comes into play, but often hexadecimal values are treated as unconditionally unsigned.

yep, I see that now, the reason I didn't figure this out is that it is what you say to treat it as a string. I was trying to treat it as individual characters. but I think the atoi function is working as well. thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.