Created
September 8, 2017 13:23
-
-
Save Maikuolan/360e4f19de559466133304e090f6ef31 to your computer and use it in GitHub Desktop.
This Gist just demonstrates some basic ideas for converting numbers from a numberic format into a word format. It's pretty simplistic (i.e., done in a rush and messy as shit) and is only really intended to provide some basic ideas, and of course, there'll likely be others ways to go about it, too.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This Gist just demonstrates some basic ideas for converting numbers from a | |
* numberic format into a word format. It's pretty simplistic (i.e., done in a | |
* rush and messy as shit) and is only really intended to provide some basic | |
* ideas, and of course, there'll likely be others ways to go about it, too. | |
* | |
* Context: https://www.facebook.com/groups/2204685680/permalink/10156073375930681/ | |
* | |
* It will likely need to be expanded upon and adapted to suit your needs (due | |
* to that this is just demonstrating some ideas and isn't a complete package, | |
* class, etc). | |
* | |
* Also note: Worth checking out this before using this Gist, in case it suits | |
* your needs: http://dk2.php.net/manual/en/class.numberformatter.php | |
* (NumberFormatter needs to be installed via PECL before using it, as it isn't | |
* pre-bundled with PHP, but might do the trick, if you're able to use it). | |
*/ | |
/** | |
* Demonstration function "ConvertNumber". | |
* | |
* @param mixed $Input The original number we're inputting (integer, float, | |
* string, etc, all should be accepted, but if we use strings, we can work | |
* around number precision limitations, so it may be better in some cases). | |
* @return string The output. | |
*/ | |
function ConvertNumber($Input) { | |
/** Normalises the input to a float (to get rid of extraneous formatting, etc). */ | |
$Input = preg_replace('~[^0-9.]~', '', $Input); | |
/** Find the character position of the decimal within the input. */ | |
$Decimal = strpos($Input, '.'); | |
/** Where we'll eventually dump our output. */ | |
$Output = ''; | |
/** Executed if a decimal exists. */ | |
if ($Decimal !== false) { | |
/** The whole number part of the input. */ | |
$Whole = substr($Input, 0, $Decimal); | |
/** The fraction part of the input. */ | |
$Fraction = substr($Input, $Decimal + 1); | |
} | |
/** Executed if a decimal DOESN'T exist. */ | |
else { | |
$Whole = $Input; | |
$Fraction = ''; | |
} | |
/** So far, so good. Now, what to call for each number? */ | |
$Numbers = [ | |
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' | |
]; | |
/** | |
* And what to call for each place? | |
* See: https://en.wikipedia.org/wiki/Names_of_large_numbers | |
*/ | |
$Places = [ | |
0 => 'zero', | |
3 => 'hundred', | |
4 => 'thousand', | |
7 => 'million', | |
10 => 'billion', | |
13 => 'trillion', | |
16 => 'quadrillion', | |
19 => 'quintillion', | |
22 => 'sextillion', | |
25 => 'septillion', | |
28 => 'octillion', | |
31 => 'nonillion', | |
34 => 'decillion', | |
37 => 'undecillion', | |
40 => 'duodecillion', | |
43 => 'tredecillion', | |
46 => 'quattuordecillion', | |
49 => 'quindecillion', | |
52 => 'sexdecillion', | |
55 => 'septendecillion', | |
58 => 'octodecillion', | |
61 => 'novemdecillion', | |
64 => 'vigintillion' | |
]; | |
/** Misc. other words. */ | |
$Words = [ | |
'and' => 'and', | |
'point' => 'point' | |
]; | |
/** In case of numbers 0<x<1. */ | |
if (empty($Whole)) { | |
$Output .= $Places[0] . ' '; | |
} | |
/** Now, let's iterate through each character of the whole number. */ | |
for ($Thirds = 0; !empty($Whole); $Whole = substr($Whole, $Thirds + 1)) { | |
$Len = strlen($Whole); | |
$Thirds = ($Len + 2) % 3; | |
$Conjunct = false; | |
$Shift = 0; | |
if ($Thirds === 2) { | |
$Hundred = substr($Whole, 0, 1); | |
$Shift++; | |
if (isset($Numbers[$Hundred])) { | |
$Output .= $Numbers[$Hundred] . ' '; | |
} | |
$Output .= $Places[3] . ' '; | |
$Conjunct = true; | |
} | |
if ($Thirds === 1 || $Conjunct) { | |
$First = substr($Whole, $Shift, 1); | |
$Second = substr($Whole, $Shift + 1, 1); | |
$Double = $First . $Second; | |
if (isset($Numbers[$Double])) { | |
if ($Conjunct) { | |
$Output .= $Words['and'] . ' '; | |
} | |
$Output .= $Numbers[$Double] . ' '; | |
} else { | |
$First .= '0'; | |
if (isset($Numbers[$First])) { | |
if ($Conjunct) { | |
$Output .= $Words['and'] . ' '; | |
} | |
$Conjunct = false; | |
$Output .= $Numbers[$First] . ' '; | |
} | |
if (isset($Numbers[$First])) { | |
if ($Conjunct) { | |
$Output .= $Words['and'] . ' '; | |
} | |
$Output .= $Numbers[$Second] . ' '; | |
} | |
} | |
} elseif ($Thirds === 0) { | |
$Number = substr($Whole, $Shift, 1); | |
if (isset($Numbers[$Number])) { | |
$Output .= $Numbers[$Number] . ' '; | |
} | |
} | |
if ($Len > 3) { | |
$Place = ($Len - $Thirds); | |
if (isset($Places[$Place])) { | |
$Output .= $Places[$Place] . ' '; | |
} | |
} | |
} | |
/** Was there a decimal? */ | |
if ($Decimal !== false) { | |
$Output .= $Words['point'] . ' '; | |
} | |
/** Now, let's iterate through each character of the fraction. */ | |
while (!empty($Fraction)) { | |
$ThisNumber = substr($Fraction, 0, 1); | |
if (!$ThisNumber) { | |
$Output .= $Places[0] . ' '; | |
} elseif (isset($Numbers[$ThisNumber])) { | |
$Output .= $Numbers[$ThisNumber] . ' '; | |
} | |
$Fraction = strlen($Fraction > 1) ? substr($Fraction, 1) : false; | |
} | |
return ucfirst(trim($Output)); | |
} | |
echo ConvertNumber(123456789.8765) . "\n"; | |
echo ConvertNumber(12345678.98765) . "\n"; | |
echo ConvertNumber(1234567.898765) . "\n"; | |
echo ConvertNumber(123456.7898765) . "\n"; | |
echo ConvertNumber(12345.67898765) . "\n"; | |
echo ConvertNumber(1234.567898765) . "\n"; | |
echo ConvertNumber(123.4567898765) . "\n"; | |
echo ConvertNumber(12.34567898765) . "\n"; | |
echo ConvertNumber(1.234567898765) . "\n"; | |
echo ConvertNumber(0) . "\n"; | |
echo ConvertNumber(17) . "\n"; | |
echo ConvertNumber(13.111003) . "\n"; | |
echo ConvertNumber(19) . "\n"; | |
echo ConvertNumber(777) . "\n"; | |
echo ConvertNumber('99999999999999999999999999999999999') . "\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment