Skip to content

Instantly share code, notes, and snippets.

@Maikuolan
Created September 8, 2017 13:23
Show Gist options
  • Save Maikuolan/360e4f19de559466133304e090f6ef31 to your computer and use it in GitHub Desktop.
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.
<?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