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.


$orderOfMag = array('Hundred', 'Thousand,', 'Million,', 'Billion,', 'Trillion,');
$smallNumbers = array('Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen');
$decades = array('', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety');
 
function NumberToEnglish($num, $count = 0){
   global $orderOfMag, $smallNumbers, $decades;
   $isLast = true;
   $str = '';
 
   if ($num < 0){
      $str = 'Negative ';
      $num = abs($num);
   }
 
   (int) $thisPart = substr((string) $num, -3);
 
   if (strlen((string) $num) > 3){
      // Number still too big, work on a smaller chunk
      $str .= NumberToEnglish((int) substr((string) $num, 0, strlen((string) $num) - 3), $count + 1);
      $isLast = false;
   }
 
   // do translation stuff
   if (($count == 0 || $isLast) && ($str == '' || $str == 'Negative '))
      // This is either a very small number or the most significant digits of the number. Either way we don't want a preceeding "and"
      $and = '';
   else
      $and = ' and ';
 
   if ($thisPart > 99){
      // Hundreds part of the number chunk
      $str .= ($isLast ? '' : ' ') . "{$smallNumbers[$thisPart/100]} {$orderOfMag[0]}";
 
      if(($thisPart %= 100) == 0){
         // There is nothing else to do for this chunk (was a multiple of 100)
         $str .= " {$orderOfMag[$count]}";
         return $str;
      }
      $and = ' and ';  // Set up our and string to the word "and" since there is something in the hundreds place of this chunk
   }
 
   if ($thisPart >= 20){
      // Tens part of the number chunk
      $str .= "{$and}{$decades[$thisPart /10]}";
      $and = ' '; // Make sure we don't have any extranious "and"s
      if(($thisPart %= 10) == 0)
         return $str . ($count != 0 ? " {$orderOfMag[$count]}" : '');
   }
 
   if ($thisPart < 20 && $thisPart > 0)
      // Ones part of the number chunk
      return $str . "{$and}{$smallNumbers[(int) $thisPart]} " . ($count != 0 ? $orderOfMag[$count] : '');
   elseif ($thisPart == 0 && strlen($thisPart) == 1)
      // The number is zero
      return $str . "{$smallNumbers[(int)$thisPart]}";
}