Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!decwrl!shelby!csli!poser From: poser@csli.Stanford.EDU (Bill Poser) Newsgroups: comp.lang.c Subject: integer to string conversion Keywords: code Message-ID: <9813@csli.Stanford.EDU> Date: 24 Jul 89 00:40:03 GMT References: <3020@ohstpy.mps.ohio-state.edu> Sender: poser@csli.Stanford.EDU (Bill Poser) Reply-To: poser@csli.stanford.edu (Bill Poser) Organization: Center for the Study of Language and Information, Stanford U. Lines: 92 One way to put an integer into a character string is to use sprintf(3), e.g.: sprintf(string,"%d",foo); If you are doing a lot of conversions it may be worthwhile to use a special-purpose function. /* * This is a fast subroutine for converting a binary * integer into a decimal ASCII string. It is very much * like the itoa routine described on p.60 of K&R, but differs * from it in several respects. One is the order of arguments. * The name of the string in which to write is given first in order * to be consistent with sprintf and kindred functions. * * The other differences are intended to speed up the function. * These include: * * Use of registers for frequently accessed variables. * * Use of a divide, two shifts, an add and a subtract in place of a * divide and a C modulus operation. Interestingly, on this machine * replacing the modulus with a multiplication and a subtraction only * cut the time a little, but replacing the multiplication with * two shifts and an add cut the time substantially. This optimization * should work on other machines using the MC68020 processor. Your * mileage may vary on machines using processors whose relative * instruction times are different. * * Use of pointer arithmetic rather than array indexing. * * Inline code for reversal of the string (which is generated backwards). * This not only eliminates the function call overhead, but it also * eliminates the need to detect the end of the string using strlen * since we know its location already. * * Using itoa(s,n) is almost 20 % faster than using sprintf(s,"%d",n). * Testing on conversions of the 1e6 integers from -500000 to 499999 * on an unloaded HP 9000/350 showed an average of 53.2 microseconds * per conversion for sprintf() and 43.8 microseconds per conversion * for this implementation of itoa. (Figures are after subtraction * of test loop overhead of 1.1 seconds.) * * Author: William J. Poser (Department of Linguistics, Stanford U.) * */ void itoa(string,k) char *string; /* String in which to write */ int k; /* Integer to convert */ { register int temp; register char *s; register char *p; register int n; register int q; register int r; int sign; n = k; /* Copy integer into register */ p = s = string; /* Copy pointer into registers */ if( (sign = n) < 0) n = -n; /* Make n positive */ /* Do conversion */ do { q = n / 10; r = (q << 3) + (q << 1); /* Multiply by 10 (8x + 2x = 10x) */ *s++ = n + '0' - r; } while (( n = q) > 0); if(sign < 0) *s++ = '-'; /* If negative, add sign */ *s = '\0'; /* Null terminate string */ s--; /* Point s at last non-null char */ /* * Now we reverse the string. When we begin, p points at the first * character of the string, s at the last non-null character. */ while(p < s){ temp = *p; *p++ = *s; *s-- = temp; } return; }