Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.5 KiB

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