fork(1) download
  1. // Convert a signed long integer to English text. (2.00)
  2. // @see dwYRr9
  3.  
  4. #include <stdlib.h>
  5. #include <limits.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <time.h>
  9. #include <assert.h>
  10.  
  11. //
  12. // Utility.
  13. //
  14.  
  15. struct astring {
  16. char first[288], * last;
  17. };
  18.  
  19. char* stpcpy_(char* s, const char* t)
  20. {
  21. size_t n = strlen(t);
  22. memcpy(s, t, n + 1);
  23. return s + n;
  24. }
  25.  
  26. struct astring* astring_append(struct astring* s, const char* t)
  27. {
  28. s->last = stpcpy_(s->last, t);
  29. return s;
  30. }
  31.  
  32. //
  33. // Convert.
  34. //
  35.  
  36. struct astring* textnumber_detail(int n, struct astring* result)
  37. {
  38. assert(1 <= n && n <= 999);
  39.  
  40. static const char* ones[] = {
  41. "",
  42. "one",
  43. "two",
  44. "three",
  45. "four",
  46. "five",
  47. "six",
  48. "seven",
  49. "eight",
  50. "nine"
  51. };
  52.  
  53. static const char* teens[] = {
  54. "ten",
  55. "eleven",
  56. "twelve",
  57. "thirteen",
  58. "fourteen",
  59. "fifteen",
  60. "sixteen",
  61. "seventeen",
  62. "eighteen",
  63. "nineteen"
  64. };
  65.  
  66. static const char* tens[] = {
  67. "",
  68. "",
  69. "twenty",
  70. "thirty",
  71. "forty",
  72. "fifty",
  73. "sixty",
  74. "seventy",
  75. "eighty",
  76. "ninety"
  77. };
  78.  
  79. // Hundreds.
  80.  
  81. if (n >= 100)
  82. {
  83. astring_append(result, ones[n / 100 % 10]);
  84. astring_append(result, " hundred");
  85. n %= 100;
  86. if (n != 0)
  87. astring_append(result, " and ");
  88. }
  89.  
  90. // Tens and ones.
  91.  
  92. if (n < 10)
  93. {
  94. astring_append(result, ones[n]);
  95. }
  96. else if (n < 20)
  97. {
  98. astring_append(result, teens[n % 10]);
  99. }
  100. else
  101. {
  102. astring_append(result, tens[n / 10]);
  103. if (n % 10)
  104. {
  105. astring_append(result, "-");
  106. astring_append(result, ones[n % 10]);
  107. }
  108. }
  109. return result;
  110. }
  111.  
  112. const char* textnumber(long int n)
  113. {
  114. assert(n > LONG_MIN || LONG_MIN + LONG_MAX == 0);
  115.  
  116. static const char* base[] = {
  117. "",
  118. " thousand",
  119. " million",
  120. " billion",
  121. " trillion",
  122. " quadrillion",
  123. " quintillion"
  124. };
  125.  
  126. static _Thread_local struct astring result[1];
  127. result->last = result->first;
  128.  
  129. // Zero.
  130.  
  131. if (n == 0)
  132. {
  133. astring_append(result, "zero");
  134. return result->first;
  135. }
  136.  
  137. // Negative.
  138.  
  139. if (n < 0)
  140. {
  141. astring_append(result, "minus ");
  142. n = -n;
  143. }
  144.  
  145. // Log base 1000.
  146.  
  147. long int k = 1;
  148. int j = 0;
  149. for (long int i = n; i >= 1000; i /= 1000)
  150. {
  151. j += 1;
  152. k *= 1000;
  153. }
  154.  
  155. // Powers of 1000.
  156.  
  157. for (int i = j; i >= 0; i--)
  158. {
  159. long int m = n / k % 1000;
  160. if (m != 0)
  161. {
  162. astring_append(textnumber_detail(m, result), base[i]);
  163. if (n % k != 0)
  164. astring_append(result, ", ");
  165. else break;
  166. }
  167. k /= 1000;
  168. }
  169. return result->first;
  170. }
  171.  
  172. //
  173. // Show.
  174. //
  175.  
  176. int main(int argc, char* argv[])
  177. {
  178. printf("%d\n%s\n\n", 0, textnumber(0));
  179. printf("%d\n%s\n\n", -1, textnumber(-1));
  180. printf("%d\n%s\n\n", 1000000, textnumber(1000000));
  181. printf("%d\n%s\n\n", 1000003, textnumber(1000003));
  182. printf("%d\n%s\n\n", 1002003, textnumber(1002003));
  183. printf("%ld\n%s\n\n", LONG_MAX, textnumber(LONG_MAX));
  184.  
  185. srand(time(0));
  186. for (int i = 0; i < 5; i++)
  187. {
  188. int x = rand() % 21 - 10;
  189. printf("%d\n%s\n\n", x, textnumber(x));
  190. }
  191. for (int i = 0; i < 5; i++)
  192. {
  193. int x = rand() % 201 - 100;
  194. printf("%d\n%s\n\n", x, textnumber(x));
  195. }
  196. for (int i = 0; i < 5; i++)
  197. {
  198. int x = rand() % 2001 - 1000;
  199. printf("%d\n%s\n\n", x, textnumber(x));
  200. }
  201. for (int i = 0; i < 5; i++)
  202. {
  203. int x = rand() - rand();
  204. printf("%d\n%s\n\n", x, textnumber(x));
  205. }
  206. return 0;
  207. }
Success #stdin #stdout 0s 5280KB
stdin
Standard input is empty
stdout
0
zero

-1
minus one

1000000
one million

1000003
one million, three

1002003
one million, two thousand, three

9223372036854775807
nine quintillion, two hundred and twenty-three quadrillion, three hundred and seventy-two trillion, thirty-six billion, eight hundred and fifty-four million, seven hundred and seventy-five thousand, eight hundred and seven

-2
minus two

5
five

0
zero

-8
minus eight

7
seven

61
sixty-one

-10
minus ten

-22
minus twenty-two

-84
minus eighty-four

-60
minus sixty

906
nine hundred and six

231
two hundred and thirty-one

-574
minus five hundred and seventy-four

770
seven hundred and seventy

533
five hundred and thirty-three

-548126886
minus five hundred and forty-eight million, one hundred and twenty-six thousand, eight hundred and eighty-six

-623571431
minus six hundred and twenty-three million, five hundred and seventy-one thousand, four hundred and thirty-one

-283271142
minus two hundred and eighty-three million, two hundred and seventy-one thousand, one hundred and forty-two

-607523002
minus six hundred and seven million, five hundred and twenty-three thousand, two

797028367
seven hundred and ninety-seven million, twenty-eight thousand, three hundred and sixty-seven