itoa'd you so?

Levi Pearson levi at
Fri Sep 21 23:42:29 MDT 2007

Charles Curley <charlescurley at> writes:
> I like it. A few points.
> * It is base ten only. My solution is much more general. Need base 36?
>   Recall that base 10 was not specified in the original problem. But
>   your method can be adapted at the cost of:
>   * expanding the lookup table,
>   * dividing by a variable instead of an inline constant, usually
>     slower.

Your solution doesn't take 'base' as a paramter, so I can only assume
you've defined it as a constant global variable somewher else in your
program.  In that case, your solution is just as fixed as mine.  The
modifications to change the base for either are trivial, but require a
> * You have a call to abs inside your main loop. I think I see why, but
>   would you safely speed things up by moving it outside?

Only after the first iteration.  It's there so that it handles INT_MIN
properly.  It's plenty fast, so I see no reason to move it, but you
could unroll the loop one iteration and not perform the abs() inside
after that if you needed to.

> * Your reverse function is nice, but probably slower than strcat
>   because it uses an intermediate variable. But I think you can speed
>   it up considerably by only running for (strlen (s))/2 iterations. If
>   so, it probably would be better than my temporary buffer.

I think you need to read the reverse function more closely.  That's
precisely what it does.

> * I replaced my while loop with a do ... while loop, and found (to no
>   great surprise) that it is slower. I didn't check, but I doubt it
>   saved any space because of the way do ... while loops usually
>   compile. That did let me get rid of the 0 special case, making
>   things more elegant. The same might apply here.

The code I presented is adapted from the K&R C book, as I said, in the
section on control flow.  It was an example of where a do/while loop
would be handy. :)

> * I declared some variables to be register variables. That helps on
>   Intel architecture, which is so pathetically register poor. It might
>   or might not help on register rich processors because the compiler
>   might do it for you.

I think modern compilers do a pretty good job of optimizing register
use when you ask them to, and I think they're also free to ignore a
register declaration.  I'm not sure there's any real benefit; you'd
have to compare asm output to tell.

> * I declared the function digit inline. That helped. But it would make
>   for a smaller code size only if digit isn't used elsewhere. It could
>   be a useful routine for special cases like a hex dump.

Possibly.  The compiler ought to be able to inline it without your
help, though, if you ask it to.

I think your program is pretty good now, aside from the fatal flaw of
not handling MIN_INT properly.  That's really not acceptable; it needs
to be correct more than it needs to be sped up.  itoa is pretty much
never going to be an embedded system bottleneck, but you never know
when you're going to hit a corner case.  Also, on my computer at
least (1.2 Ghz PPC), my version is still faster.


More information about the PLUG mailing list