PHP: Express Number in Words [duplicate] - php

This question already has answers here:
Is there an easy way to convert a number to a word in PHP?
(14 answers)
Closed 6 years ago.
Is there a function that will express any given number in words?
For example:
If a number is 1432, then this function will return "One thousand four hundred and thirty two".

Use the NumberFormatter class that are in php ;)
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format(1432);
That would output "one thousand four hundred thirty-two"

You can do this in many ways I am mentioning here two ways by using The NumberFormatter class as mentioned in Martindilling answer (if you have php version 5.3.0 or higher and also PECL extension 1.0.0 or higher) or by using the following custom function.
function convertNumberToWord($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' . ' ' : '');
$tens = (int) ($num_levels[$i] % 100);
$singles = '';
if ( $tens < 20 ) {
$tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' );
} else {
$tens = (int)($tens / 10);
$tens = ' ' . $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;
}
return implode(' ', $words);
}

Yes, http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/
However this is pretty dirty example. Please use NumberFormatter from intl (this will work from PHP 5.3)
$f = new NumberFormatter("in", NumberFormatter::SPELLOUT);
echo $f->format(123456);

In case of using Yii2 you can do this as simple as the following:
$sum = 100500;
echo Yii::$app->formatter->asSpellout($sum);
This prints spelled out $sum in your app's language.
Docs reference

Related

PHP how to convert number (year) to text ex. 1996 = Ninteen Ninty six, and 2004 = Two thousand four

I have a certificate I want to convert year to text but in the given format
convertYearToText(1994){
return "Ninteen hundred ninty six";
}
convertYearToText(2004){
return "two thousand four";
}
I have a function but it gives me One Thousand Nine Hundred Ninety-Six
numberTowords(1996)
{
$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' . ' ' : '');
$tens = (int) ($num_levels[$i] % 100);
$singles = '';
if ( $tens < 20 ) {
$tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' );
} else {
$tens = (int)($tens / 10);
$tens = ' ' . $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;
}
return implode(' ', $words);
}
I need the return result to be "nineteen hundred ninety-six"
please help
I took the liberty of rewriting and cleaning up your function, adding one crucial part: the conversion from
(a) One Thousand Nine Hundred Ninety Six to (b) Nineteen Hundred Ninety Six.
The function now accepts a optional second argument $year. If set to true, it will return (b), otherwise (a).
numberTowords(1996) will give (a)
numberTowords(1996,true) will give (b)
The comments in de code show what I've changed
function numberTowords($num,$year=false){
$num = str_replace(array(',', ' '), '' , trim($num));
if($num==='')return false;
$num = (int) $num;
$words = [];
$list=[
1=>['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'],
2=>['', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety', 'hundred'],
3=>['', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion','octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion','quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion']
];
//$levels = number of parts of 3
$levels = ceil(strlen($num)/3);
if($levels===0)return false;
//$parts = parts of 3, first one left-padded with zeros
$parts = str_split(substr('00' . $num, -$levels*3), 3);
$part_count=count($parts);
//THE IMPORTANT YEAR BIT
//only if year-flag = true
//only if no more then 2 parts
//only if year < 9999
// EXAMPLE: 1986
$change = false; //<< === added flag
if($year===true && $part_count===2 && $num<9999){
//get the first digit of last part (ex: 9)
$x=substr($parts[$part_count-1],0,1);
//if first digit = 0 : skip
//else: remove from last part and add to part before
// ex: 001 => 0019 and 986 => 86
if($x!=='0'){
$parts[$part_count-2]=$parts[$part_count-2].$x;
$parts[$part_count-1]=substr($parts[$part_count-1],1);
}
}
//LOOP THE PARTS
for ($i=0; $i < $part_count; $i++) {
$w=[];
//get the (int) of part
$part_num=(int)$parts[$i];
//HUNDREDS
if($part_num >= 100){
$w[]=$list[1][(int)substr($parts[$i],0,1)];
$w[]=$list[2][10];
}
//TENS and SINGLES
$remainder=$part_num%100;
if($remainder>19){
$w[]=$list[2][floor($remainder/10)];
$w[]=$list[1][$remainder%10];
}
else{
$w[]=$list[1][$remainder];
}
// << TEST FOR FLAG
if($change===true && $i===0)
$w[]=$list[2][10];
else
$w[]=$list[3][$part_count - $i -1];
$words[]=implode(' ',$w);
} //end for loop
return implode(' ', $words);
}
Could you not just use
$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format(1994);
This may also help if you don't want to use a plugin
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";
}
}
I will assume you want to follow grammar and spelling rules:
It is ninety and nineteen, not ninty or ninteen.
A hyphen is required for writing out numbers between 21 and 99 that are not a multiple of 10.
Also, your function deals with numbers that are way out of the practical range of years, so I would suggest a function that specifically deals with numbers in the range 1 to 9999, taking the two points above into consideration:
function convertBelow100($pair) { // Helper function
$text = ["", "one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen", "twenty", "thirty",
"forty", "fifty", "sixty", "seventy", "eighty", "ninety"];
return $pair < 20 ? $text[$pair]
: $text[18+floor($pair/10)] . ($pair%10 ? "-" . $text[$pair%10] : "");
}
function convertYearToText($year) { // Main algorithm
$century = floor($year/100);
return trim(($century%10 ? convertBelow100($century) . " hundred "
: ($year > 999 ? convertBelow100(floor($year/1000)) . " thousand " : "")
) . convertBelow100($year%100));
}

php calculate string values: "2+4+3-12+3-5"

How can I calculate values in a string containing the following numbers and (+/-) operators:
Code Like
$string = "3+5+3-7+4-3-1";
//result should be = 4
Updated:
I am trying to calculate $array = [1, +, 6, -, 43, +, 10];
I have converted into the string: implode("", $array);
you can use eval
$string = "3+5+3-7+4-3-1";
eval( '$res = (' . $string . ');' );
echo $res;
$arr_val = array(1, '+', 6, '-', 43, '+', 10);
$total = 0;
if(isset($arr_val[0]) && ($arr_val[0] != '+' || $arr_val[0] != '-'))
$total = intval($arr_val[0]);
foreach($arr_val AS $key => $val) {
if($val == '+') {
if(isset($arr_val[$key+1]) && ($arr_val[$key+1] != '+' || $arr_val[$key+1] != '-')) {
$total = $total + intval($arr_val[$key+1]);
}
} else if($val == '-') {
if(isset($arr_val[$key+1]) && ($arr_val[$key+1] != '+' || $arr_val[$key+1] != '-')) {
$total = $total - intval($arr_val[$key+1]);
}
}
}
echo $total;
May be it will solve your problem.
For any kind of array like: [1, + , 4, -, 5, , 3, 8, + , 6]
Solved with the custom php helper function:
function calcArray($arrVal)
{
if (count($arrVal) == 1) {
return reset($arrVal);
}
if (is_int($arrVal[1])) {
$arrVal[0] = $arrVal[0].$arrVal[1];
unset($arrVal[1]);
return calcArray(array_values($arrVal));
}
$emptyValKey = array_search('', $arrVal);
if ($emptyValKey) {
$concatVal = $arrVal[$emptyValKey-1].$arrVal[$emptyValKey+1];
unset($arrVal[$emptyValKey+1]);
unset($arrVal[$emptyValKey]);
$arrVal[$emptyValKey-1] = $concatVal;
return calcArray(array_values($arrVal));
}
$total = $arrVal[1] == "+" ? $arrVal[0] + $arrVal[2]:$arrVal[0] - $arrVal[2];
unset($arrVal[0]);
unset($arrVal[1]);
unset($arrVal[2]);
array_unshift($arrVal, $total);
$arrVal = array_values(array_filter($arrVal));
return calcArray($arrVal);
}

Break down number into thousands,hundreds,etc

I'm currently putting together a cheque printing solution for my company. When printing the cheque you need to print the number of millions,hundred thousands,ten thousands,thousands, hundreds,tens and units (pounds/dollars/euros etc ) from the amount being paid.
In the case of 111232.23 the following is correctly output from the code I have written below. I cant help feeling that there is a more efficient or reliable method of doing this? Does anyone know of a library/class math technique that does this?
float(111232.23)
Array
(
[100000] => 1
[10000] => 1
[1000] => 1
[100] => 2
[10] => 3
[1] => 2
)
<?php
$amounts = array(111232.23,4334.25,123.24,3.99);
function cheque_format($amount)
{
var_dump($amount);
#no need for millions
$levels = array(100000,10000,1000,100,10,1);
do{
$current_level = current($levels);
$modulo = $amount % $current_level;
$results[$current_level] = $div = number_format(floor($amount) / $current_level,0);
if($div)
{
$amount -= $current_level * $div;
}
}while($modulo && next($levels));
print_r($results);
}
foreach($amounts as $amount)
{
cheque_format($amount);
}
?>
I think you just re-wrote the number_format function that PHP has. My suggestion is to use the PHP function rather than to re-write it.
<?php
$number = 1234.56;
// english notation (default)
$english_format_number = number_format($number);
// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
?>
I'm not sure exactly what the PHP script would be for this, but if you have 10000, 1000, 100, 10, 1 as the things you need the amounts of. How many 10,000's in amount $dollar?
floor($dollar/10000)
how many thousands?
floor(($dollar%10000)/1000)
etc.
This is not the answer for the question, but the following also break down the decimals.
function cheque_format($amount, $decimals = true, $decimal_seperator = '.')
{
var_dump($amount);
$levels = array(100000, 10000, 1000, 100, 10, 5, 1);
$decimal_levels = array(50, 20, 10, 5, 1);
preg_match('/(?:\\' . $decimal_seperator . '(\d+))?(?:[eE]([+-]?\d+))?$/', (string)$amount, $match);
$d = isset($match[1]) ? $match[1] : 0;
foreach ( $levels as $level )
{
$level = (float)$level;
$results[(string)$level] = $div = (int)(floor($amount) / $level);
if ($div) $amount -= $level * $div;
}
if ( $decimals ) {
$amount = $d;
foreach ( $decimal_levels as $level )
{
$level = (float)$level;
$results[$level < 10 ? '0.0'.(string)$level : '0.'.(string)$level] = $div = (int)(floor($amount) / $level);
if ($div) $amount -= $level * $div;
}
}
print_r($results);
}

A loop suddenly ceases to iterate?

I have this php code:
<?php
$numarray = trim($_GET['num']);
$i = strlen($numarray);
$result = "";
$numneedarray = array(
90 => 'ninety',
80 => 'eighty',
70 => 'seventy',
60 => 'sixty',
50 => 'fifty',
40 => 'forty',
30 => 'thirty',
20 => 'twenty',
19 => 'nineteen',
18 => 'eighteen',
17 => 'seventeen',
16 => 'sixteen',
15 => 'fifteen',
14 => 'fourteen',
13 => 'thirteen',
12 => 'twelve',
11 => 'eleven',
10 => 'ten',
9 => 'nine',
8 => 'eight',
7 => 'seven',
6 => 'six',
5 => 'five',
4 => 'four',
3 => 'three',
2 => 'two',
1 => 'one'
);
for ($v = 1; $v <= $i; $v++) {
if ($i > 10) {
exit("Has to be 10-digit or less.");
}
if ($i == 3) {
$result .= ", " . $numneedarray[$numarray[strlen($numarray) - 3]] . " hundred";
if ($numarray % 100 == 0) {
echo "Hi95";
break;
}
} elseif ($i == 2) {
if ($numarray[$v] == 1) {
$othernum = $numarray[strlen($numarray) - 1];
$othernum2 = $numarray[strlen($numarray) - 2] * 10;
$othernum3 = $othernum2 + $othernum;
if (strlen($numarray) > 2) {
$result .= " and ";
}
$result .= $numneedarray[$othernum3];
echo "Hi107";
} else {
$othernum = $numarray[strlen($numarray) - 2] * 10;
$othernum2 = $numarray[strlen($numarray) - 1];
$result .= " and " . $numneedarray[$othernum] . " " . $numneedarray[$othernum2];
echo "Hi112";
}
}
if ($i == 10) {
$digit = substr($numarray, 0, 1);
$result .= $numneedarray[$digit] . " billion";
if ($numarray % 1000000000 == 0) {
break;
}
} elseif ($i == 9) {
$number = substr($numarray, 1, 3);
$digit1 = substr($number, 0, 1);
$digit1con = $numneedarray[$digit1] . " hundred";
$digit2 = substr($number, 1, 1);
$noneed = false;
if ($digit2 != 1) {
$digit2con = $numneedarray[$digit2 * 10];
} else {
$digit23 = substr($number, 1, 2);
$digit23con = $numneedarray[$digit23];
$noneed = true;
}
$digit3 = substr($number, -1);
$digit3con = $numneedarray[$digit3];
if ($noneed == true) {
$result .= ", " . $digit1con . " and " . $digit23con . " million";
} else {
$result .= ", " . $digit1con . " and " . $digit2con . " " . $digit3con . " million";
}
if ($numarray % 100000000 == 0) {
echo "Hi";
break;
}
} elseif ($i == 6) {
$number = substr($numarray, 4, 3);
$digit1 = substr($number, 0, 1);
$digit1con = $numneedarray[$digit1] . " hundred";
$digit2 = substr($number, 1, 1);
$noneed = false;
if ($digit2 != 1) {
$digit2con = $numneedarray[$digit2 * 10];
} else {
$digit23 = substr($number, 1, 2);
$digit23con = $numneedarray[$digit23];
$noneed = true;
}
$digit3 = substr($number, -1);
$digit3con = $numneedarray[$digit3];
if ($noneed == true) {
$result .= ", " . $digit1con . " and " . $digit23con . " thousand";
} else {
$result .= ", " . $digit1con . " and " . $digit2con . " " . $digit3con . " thousand";
}
if ($numarray % 100000 == 0) {
echo "Hi89";
break;
}
}
echo $i;
$i = $i - 1;
}
if (strlen($numarray) == 1) {
echo $numneedarray[$numarray];
}
echo $result;
?>
The num value is equal to 1234567890. When I refresh the page, the value of $i only goes from 10 -> 9 -> 8 -> 7 -> 6 and then suddenly stops. Why would the loop stop running?
You try to check each digit:
for ($v = 1; $v <= $i; $v++) {
But then you decrease $i in the loop:
$i = $i - 1;
That's why you see less loops than you expected.
I hope below post will help you achieve what you're looking for:
http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/
not optimal - but change
$i = strlen($numarray);
to
$i = strlen($numarray);
$count = $i;
and
for ($v = 1; $v <= $i; $v++)
to
for ($v = 1; $v <= $count; $v++)

Convert a number to its string representation

I'm developing a simple web application where in I need to display number a to my users in string format.
Example:
12 - One Two or Twelve
-20 - minus Two zero or minus twenty
Either way is fine. I need this to be done in PHP. Any help will be appreciated.
for the first option (spell out digits), strtr is your friend
$words = array(
'-' => 'minus ',
'1' => 'one ',
'2' => 'two ',
etc....
);
echo strtr(-123, $words);
If you want to spell out the complete number you can make use of the PEAR Numbers_Words class. This class has a toWords() method that accepts a +ve or a -ve num and returns the spelled out string representation of the number.
If you want to convert the number to string digit wise, I am not aware of any lib function. But you can code one yourself easily. user187291 gives a good way to do this in his answer.
<?php
$arr = array(
-12,
20
);
foreach($arr as $num) {
$nw = new Numbers_Words();
echo "$num = ". $nw->toWords($num)."\n";
}
?>
Output:
C:\>php a.php
-12 = minus twelve
20 = twenty
bellow I am giving you an example function. It may not be a complete one but it should get you started (I know, the question has been posted long ago. still, it may help others - )
And I am sorry for any bugs :). and lastly, it is not finished one. I just post for an example starting point.
function convertToString($number, $blankIfZero=true){
$strRep = "";
$n = intval($number);
$one2twenty = array("One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven",
"Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen");
$twenty2ninty = array("Twenty", "Thirty",
"Fourty", "Fifty", "Sixty", "Seventy", "Eighty",
"Ninety");
$hundred = "Hundred";
$thousand = "Thousand";
$million = "Million";
$billion = "Billion";
switch($n){
case 0:
if($blankIfZero == true){
$strRep= $strRep."";
break;
}else{
$strRep = $strRep."Zero";
break;
}
case $n >0 && $n <20:
$strRep = $strRep." ".$one2twenty[($n-1)];
break;
case $n >=20 && $n < 100:
$strRep = $strRep . " ". $twenty2ninty[(($n/10) - 2)];
$strRep .= convertToString($n%10);
break;
case $n >= 100 && $n <= 999:
$strRep = $strRep.$one2twenty[(($n/100)-1)]." ".$hundred. " ";
$strRep .= convertToString($n%100);
break;
case $n >= 1000 && $n < 100000:
if($n < 20000){
$strRep = $strRep.$one2twenty[(($n/1000)-1)]." ".$thousand. " ";
$strRep .= convertToString($n%1000);
break;
}else{
$strRep = $strRep . $twenty2ninty[(($n/10000) - 2)];
$strRep .= convertToString($n%10000);
break;
}
case $n >= 100000 && $n < 1000000:
$strRep .= convertToString($n/1000). " ".$thousand. " ";
$strRep .= convertToString(($n%100000)%1000);
break;
case $n >= 1000000 && $n < 10000000:
$strRep = $strRep . $one2twenty[(($n/1000000) - 1)]. " ".$million." ";
$strRep .= convertToString($n%1000000);
break;
case $n >= 10000000 && $n < 10000000000:
$strRep .= convertToString($n/1000000). " ".$million. " ";
$strRep .= convertToString(($n%1000000));
break;
}
return $strRep;
}
Building on the work that #SRC did in a previous answer, I wrote a function to convert any raw unsigned integer into English, mainly out of curiosity.
You can find the code here: a GitHub Gist by StampyCode
This code is only limited by PHP's Integer limit (64-bit):
9223372036854775807
Which is processed by this code to output:
nine quintillion, two hundred and twenty three quadrillion, three hundred and seventy two trillion, thirty six billion, eight hundred and fifty four million, seven hundred and seventy five thousand, eight hundred and seven
Code embed:
<?php
$_1to19 = [
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
];
$_teen = [
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety",
];
$_mult = [
2 => 'hundred',
3 => 'thousand',
6 => 'million',
9 => 'billion',
12 => 'trillion',
15 => 'quadrillion',
18 => 'quintillion',
21 => 'sextillion',
24 => 'septillion', // php can't count this high
27 => 'octillion',
];
$fnBase = function ($n, $x) use (&$fn, $_mult) {
return $fn($n / (10 ** $x)) . ' ' . $_mult[$x];
};
$fnOne = function ($n, $x) use (&$fn, &$fnBase) {
$y = ($n % (10 ** $x)) % (10 ** $x);
$s = $fn($y);
$sep = ($x === 2 && $s ? " and " : ($y < 100 ? ($y ? " and " : '') : ', '));
return $fnBase($n, $x) . $sep . $s;
};
$fnHundred = function ($n, $x) use (&$fn, &$fnBase) {
$y = $n % (10 ** $x);
$sep = ($y < 100 ? ($y ? ' and ' : '') : ', ');
return ', ' . $fnBase($n, $x) . $sep . $fn($y);
};
$fn = function ($n) use (&$fn, $_1to19, $_teen, $number, &$fnOne, &$fnHundred) {
switch ($n) {
case 0:
return ($number > 1 ? '' : 'zero');
case $n < 20:
return $_1to19[$n - 1];
case $n < 100:
return $_teen[($n / 10) - 2] . ' ' . $fn($n % 10);
case $n < (10 ** 3):
return $fnOne($n, 2);
};
for ($i = 4; $i < 27; ++$i) {
if ($n < (10 ** $i)) {
break;
}
}
return ($i % 3) ? $fnHundred($n, $i - ($i % 3)) : $fnOne($n, $i - 3);
};
$number = $fn((int)$number);
$number = str_replace(', , ', ', ', $number);
$number = str_replace(', ', ', ', $number);
$number = str_replace(' ', ' ', $number);
$number = ltrim($number, ', ');
return $number;

Categories