Task

Show how to spell out a number in English.

You can use a preexisting implementation or roll your own, but you should support inputs up to at least one million (or the maximum value of your language's default bounded integer type, if that's less).

Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.



Related task

   Spelling of ordinal numbers.


   declare integer_names (0:20) character (9) varying static initial
      ('zero',  'one',   'two',  'three', 'four',   'five', 'six',
       'seven', 'eight', 'nine', 'ten',   'eleven', 'twelve',
       'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen',
       'eighteen', 'nineteen', 'twenty' );
   declare x(10) character (7) varying static initial
      ('ten', 'twenty', 'thirty', 'fourty', 'fifty',
       'sixty', 'seventy', 'eighty', 'ninety', 'hundred');
   declare y(0:5) character (10) varying static initial
      ('', '', ' thousand ', ' million ', ' billion ', ' trillion ');
   declare (i, j, m, t) fixed binary (31);
   declare (units, tens, hundreds, thousands) fixed binary (7);
   declare (h, v, value) character (200) varying;
   declare (d, k, n) fixed decimal (15);
   declare three_digits fixed decimal (3);
 
      value = '';
      i = 5;
      k = n;
      do d = 1000000000000 repeat d/1000 while (d > 0);
         i = i - 1;
         three_digits = k/d;
         k = mod(k, d);
         if three_digits = 0 then iterate;
 
         units = mod(three_digits, 10);
         t = three_digits / 10;
         tens = mod(t, 10);
         hundreds = three_digits / 100;
         m = mod(three_digits, 100);
         if m <= 20 then
            v = integer_names(m);
         else if units = 0 then
            v = '';
         else
            v = integer_names(units);
         if tens >= 2 & units ^= 0 then
            v = x(tens) || v;
         else if tens > 2 & units = 0 then
            v = v || x(tens);
 
         if units + tens = 0 then
            if n > 0 then  v = '';
         if hundreds > 0 then
            h = integer_names(hundreds) || ' hundred ';
         else
            h = '';
         if three_digits > 100 & (tens + units > 0) then
            v = 'and ' || v;
         if i = 1 & value ^= '' & three_digits <= 9 then
            v = 'and ' || v;
         value = value ||h || v || y(i);
      end;
      put skip edit (trim(N), ' = ', value) (a);