itoa'd you so?

Dave Smith dave at thesmithfam.org
Wed Sep 19 15:42:14 MDT 2007


Steve wrote:
> So my question is, what is wrong with this method (I haven't tested it
> so there may be a minor syntax error, but that aside)?
>   

If clock cycles really count, the last thing you want to do is invoke 
the pains of the C++ streaming crap. You maybe could have done something 
like this on a lean system:

void itoa( int i, char *buf )
{
    sprintf( buf, "%d", i );
}

Some purists would say this is begging for a buffer overflow, but I beg 
to differ, since you can't sprintf() an int malformed enough to get 
arbitrary code execution, even though you could at least break the 
program by writing over the end of buf. A safer bet would be to require 
the user to pass a buffer size and use snprintf(). Whatever the case, 
it's probably going to be a lot faster than the C++ stream API.

And for an even leaner system I would have done this (yes, I have worked 
on systems recently where there is not enough memory even for sprintf()):

// An integer-based pow10()
int pow10i( unsigned int p )
{
    int ret = 1;
    while(p--)
        ret *= 10;
    return ret;
}

void itoa( int value, char *buf )
{
    if( value == 0 )
    {
        buf[0] = '0';
        buf[1] = '\0';
    }
    else
    {
        int i = value;
        int is_negative = ( i < 0 ) ? 1 : 0;
        if( is_negative )
        {
            buf[0] = '-';
            i = -i;
        }

        int len = (int)log10( i ) + 1;

        for( int pos=len-1; pos>=0; pos-- )
        {
            const int power = pow10i( pos );
            int val = ( i - ( i % power ) ) / power;

            i -= ( val * power );
            int index = is_negative ? len-pos : len-pos-1;
            buf[index] = '0' + val;
        }

        int index = is_negative ? len+1 : len;
        buf[index] = 0;
    }
}

Please don't make fun of my code -- I wrote it in just a couple minutes, 
and I'm ashamed of the floating point math it does. :) Turns out the 
sprintf() version is about twice as fast, but my "raw" version would run 
on even the leanest of systems with only a small amount of code space.

Bring on the flames about crappy C code... :)

Also, the best answer to this question would have been: Search google to 
find a fast, robust, and most importantly tested itoa() implementation 
(which I did not do -- this was all original coding, for better or worse).

--Dave


Oh, and if you fancy yourself a good embedded C/C++ coder, why don't you 
send me your resume. My company is paying top dollar these days for good 
embedded developers. We're also looking for Qt coders as well as Linux 
C++ and Python developers. And no, you will probably NOT be asked to 
implement itoa() in an interview, but you may be asked to implement 
atoi(), which is quite a bit easier. ;)



More information about the PLUG mailing list