AVR 32-bit xtoi()

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Has anybody implemented ANSI's xtoi() function for the AVR? I'm particulary interested in a small footprint hex-to-32bitInteger xtoi(), taking inputs in string of 8 characters wide:

9A7F1EFC -> 2592022268.

Many thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
Has anybody implemented ANSI's xtoi() function for the AVR?
I haven't seen an implementation but the concept is very straightforward. The code below (untested) compiles to 66 bytes or so (using -Os). The if..else if chain probably produces smaller code than a switch statement but you might try that if you're interested.

Note, however, that this implementation produces an unsigned int as I've seen others do. If you want to change it to uint32_t it is simple to do so although the code will grow by 20 bytes or so.

unsigned int
xtoi(const char *hexStr)
{
    unsigned int result = 0;

    if (hexStr)
    {
        char c;
        while ((c = *hexStr++) != '\0')
        {
            if ((c >= '0') && (c <= '9'))
                c -= '0';
            else if ((c >= 'A') && (c <= 'F'))
                c -= 'A' - 10;
            else if ((c >= 'a') && (c <= 'f'))
                c -= 'a' - 10;
            else
                break;
            result = (result * 16) + c;
        }
    }
    return(result);
}

edit: corrected the expressions reducing hexadecimal characters to their respective values.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

Last Edited: Sat. Jul 23, 2011 - 01:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I realized that the test of the fetched character in the while expression is redundant; removing it results in slightly smaller generated code.

unsigned int
xtoi(const char *hexStr)
{
    unsigned int result = 0;

    if (hexStr)
    {
        char c;
        for (;;)
        {
            c = *hexStr++;
            if ((c >= '0') && (c <= '9'))
                c -= '0';
            else if ((c >= 'A') && (c <= 'F'))
                c -= 'A' - 10;
            else if ((c >= 'a') && (c <= 'f'))
                c -= 'a' - 10;
            else
                break;
            result = (result * 16) + c;
        }
    }
    return(result);
}

edit: corrected the expression reducing hexadecimal characters to their respective values.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

Last Edited: Sat. Jul 23, 2011 - 01:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought about something similar, but less optimal.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code that reduces hexadecimal characters to their respective values is incorrect; the expression should include -10 instead of +10. I've corrected it in both of the previous posts.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net