home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / xtoa.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  5KB  |  193 lines

  1. /***
  2. *xtoa.c - convert integers/longs to ASCII string
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       The module has code to convert integers/longs to ASCII strings.  See
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <stdlib.h>
  13. #include <limits.h>
  14.  
  15. /***
  16. *char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII
  17. *       string
  18. *
  19. *Purpose:
  20. *       Converts an int to a character string.
  21. *
  22. *Entry:
  23. *       val - number to be converted (int, long or unsigned long)
  24. *       int radix - base to convert into
  25. *       char *buf - ptr to buffer to place result
  26. *
  27. *Exit:
  28. *       fills in space pointed to by buf with string result
  29. *       returns a pointer to this buffer
  30. *
  31. *Exceptions:
  32. *
  33. *******************************************************************************/
  34.  
  35. /* helper routine that does the main job. */
  36.  
  37. static void __cdecl xtoa (
  38.         unsigned long val,
  39.         char *buf,
  40.         unsigned radix,
  41.         int is_neg
  42.         )
  43. {
  44.         char *p;                /* pointer to traverse string */
  45.         char *firstdig;         /* pointer to first digit */
  46.         char temp;              /* temp char */
  47.         unsigned digval;        /* value of digit */
  48.  
  49.         p = buf;
  50.  
  51.         if (is_neg) {
  52.             /* negative, so output '-' and negate */
  53.             *p++ = '-';
  54.             val = (unsigned long)(-(long)val);
  55.         }
  56.  
  57.         firstdig = p;           /* save pointer to first digit */
  58.  
  59.         do {
  60.             digval = (unsigned) (val % radix);
  61.             val /= radix;       /* get next digit */
  62.  
  63.             /* convert to ascii and store */
  64.             if (digval > 9)
  65.                 *p++ = (char) (digval - 10 + 'a');  /* a letter */
  66.             else
  67.                 *p++ = (char) (digval + '0');       /* a digit */
  68.         } while (val > 0);
  69.  
  70.         /* We now have the digit of the number in the buffer, but in reverse
  71.            order.  Thus we reverse them now. */
  72.  
  73.         *p-- = '\0';            /* terminate string; p points to last digit */
  74.  
  75.         do {
  76.             temp = *p;
  77.             *p = *firstdig;
  78.             *firstdig = temp;   /* swap *p and *firstdig */
  79.             --p;
  80.             ++firstdig;         /* advance to next two digits */
  81.         } while (firstdig < p); /* repeat until halfway */
  82. }
  83.  
  84. /* Actual functions just call conversion helper with neg flag set correctly,
  85.    and return pointer to buffer. */
  86.  
  87. char * __cdecl _itoa (
  88.         int val,
  89.         char *buf,
  90.         int radix
  91.         )
  92. {
  93.         if (radix == 10 && val < 0)
  94.             xtoa((unsigned long)val, buf, radix, 1);
  95.         else
  96.             xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
  97.         return buf;
  98. }
  99.  
  100. char * __cdecl _ltoa (
  101.         long val,
  102.         char *buf,
  103.         int radix
  104.         )
  105. {
  106.         xtoa((unsigned long)val, buf, radix, (radix == 10 && val < 0));
  107.         return buf;
  108. }
  109.  
  110. char * __cdecl _ultoa (
  111.         unsigned long val,
  112.         char *buf,
  113.         int radix
  114.         )
  115. {
  116.         xtoa(val, buf, radix, 0);
  117.         return buf;
  118. }
  119.  
  120. #ifndef _NO_INT64
  121.  
  122. static void __stdcall x64toa (      /* stdcall is faster and smaller... Might as well use it for the helper. */
  123.         unsigned __int64 val,
  124.         char *buf,
  125.         unsigned radix,
  126.         int is_neg
  127.         )
  128. {
  129.         char *p;                /* pointer to traverse string */
  130.         char *firstdig;         /* pointer to first digit */
  131.         char temp;              /* temp char */
  132.         unsigned digval;        /* value of digit */
  133.  
  134.         p = buf;
  135.  
  136.         if ( is_neg )
  137.         {
  138.             *p++ = '-';         /* negative, so output '-' and negate */
  139.             val = (unsigned __int64)(-(__int64)val);
  140.         }
  141.  
  142.         firstdig = p;           /* save pointer to first digit */
  143.  
  144.         do {
  145.             digval = (unsigned) (val % radix);
  146.             val /= radix;       /* get next digit */
  147.  
  148.             /* convert to ascii and store */
  149.             if (digval > 9)
  150.                 *p++ = (char) (digval - 10 + 'a');  /* a letter */
  151.             else
  152.                 *p++ = (char) (digval + '0');       /* a digit */
  153.         } while (val > 0);
  154.  
  155.         /* We now have the digit of the number in the buffer, but in reverse
  156.            order.  Thus we reverse them now. */
  157.  
  158.         *p-- = '\0';            /* terminate string; p points to last digit */
  159.  
  160.         do {
  161.             temp = *p;
  162.             *p = *firstdig;
  163.             *firstdig = temp;   /* swap *p and *firstdig */
  164.             --p;
  165.             ++firstdig;         /* advance to next two digits */
  166.         } while (firstdig < p); /* repeat until halfway */
  167. }
  168.  
  169. /* Actual functions just call conversion helper with neg flag set correctly,
  170.    and return pointer to buffer. */
  171.  
  172. char * __cdecl _i64toa (
  173.         __int64 val,
  174.         char *buf,
  175.         int radix
  176.         )
  177. {
  178.         x64toa((unsigned __int64)val, buf, radix, (radix == 10 && val < 0));
  179.         return buf;
  180. }
  181.  
  182. char * __cdecl _ui64toa (
  183.         unsigned __int64 val,
  184.         char *buf,
  185.         int radix
  186.         )
  187. {
  188.         x64toa(val, buf, radix, 0);
  189.         return buf;
  190. }
  191.  
  192. #endif  /* _NO_INT64 */
  193.