Task: Number names


C++: #include <string>
#include <iostream>
using std::string;

const char* smallNumbers[] = {
  "zero", "one", "two", "three", "four", "five",
  "six", "seven", "eight", "nine", "ten",
  "eleven", "twelve", "thirteen", "fourteen", "fifteen",
  "sixteen", "seventeen", "eighteen", "nineteen"
};
 
string spellHundreds(unsigned n) {
  string res;
  if (n > 99) {
    res = smallNumbers[n/100];
    res += " hundred";
    n %= 100;
    if (n) res += " and ";
  }
  if (n >= 20) {
    static const char* Decades[] = {
      "", "", "twenty", "thirty", "forty",
      "fifty", "sixty", "seventy", "eighty", "ninety"
    };
    res += Decades[n/10];
    n %= 10;
    if (n) res += "-";
  }
  if (n < 20 && n > 0)
    res += smallNumbers[n];
  return res;
}


const char* thousandPowers[] = {
  " billion", " million",  " thousand", "" };

typedef unsigned long Spellable;

string spell(Spellable n) {
  if (n < 20) return smallNumbers[n];
  string res;
  const char** pScaleName = thousandPowers;
  Spellable scaleFactor = 1000000000;	
  while (scaleFactor > 0) {
    if (n >= scaleFactor) {
      Spellable h = n / scaleFactor;
      res += spellHundreds(h) + *pScaleName;
      n %= scaleFactor;
      if (n) res += ", ";
    }
    scaleFactor /= 1000;
    ++pScaleName;
  }
  return res;
}

int main() {
#define SPELL_IT(x) std::cout << #x " " << spell(x) << std::endl;
  SPELL_IT(      99);
  SPELL_IT(     300);
  SPELL_IT(     310);
  SPELL_IT(    1501);
  SPELL_IT(   12609);
  SPELL_IT(  512609);
  SPELL_IT(43112609);
  SPELL_IT(1234567890);
  return 0;
}





PHP: $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){

      $str .= NumberToEnglish((int) substr((string) $num, 0, strlen((string) $num) - 3), $count + 1);
      $isLast = false;
   }

   if (($count == 0 || $isLast) && ($str == '' || $str == 'Negative '))

      $and = '';
   else
      $and = ' and ';

   if ($thisPart > 99){

      $str .= ($isLast ? '' : ' ') . "{$smallNumbers[$thisPart/100]} {$orderOfMag[0]}";

      if(($thisPart %= 100) == 0){

         $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){

      $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)

      return $str . "{$and}{$smallNumbers[(int) $thisPart]} " . ($count != 0 ? $orderOfMag[$count] : '');
   elseif ($thisPart == 0 && strlen($thisPart) == 1)

      return $str . "{$smallNumbers[(int)$thisPart]}";
}