Reputation: 131879
In PHP, is there an easy way to convert a number to a word? For instance, 27 to twenty-seven.
Upvotes: 47
Views: 72761
Reputation: 5
I have generated this using a recursive function:
$wordnum = numberToWord($number);
echo $wordnum."<BR>";
function singledigit($number){
switch($number){
case 0:$word = "zero";break;
case 1:$word = "One";break;
case 2:$word = "two";break;
case 3:$word = "three";break;
case 4:$word = "Four";break;
case 5:$word = "Five";break;
case 6:$word = "Six";break;
case 7:$word = "Seven";break;
case 8:$word = "Eight";break;
case 9:$word = "Nine";break;
}
return $word;
}
function doubledigitnumber($number){
if($number == 0){
$word = "";
}
else{
$word = singledigit($number);
}
return $word;
}
function doubledigit($number){
switch($number[0]){
case 0:$word = doubledigitnumber($number[1]);break;
case 1:
switch($number[1]){
case 0:$word = "Ten";break;
case 1:$word = "Eleven";break;
case 2:$word = "Twelve";break;
case 3:$word = "Thirteen";break;
case 4:$word = "Fourteen";break;
case 5:$word = "Fifteen";break;
case 6:$word = "Sixteen";break;
case 7:$word = "Seventeen";break;
case 8:$word = "Eighteen";break;
case 9:$word = "Ninteen";break;
}break;
case 2:$word = "Twenty".doubledigitnumber($number[1]);break;
case 3:$word = "Thirty".doubledigitnumber($number[1]);break;
case 4:$word = "Forty".doubledigitnumber($number[1]);break;
case 5:$word = "Fifty".doubledigitnumber($number[1]);break;
case 6:$word = "Sixty".doubledigitnumber($number[1]);break;
case 7:$word = "Seventy".doubledigitnumber($number[1]);break;
case 8:$word = "Eighty".doubledigitnumber($number[1]);break;
case 9:$word = "Ninety".doubledigitnumber($number[1]);break;
}
return $word;
}
function unitdigit($numberlen,$number){
switch($numberlen){
case 3:$word = "Hundred";break;
case 4:$word = "Thousand";break;
case 5:$word = "Thousand";break;
case 6:$word = "Lakh";break;
case 7:$word = "Lakh";break;
case 8:$word = "Crore";break;
case 9:$word = "Crore";break;
}
return $word;
}
function numberToWord($number){
$numberlength = strlen($number);
if ($numberlength == 1) {
return singledigit($number);
}elseif ($numberlength == 2) {
return doubledigit($number);
}
else {
$word = "";
$wordin = "";
if($numberlength == 9){
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = doubledigit($number[0].$number[1]) ." ".$unitdigit." ";
return $word." ".numberToWord(substr($number,2));
}
else{
return $word." ".numberToWord(substr($number,1));
}
}
if($numberlength == 7){
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = doubledigit($number[0].$number[1]) ." ".$unitdigit." ";
return $word." ".numberToWord(substr($number,2));
}
else{
return $word." ".numberToWord(substr($number,1));
}
}
if($numberlength == 5){
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = doubledigit($number[0].$number[1]) ." ".$unitdigit." ";
return $word." ".numberToWord(substr($number,2));
}
else{
return $word." ".numberToWord(substr($number,1));
}
}
else{
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = singledigit($number[0]) ." ".$unitdigit." ";
}
return $word." ".numberToWord(substr($number,1));
}
}
}
Upvotes: -3
Reputation: 5
Amount in Words:</b><?=no_to_words($number)?>
A very simple way to convert numbers to words using the PHP function.
Upvotes: -3
Reputation: 662
protected function numberTextHelper($number)
{
if (($number < 0) || ($number > 999999999))
{
throw new Exception("Number is out of range");
}
$ones = array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eightteen", "Nineteen");
$tens = array("", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eigthy", "Ninety");
$giga = floor($number / 1000000);
// Millions (giga)
$number -= $giga * 1000000;
$thousands = floor($number / 1000);
// Thousands (kilo)
$number -= $thousands * 1000;
$hecto = floor($number / 100);
// Hundreds (hecto)
$number -= $hecto * 100;
$deca = floor($number / 10);
// Tens (deca)
$n = $number % 10;
$frac = round($number - (int)$number,2);
// Ones
$result = array();
if ($giga)
{
$result[]= $this->numberTextHelper($giga).' '.($giga>1?'MILLIONS':'MILLION');
}
if ($thousands)
{
$result[]= $thousands>1?$this->numberTextHelper($thousands).' THOUSANDS':'THOUSAND';
}
if ($hecto)
{
$result[]= $this->numberTextHelper($hecto).'HUNDRED';
}
if ($deca)
{
if($deca<2)
{
$result[]= $ones[$deca * 10 + $n];
$n=0;
}
else
{
$result[]= $tens[$deca];
}
}
if ($n)
{
$result[]= $ones[$n];
}
if($frac)
{
$result[]= 'and';
$result[]= $this->numberTextHelper($frac*100);
$result[]= 'cents';
}
if(empty($result))
{
$result[]= 'zero';
}
return implode(' ',$result);
}
And you can translate it
function numberText($number)
{
$result=$this->numberTextHelper($number);
$result=$this->strtoupper($result);
$text=array_filter(explode(' ',$result));
$translated=array_map(array($this,'getLang'),$text);
return implode(' ',$translated);
}
Upvotes: 1
Reputation: 868
The below code is working fine
$test = 1000025.05;
$f = new \NumberFormatter( locale_get_default(), \NumberFormatter::SPELLOUT );
$word = $f->format($test);
echo $word;
Upvotes: 1
Reputation: 331
<?php
$grandTotalAmount = 700000000;
echo ($grandTotalAmount == round($grandTotalAmount)) ? convert_number_to_words(floatval($grandTotalAmount)) . ' Only' : convert_number_to_words(floatval($grandTotalAmount)) . ' Only';
function convert_number_to_words($number) {
$hyphen = ' ';
$conjunction = ' and ';
$separator = ', ';
$negative = 'negative ';
$decimal = ' Thai Baht And ';
$dictionary = array(
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'fourty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
1000000 => 'million',
1000000000 => 'billion',
1000000000000 => 'trillion',
1000000000000000 => 'quadrillion',
1000000000000000000 => 'quintillion'
);
if (!is_numeric($number)) {
return false;
}
if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
// overflow
trigger_error(
'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX, E_USER_WARNING
);
return false;
}
if ($number < 0) {
return $negative . convert_number_to_words(abs($number));
}
$string = $fraction = null;
if (strpos($number, '.') !== false) {
list($number, $fraction) = explode('.', $number);
}
switch (true) {
case $number < 21:
$string = $dictionary[$number];
break;
case $number < 100:
$tens = ((int) ($number / 10)) * 10;
$units = $number % 10;
$string = $dictionary[$tens];
if ($units) {
$string .= $hyphen . $dictionary[$units];
}
break;
case $number < 1000:
$hundreds = $number / 100;
$remainder = $number % 100;
$string = $dictionary[$hundreds] . ' ' . $dictionary[100];
if ($remainder) {
$string .= $conjunction . convert_number_to_words($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int) ($number / $baseUnit);
$remainder = $number % $baseUnit;
$string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit];
if ($remainder) {
$string .= $remainder < 100 ? $conjunction : $separator;
$string .= convert_number_to_words($remainder);
}
break;
}
if (null !== $fraction && is_numeric($fraction)) {
$string .= $decimal;
$words = array();
foreach (str_split((string) $fraction) as $number) {
$words[] = $dictionary[$number];
}
$string .= implode(' ', $words);
}
return $string;
}
?>
Upvotes: 1
Reputation: 844
Yes there is. without using a library you just need to follow this..
First you need to check in your server if ;extension=php_intl.dll
is enabled in your php.ini if still not work you need to see this answer.
intl extension php_intl.dll with wamp
after successfully moving all the files starts with icu.
from: <wamp_installation_path>/bin/php/php5.4.3/
to: <wamp_installation_path>/bin/apache/apache2.2.22/bin/
and restart your server.
try to run this code:
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format(123456);
it will show the output of one hundred twenty-three thousand four hundred fifty-six.
hope that helps everyone :).
Upvotes: 2
Reputation: 184
You can use the NumberFormatter Class:
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format($myNumber);
Upvotes: 4
Reputation: 423
Using NumberFormatter class it is simple to get convert to words.
<?php
$number = '12345';
$locale = 'en_US';
$fmt = numfmt_create($locale, NumberFormatter::SPELLOUT);
$in_words = numfmt_format($fmt, $number);
print_r($in_words);
// twelve thousand three hundred forty-five
?>
Upvotes: 9
Reputation: 103
I needed a solution that put 'and' into the returned string and formatted it into a sentence - typically as a human would say it. So I adapted a different solution slightly - posted as I thought this could be useful for someone.
4,835,301 returns "Four million eight hundred and thirty five thousand three hundred and one."
Code
function convertNumber($num = false)
{
$num = str_replace(array(',', ''), '' , trim($num));
if(! $num) {
return false;
}
$num = (int) $num;
$words = array();
$list1 = array('', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
);
$list2 = array('', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety', 'hundred');
$list3 = array('', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion',
'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion',
'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion'
);
$num_length = strlen($num);
$levels = (int) (($num_length + 2) / 3);
$max_length = $levels * 3;
$num = substr('00' . $num, -$max_length);
$num_levels = str_split($num, 3);
for ($i = 0; $i < count($num_levels); $i++) {
$levels--;
$hundreds = (int) ($num_levels[$i] / 100);
$hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' hundred' . ( $hundreds == 1 ? '' : '' ) . ' ' : '');
$tens = (int) ($num_levels[$i] % 100);
$singles = '';
if ( $tens < 20 ) {
$tens = ($tens ? ' and ' . $list1[$tens] . ' ' : '' );
} elseif ($tens >= 20) {
$tens = (int)($tens / 10);
$tens = ' and ' . $list2[$tens] . ' ';
$singles = (int) ($num_levels[$i] % 10);
$singles = ' ' . $list1[$singles] . ' ';
}
$words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' );
} //end for loop
$commas = count($words);
if ($commas > 1) {
$commas = $commas - 1;
}
$words = implode(' ', $words);
$words = preg_replace('/^\s\b(and)/', '', $words );
$words = trim($words);
$words = ucfirst($words);
$words = $words . ".";
return $words;
}
Upvotes: 7
Reputation: 1293
Here's a small class I wrote tonight. Caveats:
longform
method doesn't handle decimals. It just erases them. Feel free to modify this and add that functionality if you wish. numberformat
method does do decimals, but doesn't do any rounding. I had to create a new numberformat
function because of PHP's inherent limitations with integer sizes. I was translating numbers so big that when I used number_format()
to check my translations, it took me 30 minutes to realize my translations weren't wrong, number_format
was. 2,147,483,647
(2 billion and change). 64-bit versions will handle up to like 9 quintillion
or something. BUT that's irrelevant here as long as you feed the numbers to the longform
method as a string
. I did a 306-digit number over ajax
from a webform just fine, as long as I passed it to the server as ''+number
. So, this class will translate numbers up to 999 Centillion, 999 etc.
(e.g., a string of 9s 306 characters long). Any number bigger than that and the function just returns a dumb message.
Usage:
$number = '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999';
reallyBig::longform($number);
The optional second boolean parameter defaults to true, which adds commas as best it can in the right places, to make the number more readable.
By the way, you can put a -
at the front if you want it to be negative, but any other characters included in the inputted string will be stripped out. For instance:
reallyBig::longform('-C55LL-M5-4-a-9u7-71m3-M8');
will output: negative five billion, five hundred fifty-four million, nine hundred seventy-seven thousand, one hundred thirty-eight
The numberformat
method isn't necessary for any other method. It's just there if you want to check a really long translated number. Since all these functions handle numbers as strings, they don't run up against PHP's limitations.
The only reason I stopped at a 999 centillion is because centillion was the last number on the website I was looking at when I couldn't remember what came after a decillion.
class reallyBig
{
private static $map, $strings;
private static function map()
{
$map = array();
$num = 1;
$count = 1;
while($num < 307)
{
if($count == 1) $map[$num] = $num+2;
elseif($count == 2) $map[$num] = $num+1;
else
{
$map[$num] = $num;
$count = 0;
}
$count++;
$num++;
}
return $map;
}
private static function strings()
{
return array
(
6 => 'thousand',
9 => 'million',
12 => 'billion',
15 => 'trillion',
18 => 'quadrillion',
21 => 'quintillion',
24 => 'sextillion',
27 => 'septillion',
30 => 'octillion',
33 => 'nonillion',
36 => 'decillion',
39 => 'undecillion',
42 => 'duodecillion',
45 => 'tredecillion',
48 => 'quattuordecillion',
51 => 'quindecillion',
54 => 'sexdecillion',
57 => 'septendecillion',
60 => 'octodecillion',
63 => 'novemdecillion',
66 => 'vigintillion',
69 => 'unvigintillion',
72 => 'duovigintillion',
75 => 'trevigintillion',
78 => 'quattuorvigintillion',
81 => 'quinvigintillion',
84 => 'sexvigintillion',
87 => 'septenvigintillion',
90 => 'octovigintillion',
93 => 'novemvigintillion',
96 => 'trigintillion',
99 => 'untrigintillion',
102 => 'duotrigintillion',
105 => 'tretrigintillion',
108 => 'quattuortrigintillion',
111 => 'quintrigintillion',
114 => 'sextrigintillion',
117 => 'septentrigintillion',
120 => 'octotrigintillion',
123 => 'novemtrigintillion',
126 => 'quadragintillion',
129 => 'unquadragintillion',
132 => 'duoquadragintillion',
135 => 'trequadragintillion',
138 => 'quattuorquadragintillion',
141 => 'quinquadragintillion',
144 => 'sexquadragintillion',
147 => 'septenquadragintillion',
150 => 'octoquadragintillion',
153 => 'novemquadragintillion',
156 => 'quinquagintillion',
159 => 'unquinquagintillion',
162 => 'duoquinquagintillion',
165 => 'trequinquagintillion',
168 => 'quattuorquinquagintillion',
171 => 'quinquinquagintillion',
174 => 'sexquinquagintillion',
177 => 'septenquinquagintillion',
180 => 'octoquinquagintillion',
183 => 'novemquinquagintillion',
186 => 'sexagintillion',
189 => 'unsexagintillion',
192 => 'duosexagintillion',
195 => 'tresexagintillion',
198 => 'quattuorsexagintillion',
201 => 'quinsexagintillion',
204 => 'sexsexagintillion',
207 => 'septensexagintillion',
210 => 'octosexagintillion',
213 => 'novemsexagintillion',
216 => 'septuagintillion',
219 => 'unseptuagintillion',
222 => 'duoseptuagintillion',
225 => 'treseptuagintillion',
228 => 'quattuorseptuagintillion',
231 => 'quinseptuagintillion',
234 => 'sexseptuagintillion',
237 => 'septenseptuagintillion',
240 => 'octoseptuagintillion',
243 => 'novemseptuagintillion',
246 => 'octogintillion',
249 => 'unoctogintillion',
252 => 'duooctogintillion',
255 => 'treoctogintillion',
258 => 'quattuoroctogintillion',
261 => 'quinoctogintillion',
264 => 'sexoctogintillion',
267 => 'septenoctogintillion',
270 => 'octooctogintillion',
273 => 'novemoctogintillion',
276 => 'nonagintillion',
279 => 'unnonagintillion',
282 => 'duononagintillion',
285 => 'trenonagintillion',
288 => 'quattuornonagintillion',
291 => 'quinnonagintillion',
294 => 'sexnonagintillion',
297 => 'septennonagintillion',
300 => 'octononagintillion',
303 => 'novemnonagintillion',
306 => 'centillion',
);
}
public static function longform($number = string, $commas = true)
{
$negative = substr($number, 0, 1) == '-' ? 'negative ' : '';
list($number) = explode('.', $number);
$number = trim(preg_replace("/[^0-9]/u", "", $number));
$number = (string)(ltrim($number,'0'));
if(empty($number)) return 'zero';
$length = strlen($number);
if($length < 2) return $negative.self::ones($number);
if($length < 3) return $negative.self::tens($number);
if($length < 4) return $commas ? $negative.str_replace('hundred ', 'hundred and ', self::hundreds($number)) : $negative.self::hundreds($number);
if($length < 307)
{
self::$map = self::map();
self::$strings = self::strings();
$result = self::beyond($number, self::$map[$length]);
if(!$commas) return $negative.$result;
$strings = self::$strings;
$thousand = array_shift($strings);
foreach($strings as $string) $result = str_replace($string.' ', $string.', ', $result);
if(strpos($result, 'thousand') !== false) list($junk,$remainder) = explode('thousand', $result);
else $remainder = $result;
return strpos($remainder, 'hundred') !== false ? $negative.str_replace('thousand ', 'thousand, ', $result) : $negative.str_replace('thousand ', 'thousand and ', $result);
}
return 'a '.$negative.'number too big for your britches';
}
private static function ones($number)
{
$ones = array('zero','one','two','three','four','five','six','seven','eight','nine');
return $ones[$number];
}
private static function tens($number)
{
$number = (string)(ltrim($number,'0'));
if(strlen($number) < 2) return self::ones($number);
if($number < 20)
{
$teens = array('ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen');
return $teens[($number-10)];
}
else
{
$tens = array('','','twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety');
$word = $tens[$number[0]];
return empty($number[1]) ? $word : $word.'-'.self::ones($number[1]);
}
}
private static function hundreds($number)
{
$number = (string)(ltrim($number,'0'));
if(strlen($number) < 3) return self::tens($number);
$word = self::ones($number[0]).' hundred';
$remainder = substr($number, -2);
if(ltrim($remainder,'0') != '') $word .= ' '.self::tens($remainder);
return $word;
}
private static function beyond($number, $limit)
{
$number = (string)(ltrim($number,'0'));
$length = strlen($number);
if($length < 4) return self::hundreds($number);
if($length < ($limit-2)) return self::beyond($number, self::$map[($limit-3)]);
if($length == $limit) $word = self::hundreds(substr($number, 0, 3), true);
elseif($length == ($limit-1)) $word = self::tens(substr($number, 0, 2));
else $word = self::ones($number[0]);
$word .= ' '.self::$strings[$limit];
$sub = ($limit-3);
$remainder = substr($number, -$sub);
if(ltrim($remainder,'0') != '') $word .= ' '.self::beyond($remainder, self::$map[$sub]);
return $word;
}
public static function numberformat($number, $fixed = 0, $dec = '.', $thou = ',')
{
$negative = substr($number, 0, 1) == '-' ? '-' : '';
$number = trim(preg_replace("/[^0-9\.]/u", "", $number));
$number = (string)(ltrim($number,'0'));
$fixed = (int)$fixed;
if(!is_numeric($fixed)) $fixed = 0;
if(strpos($number, $dec) !== false) list($number,$decimals) = explode($dec, $number);
else $decimals = '0';
if($fixed) $decimals = '.'.str_pad(substr($decimals, 0, $fixed), $fixed, 0, STR_PAD_RIGHT);
else $decimals = '';
$thousands = array_map('strrev', array_reverse(str_split(strrev($number), 3)));
return $negative.implode($thou,$thousands).$decimals;
}
}
Upvotes: 1
Reputation: 711
Alternatively, you can use the NumberFormatter class from intl
package in PHP . Here's a sample code to get you started (for commandline):
<?php
if ($argc < 3)
{
echo "usage: php {$argv[0]} lang-tag number ...\n";
exit;
}
array_shift($argv);
$lang_tag = array_shift($argv);
$nf1 = new NumberFormatter($lang_tag, NumberFormatter::DECIMAL);
$nf2 = new NumberFormatter($lang_tag, NumberFormatter::SPELLOUT);
foreach ($argv as $num)
{
echo $nf1->format($num).' is '.$nf2->format($num)."\n";
}
Upvotes: 38
Reputation: 3102
I found some (2007/2008) source-code online and as it is copyright but I can use it freely and modify it however I want, so I place it here and re-license under CC-Wiki:
<?php
/**
* English Number Converter - Collection of PHP functions to convert a number
* into English text.
*
* This exact code is licensed under CC-Wiki on Stackoverflow.
* http://creativecommons.org/licenses/by-sa/3.0/
*
* @link http://stackoverflow.com/q/277569/367456
* @question Is there an easy way to convert a number to a word in PHP?
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2007-2008 Brenton Fletcher. http://bloople.net/num2text
* You can use this freely and modify it however you want.
*/
function convertNumber($number)
{
list($integer, $fraction) = explode(".", (string) $number);
$output = "";
if ($integer{0} == "-")
{
$output = "negative ";
$integer = ltrim($integer, "-");
}
else if ($integer{0} == "+")
{
$output = "positive ";
$integer = ltrim($integer, "+");
}
if ($integer{0} == "0")
{
$output .= "zero";
}
else
{
$integer = str_pad($integer, 36, "0", STR_PAD_LEFT);
$group = rtrim(chunk_split($integer, 3, " "), " ");
$groups = explode(" ", $group);
$groups2 = array();
foreach ($groups as $g)
{
$groups2[] = convertThreeDigit($g{0}, $g{1}, $g{2});
}
for ($z = 0; $z < count($groups2); $z++)
{
if ($groups2[$z] != "")
{
$output .= $groups2[$z] . convertGroup(11 - $z) . (
$z < 11
&& !array_search('', array_slice($groups2, $z + 1, -1))
&& $groups2[11] != ''
&& $groups[11]{0} == '0'
? " and "
: ", "
);
}
}
$output = rtrim($output, ", ");
}
if ($fraction > 0)
{
$output .= " point";
for ($i = 0; $i < strlen($fraction); $i++)
{
$output .= " " . convertDigit($fraction{$i});
}
}
return $output;
}
function convertGroup($index)
{
switch ($index)
{
case 11:
return " decillion";
case 10:
return " nonillion";
case 9:
return " octillion";
case 8:
return " septillion";
case 7:
return " sextillion";
case 6:
return " quintrillion";
case 5:
return " quadrillion";
case 4:
return " trillion";
case 3:
return " billion";
case 2:
return " million";
case 1:
return " thousand";
case 0:
return "";
}
}
function convertThreeDigit($digit1, $digit2, $digit3)
{
$buffer = "";
if ($digit1 == "0" && $digit2 == "0" && $digit3 == "0")
{
return "";
}
if ($digit1 != "0")
{
$buffer .= convertDigit($digit1) . " hundred";
if ($digit2 != "0" || $digit3 != "0")
{
$buffer .= " and ";
}
}
if ($digit2 != "0")
{
$buffer .= convertTwoDigit($digit2, $digit3);
}
else if ($digit3 != "0")
{
$buffer .= convertDigit($digit3);
}
return $buffer;
}
function convertTwoDigit($digit1, $digit2)
{
if ($digit2 == "0")
{
switch ($digit1)
{
case "1":
return "ten";
case "2":
return "twenty";
case "3":
return "thirty";
case "4":
return "forty";
case "5":
return "fifty";
case "6":
return "sixty";
case "7":
return "seventy";
case "8":
return "eighty";
case "9":
return "ninety";
}
} else if ($digit1 == "1")
{
switch ($digit2)
{
case "1":
return "eleven";
case "2":
return "twelve";
case "3":
return "thirteen";
case "4":
return "fourteen";
case "5":
return "fifteen";
case "6":
return "sixteen";
case "7":
return "seventeen";
case "8":
return "eighteen";
case "9":
return "nineteen";
}
} else
{
$temp = convertDigit($digit2);
switch ($digit1)
{
case "2":
return "twenty-$temp";
case "3":
return "thirty-$temp";
case "4":
return "forty-$temp";
case "5":
return "fifty-$temp";
case "6":
return "sixty-$temp";
case "7":
return "seventy-$temp";
case "8":
return "eighty-$temp";
case "9":
return "ninety-$temp";
}
}
}
function convertDigit($digit)
{
switch ($digit)
{
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";
}
}
Upvotes: 44
Reputation: 62573
There is the Numbers_Words
package in PECL. It does exactly what you ask for. The following languages are supported:
Upvotes: 9
Reputation: 31
I rewrote the code above to fit the standard U.S. written word number format.
function singledigit($number){
switch($number){
case 0:$word = "zero";break;
case 1:$word = "one";break;
case 2:$word = "two";break;
case 3:$word = "three";break;
case 4:$word = "four";break;
case 5:$word = "five";break;
case 6:$word = "six";break;
case 7:$word = "seven";break;
case 8:$word = "eight";break;
case 9:$word = "nine";break;
}
return $word;
}
function doubledigitnumber($number){
if($number == 0){
$word = "";
}
else{
$word = "-".singledigit($number);
}
return $word;
}
function doubledigit($number){
switch($number[0]){
case 0:$word = doubledigitnumber($number[1]);break;
case 1:
switch($number[1]){
case 0:$word = "ten";break;
case 1:$word = "eleven";break;
case 2:$word = "twelve";break;
case 3:$word = "thirteen";break;
case 4:$word = "fourteen";break;
case 5:$word = "fifteen";break;
case 6:$word = "sixteen";break;
case 7:$word = "seventeen";break;
case 8:$word = "eighteen";break;
case 9:$word = "ninteen";break;
}break;
case 2:$word = "twenty".doubledigitnumber($number[1]);break;
case 3:$word = "thirty".doubledigitnumber($number[1]);break;
case 4:$word = "forty".doubledigitnumber($number[1]);break;
case 5:$word = "fifty".doubledigitnumber($number[1]);break;
case 6:$word = "sixty".doubledigitnumber($number[1]);break;
case 7:$word = "seventy".doubledigitnumber($number[1]);break;
case 8:$word = "eighty".doubledigitnumber($number[1]);break;
case 9:$word = "ninety".doubledigitnumber($number[1]);break;
}
return $word;
}
function unitdigit($numberlen,$number){
switch($numberlen){
case 3:case 6:case 9:case 12:$word = "hundred";break;
case 4:case 5:$word = "thousand";break;
case 7:case 8:$word = "million";break;
case 10:case 11:$word = "billion";break;
}
return $word;
}
function numberToWord($number){
$numberlength = strlen($number);
if ($numberlength == 1) {
return singledigit($number);
}elseif ($numberlength == 2) {
return doubledigit($number);
}
else {
$word = "";
$wordin = "";
switch ($numberlength ) {
case 5:case 8: case 11:
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = doubledigit($number[0].$number[1]) ." ".$unitdigit." ";
return $word." ".numberToWord(substr($number,2));
}
else{
return $word." ".numberToWord(substr($number,1));
}
break;
default:
if($number[0] >0){
$unitdigit = unitdigit($numberlength,$number[0]);
$word = singledigit($number[0]) ." ".$unitdigit." ";
}
return $word." ".numberToWord(substr($number,1));
}
}
}
Upvotes: 3