Skip to content

Instantly share code, notes, and snippets.

@rstruber
Last active August 29, 2015 14:27
Show Gist options
  • Save rstruber/50742ea36a6be0d1cb9c to your computer and use it in GitHub Desktop.
Save rstruber/50742ea36a6be0d1cb9c to your computer and use it in GitHub Desktop.
PHP class convert an arbitrary number to an english string
#! /usr/local/bin/php
<?php
include_once('NumberConv.php');
$a = new NumberConv(0);
echo $a . PHP_EOL;
$a = new NumberConv(5);
echo $a . PHP_EOL;
$a = new NumberConv(10);
echo $a . PHP_EOL;
$a = new NumberConv(13);
echo $a . PHP_EOL;
$a = new NumberConv(16);
echo $a . PHP_EOL;
$a = new NumberConv(20);
echo $a . PHP_EOL;
$a = new NumberConv(305);
echo $a . PHP_EOL;
$a = new NumberConv(500);
echo $a . PHP_EOL;
$a = new NumberConv(1000);
echo $a . PHP_EOL;
$a = new NumberConv(5295200059);
echo $a . PHP_EOL;
$a = new NumberConv(300410);
echo $a . PHP_EOL;
$a = new NumberConv(-1024901490);
echo $a . PHP_EOL;
$a = new NumberConv('$102531');
echo $a . PHP_EOL;
<?php
class NumberConv {
protected $single = [
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
];
protected $double = [
10 => 'ten',
20 => 'twenty',
30 => 'thirty',
40 => 'forty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
];
protected $teen = [
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
];
protected $places = [
1 => 'hundred',
2 => 'thousand',
3 => 'million',
4 => 'billion',
5 => 'trillion',
6 => 'quadrillion',
7 => 'quintillion',
8 => 'sextillion',
9 => 'septillion',
10 => 'octillion',
11 => 'nonillion',
12 => 'decillion',
13 => 'undecillion',
14 => 'duodecillion',
15 => 'tredecillion',
];
protected $modifier_map = [
'-' => [
'string' => 'negative',
'fix' => 'prefix'
],
'$' => [
'string' => 'dollars',
'fix' => 'suffix'
]
];
protected $modifier_value = '';
public $number = null;
protected $string = '';
public function __construct($number) {
$number = ltrim($number);
if (strlen($number > 1))
$number = ltrim($number, '0');
if (!is_numeric(substr($number, 0, 1))) {
$this->modifier_value = substr($number, 0, 1);
$number = substr($number,1);
}
$this->number = $number;
}
public function __toString() {
if (!empty($this->string))
return $this->string;
if ($this->number == 0) {
$this->string = 'zero ';
}
else {
/**
* 1. Reverse the number because numbers actually parse right to left (1234 becomes 4321)
* 2. Split number into chunks of 3 (4321 becomes [432, 1])
* 3. Put every element of resulting array back into original order ([432, 1] becomes [234, 1])
* 4. Reverse the array order ([234, 1] becomes [1, 234])
*/
$split = array_reverse(array_map('strrev', str_split(strrev($this->number), 3)));
$places = count($split);
foreach ($split as $n) {
if (strlen($n) == 3) {
if (array_key_exists($n[0], $this->single))
$this->string .= "{$this->single[$n[0]]} {$this->places[1]} ";
$n = substr($n,1);
}
if (strlen($n) == 2) {
if (array_key_exists($n[0] . $n[1], $this->teen)) {
$this->string .= $this->teen[$n[0] . $n[1]] . ' ';
$n = substr($n,1);
}
elseif (array_key_exists($n[0] . '0', $this->double)) {
$this->string .= $this->double[$n[0] . '0'] . ' ';
}
$n = substr($n,1);
}
if (strlen($n) == 1 && array_key_exists($n[0], $this->single))
$this->string .= "{$this->single[$n[0]]} ";
if ($places > 1 && array_key_exists($places, $this->places))
$this->string .= "{$this->places[$places]} ";
$places--;
}
}
if (!empty($this->modifier_value) && array_key_exists($this->modifier_value, $this->modifier_map)) {
$modifier = $this->modifier_map["{$this->modifier_value}"];
if ($modifier['fix'] == 'prefix')
$this->string = $modifier['string'] . ' ' . $this->string;
elseif ($modifier['fix'] == 'suffix')
$this->string .= $modifier['string'];
}
return trim($this->string);
}
}
#! /usr/local/bin/php
<?php
include_once('NumberConv.php');
$a = new NumberConv($argv[1]);
echo $a . PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment