Yes, this is quite ugly, and if I ever catch you writing something this cryptic I'll force a 15 page code review on you. However, one can tell how much fun atoi actually is once you take into account error checking!/* atoi - christopher.watford@gmail.com */
/* PUBLIC DOMAIN */
long atoi(const char *value) {
long ival = 0, c, n = 1, i = 0, oval;
for( ; c = value[i]; ++i) /* chomp leading spaces */
if(!isspace(c)) break;
if(c=='-' || c=='+') { /* chomp sign */
n = (c!='-' ? n : -1); i++;
}
while(c = value[i++]) { /* parse number */
if(!isdigit(c)) return 0;
oval = ival; /* save ival for overflow detection */
ival = (ival * 10) + (c - '0'); /* mult/accum */
if(ival < oval) { /* report overflow/underflow */
errno = ERANGE;
return (n>0 ? LONG_MAX : LONG_MIN);
}
}
return (n>0 ? ival : -ival);
}
Naturally our conversation drifted to atof--well in his defense I drifted to atof--and I decided I should write a compliant implementation. As it turns out implementing overflow and underflow checking for floating point numbers is much harder (and trickier too!) than for integers. Below are the pretty printed sources to both my atoi and atof implementations, along with links to download. They are in the public domain and you should use them at your own risk, because if I were to catch you using either of these I will hold a code review so harsh it would make a death row inmate cry.
View atoi source (download)
View atof source (download)