fork(1) download
  1. // Convert a signed long integer to English text. (2.01)
  2. // @see dwYRr9
  3.  
  4. #include <stdlib.h>
  5. #include <limits.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <stdio.h>
  9. #include <time.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_lower(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. int hundred = n / 100 % 10;
  80. int ten = n / 10 % 10;
  81. int one = n % 10;
  82.  
  83. if (hundred)
  84. {
  85. astring_append(result, ones[hundred]);
  86. astring_append(result, " hundred");
  87. if (ten || one)
  88. astring_append(result, " and ");
  89. }
  90.  
  91. if (ten == 0)
  92. {
  93. astring_append(result, ones[one]);
  94. }
  95. else if (ten == 1)
  96. {
  97. astring_append(result, teens[one]);
  98. }
  99. else
  100. {
  101. astring_append(result, tens[ten]);
  102. if (one)
  103. {
  104. astring_append(result, "-");
  105. astring_append(result, ones[one]);
  106. }
  107. }
  108. return result;
  109. }
  110.  
  111. const char* textnumber(long int n)
  112. {
  113. assert(n > LONG_MIN || LONG_MIN + LONG_MAX == 0);
  114.  
  115. static const char* base[] = {
  116. "",
  117. " thousand",
  118. " million",
  119. " billion",
  120. " trillion",
  121. " quadrillion",
  122. " quintillion"
  123. };
  124.  
  125. static _Thread_local struct astring result[1];
  126. result->last = result->first;
  127.  
  128. if (n == 0)
  129. {
  130. astring_append(result, "zero");
  131. return result->first;
  132. }
  133.  
  134. if (n < 0)
  135. {
  136. astring_append(result, "minus ");
  137. n = -n;
  138. }
  139.  
  140. const long int k = 1000;
  141. long int k_to_j = 1;
  142. int j = 0;
  143.  
  144. for (long int i = n; i >= k; i /= k)
  145. {
  146. k_to_j *= k;
  147. j += 1;
  148. }
  149.  
  150. for (; j >= 0; j--)
  151. {
  152. long int m = n / k_to_j % k;
  153. if (m != 0)
  154. {
  155. astring_append(textnumber_lower(m, result), base[j]);
  156. if (n % k_to_j != 0)
  157. astring_append(result, ", ");
  158. else break;
  159. }
  160. k_to_j /= k;
  161. }
  162. return result->first;
  163. }
  164.  
  165. //
  166. // Show.
  167. //
  168.  
  169. int main(int argc, char* argv[])
  170. {
  171. printf("%d\n%s\n\n", 0, textnumber(0));
  172. printf("%d\n%s\n\n", -1, textnumber(-1));
  173. printf("%d\n%s\n\n", 1000000, textnumber(1000000));
  174. printf("%d\n%s\n\n", 1000003, textnumber(1000003));
  175. printf("%d\n%s\n\n", 1002003, textnumber(1002003));
  176. printf("%ld\n%s\n\n", LONG_MAX, textnumber(LONG_MAX));
  177.  
  178. srand(time(0));
  179. for (int i = 0; i < 5; i++)
  180. {
  181. int x = rand() % 21 - 10;
  182. printf("%d\n%s\n\n", x, textnumber(x));
  183. }
  184. for (int i = 0; i < 5; i++)
  185. {
  186. int x = rand() % 201 - 100;
  187. printf("%d\n%s\n\n", x, textnumber(x));
  188. }
  189. for (int i = 0; i < 5; i++)
  190. {
  191. int x = rand() % 2001 - 1000;
  192. printf("%d\n%s\n\n", x, textnumber(x));
  193. }
  194. for (int i = 0; i < 5; i++)
  195. {
  196. int x = rand() - rand();
  197. printf("%d\n%s\n\n", x, textnumber(x));
  198. }
  199. return 0;
  200. }
Success #stdin #stdout 0s 5288KB
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

-1
minus one

8
eight

1
one

-2
minus two

4
four

-30
minus thirty

-20
minus twenty

40
forty

64
sixty-four

11
eleven

-586
minus five hundred and eighty-six

-605
minus six hundred and five

-845
minus eight hundred and forty-five

890
eight hundred and ninety

-662
minus six hundred and sixty-two

-347888413
minus three hundred and forty-seven million, eight hundred and eighty-eight thousand, four hundred and thirteen

-1851565071
minus one billion, eight hundred and fifty-one million, five hundred and sixty-five thousand, seventy-one

336058241
three hundred and thirty-six million, fifty-eight thousand, two hundred and forty-one

-19933339
minus nineteen million, nine hundred and thirty-three thousand, three hundred and thirty-nine

-215634544
minus two hundred and fifteen million, six hundred and thirty-four thousand, five hundred and forty-four