+8  A: 

There was already a question about this: http://stackoverflow.com/questions/3213/c-convert-integers-into-written-numbers

The answer is for C#, but I think you can figure it out.

GoodEnough
+1  A: 

Supports up to 999 million, but no negative numbers:

String humanReadable(int inputNumber) {
  if (inputNumber == -1) {
    return "";
  }
  int remainder;
  int quotient;
  quotient = inputNumber / 1000000;
  remainder = inputNumber % 1000000;
  if (quotient > 0) {
    return humanReadable(quotient) + " million, " + humanReadable(remainder);
  }
  quotient = inputNumber / 1000;
  remainder = inputNumber % 1000;
  if (quotient > 0) {
    return humanReadable(quotient) + " thousand, " + humanReadable(remainder);
  }
  quotient = inputNumber / 100;
  remainder = inputNumber % 100;
  if (quotient > 0) {
    return humanReadable(quotient) + " hundred, " + humanReadable(remainder);
  }
  quotient = inputNumber / 10;
  remainder = inputNumber % 10;
  if (remainder == 0) {
    //hackish way to flag the algorithm to not output something like "twenty zero"
    remainder = -1;
  }
  if (quotient == 1) {
    switch(inputNumber) {
    case 10:
      return "ten";
    case 11:
      return "eleven";
    case 12:
      return "twelve";
    case 13:
      return "thirteen";
    case 14:
      return "fourteen";
    case 15:
      return "fifteen";
    case 16:
      return "sixteen";
    case 17:
      return "seventeen";
    case 18:
      return "eighteen";
    case 19:
      return "nineteen";
    }
  }
  switch(quotient) {
  case 2:
    return "twenty " + humanReadable(remainder);
  case 3:
    return "thirty " + humanReadable(remainder);
  case 4:
    return "forty " + humanReadable(remainder);
  case 5:
    return "fifty " + humanReadable(remainder);
  case 6:
    return "sixty " + humanReadable(remainder);
  case 7:
    return "seventy " + humanReadable(remainder);
  case 8:
    return "eighty " + humanReadable(remainder);
  case 9:
    return "ninety " + humanReadable(remainder);
  }
  switch(inputNumber) {
  case 0:
    return "zero";
  case 1:
    return "one";
  case 2:
    return "two";
  case 3:
    return "three";
  case 4:
    return "four";
  case 5:
    return "five";
  case 6:
    return "six";
  case 7:
    return "seven";
  case 8:
    return "eight";
  case 9:
    return "nine";
  }
}
Ryan Ahearn
+3  A: 
import math

def encodeOnesDigit(num):
   return ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'][num]

def encodeTensDigit(num):
   return ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'][num-2]

def encodeTeens(num):
   if num < 10:
      return encodeOnesDigit(num)
   else:
      return ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'][num-10]

def encodeTriplet(num):
   if num == 0: return ''
   str = ''
   if num >= 100:
      str = encodeOnesDigit(num / 100) + ' hundred'
   tens = num % 100
   if tens >= 20:
      if str != '': str += ' '
      str += encodeTensDigit(tens / 10)
      if tens % 10 > 0:
         str += '-' + encodeOnesDigit(tens % 10)
   elif tens != 0:
      if str != '': str += ' '
      str += encodeTeens(tens)
   return str

def zipNumbers(numList):
   if len(numList) == 1:
      return numList[0]
   strList = ['', ' thousand', ' million', ' billion'] # Add more as needed
   strList = strList[:len(numList)]
   strList.reverse()
   joinedList = zip(numList, strList)
   joinedList = [item for item in joinedList if item[0] != '']
   return ', '.join(''.join(item) for item in joinedList)

def humanReadable(num):
   if num == 0: return 'zero'
   negative = False
   if num < 0:
      num *= -1
      negative = True
   numString = str(num)
   tripletCount = int(math.ceil(len(numString) / 3.0))
   numString = numString.zfill(tripletCount * 3)
   tripletList = [int(numString[i*3:i*3+3]) for i in range(tripletCount)]
   readableList = [encodeTriplet(num) for num in tripletList]
   readableStr = zipNumbers(readableList)
   return 'negative ' + readableStr if negative else readableStr
Daniel F. Hanson
+1  A: 
using System;

namespace HumanReadable
{
    public static class HumanReadableExt
    {
        private static readonly string[] _digits = {
                                                       "", "one", "two", "three", "four", "five",
                                                       "six", "seven", "eight", "nine", "eleven", "twelve",
                                                       "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
                                                       "eighteen", "nineteen"
                                                   };

        private static readonly string[] _teens = {
                                                      "", "", "twenty", "thirty", "forty", "fifty",
                                                      "sixty", "seventy", "eighty", "ninety"
                                                  };

        private static readonly string[] _illions = {
                                                        "", "thousand", "million", "billion", "trillion"
                                                    };

        private static string Seg(int number)
        {
            var work = string.Empty;

            if (number >= 100) 
                work += _digits[number / 100] + " hundred ";

            if ((number % 100) < 20)
                work += _digits[number % 100];
            else
                work += _teens[(number % 100) / 10] + "-" + _digits[number % 10];

            return work;
        }

        public static string HumanReadable(this int number)
        {
            if (number == 0)
                return "zero";
            var work = string.Empty;

            var parts = new string[_illions.Length];

            for (var ind = 0; ind < parts.Length; ind++)
                parts[ind] = Seg((int) (number % Math.Pow(1000, ind + 1) / Math.Pow(1000, ind)));

            for (var ind = 0; ind < parts.Length; ind++)
                if (!string.IsNullOrEmpty(parts[ind]))
                    work = parts[ind] + " " + _illions[ind] + ", " + work;

            work = work.TrimEnd(',', ' ');

            var lastSpace = work.LastIndexOf(' ');
            if (lastSpace >= 0)
                work = work.Substring(0, lastSpace) + " and" + work.Substring(lastSpace);

            return work;
        }
    }

    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine(1.HumanReadable());
            Console.WriteLine(53.HumanReadable());
            Console.WriteLine(723603.HumanReadable());
            Console.WriteLine(1456376562.HumanReadable());
            Console.ReadLine();
        }
    }
}
Stu
A: 

There's one huge problem about this function implementation. It is it's future localization. That function, written by english native speaker, most probably wouldn't work right for any other language than english. It is nearly impossible to write general easy localizable function for any human language dialect in a world, unless you really need to keep it general. Actually in real world you do not need to operate with huge integer numbers, so you can just keep all the numbers in a big (or even not so big) string array.

akalenuk
A: 

agreed that there are a number of real world applications. as such there's already a number of real world implementations.

it's been part of bsdgames since pretty much forever...

> man number
matpalm