@ 2014-08-16T11:38:31Z <?php
$n2w = new NumberToWords(); // not in use
var_dump($n2w->convertToWords($amount));
class NumberToWords {
// base 10 dictionary
private $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 => 'forty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
1000000 => 'million',
1000000000 => 'billion',
1000000000000 => 'trillion',
1000000000000000 => 'quadrillion',
1000000000000000000 => 'quintillion'
);
// irregular ordinals
private $ordinal_dictionary = array(
0 => 'zeroth',
1 => 'first',
2 => 'second',
3 => 'third',
5 => 'fifth',
8 => 'eighth',
12 => 'twelfth',
20 => 'twentieth',
30 => 'thirtieth',
40 => 'fourtieth',
50 => 'fiftieth',
60 => 'sixtieth',
70 => 'seventieth',
80 => 'eightieth',
90 => 'ninetieth',
100 => 'hundredth',
1000 => 'thousandth',
1000000 => 'millionth',
1000000000 => 'billionth',
1000000000000 => 'trillionth',
1000000000000000 => 'quadrillionth',
1000000000000000000 => 'quintillionth'
);
// math dictionary (not currently in use)
private $math_dictionary = array(
'+' => 'add',
'-' => 'subtract',
'/' => 'divide',
'*' => 'multiply',
'%' => 'modulus',
'>' => 'greater than',
'<' => 'less than',
'=' => 'equal'
);
public $hyphen = '-';
public $conjunction = 'and';
public $separator = ',';
public $negative = 'negative '; // or minus
public $decimal = 'point';
public $percent = 'percent';
public $degrees = 'degree';
public $currency_type = 'dollar';
public $currency_fraction_type = 'cent';
public $uppercase_words = TRUE; // will uc words except 'and'
public $include_zero_dollars = TRUE;
public $include_zero_cents = TRUE;
const AUTOMATIC_MODE = 'automatic_mode';
const CURRENCY_MODE = 'currency_mode';
private $mode;
/**
* Constructor
*/
public function __construct() {
$this->mode = self::AUTOMATIC_MODE;
}
/**
* Sets the mode used during conversion
*
* @param string $mode
*/
public function setMode($mode) {
$this->mode = $mode;
}
/**
* Converts any number to words
*
* @param float $number
* @param string $mode
* (optional)
* @return string
*/
public function convertToWords($number, $mode = null) {
if ($mode != null)
$this->mode = $mode;
// default vars to null
$is_negative = FALSE;
$string = $fraction = null;
$unit_type = '';
$support_plural_units = TRUE;
// must be numeric
if (!is_numeric($number)){
// strip chars that make this non-numeric
// auto-detect currency and set mode (if at beginning of string)
if (strpos($number, '$') == 0){
$this->mode = self::CURRENCY_MODE;
}
// handle simple percent (if at end of string)
if (strpos($number, '%') == strlen($number) - 1){
$this->mode = self::AUTOMATIC_MODE;
$unit_type .= $this->percent;
$support_plural_units = FALSE;
}
// handle simple degrees (if at end of string)
if (strpos($number, '°') == strlen($number) - 1){
$this->mode = self::AUTOMATIC_MODE;
$unit_type .= $this->degrees;
}
// clean %, $, �, comma (,)
$number = preg_replace('/[,\%\$°]/', '', $number);
// if it's not clean now, it's not something we can handle
if (!is_numeric($number)){
return false;
}
}
// buffer overflow check
if (($number >= 0 && (int)$number < 0) || (int)$number < 0 - PHP_INT_MAX){
trigger_error('convert only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX, E_USER_WARNING);
return false;
}
// check for negative number, if so store/remove negative and continue
if ($number < 0){
$is_negative = TRUE;
$number = abs($number);
}
if ($this->mode == self::CURRENCY_MODE){
if ($number == (int)$number){
$number .= '.00'; // force decimal by string
}
}
// check for fraction, store it for later
if (strpos($number, '.') !== FALSE){
// only apply rounding if we have a fraction
if ($this->mode == self::CURRENCY_MODE && $number != (int)$number){
$number = round($number, 2); // we want .109 to round to .11 cents
}
list($number, $fraction) = explode('.', $number);
if ($this->mode == self::CURRENCY_MODE && $fraction != null){
if (strlen($fraction) == 1){
$fraction *= 10; // we want .1 to become .10 (or 10 cents)
}
}
}
// if dealing in currency, add units (Dollars)
if ($number != 0 || ($this->include_zero_dollars && $number == 0)){
$string .= $this->convert($number);
// add units in currency mode
if ($this->mode == self::CURRENCY_MODE){
$string .= ' ' . $this->currency_type . ($number != 1 ? 's' : '') . '';
}
}
// handle fraction
if ($fraction !== null && is_numeric($fraction)){
if ($this->mode == self::CURRENCY_MODE){
// change mode to default so there is no unit type
if (($fraction == 0 && $this->include_zero_cents) || $fraction != 0){
$before_mode = $this->mode;
$this->mode = self::AUTOMATIC_MODE;
// if string is not null, we want to add 'and'
if ($string != null)
$string .= " " . $this->conjunction . " ";
$string .= $this->convert($fraction);
$this->mode = $before_mode; // restore previous mode
$string .= ' ' . $this->currency_fraction_type . ($fraction != 1 ? 's' : '');
}
if ($this->uppercase_words)
$string = $this->ucwords($string);
return $string;
}
if ($this->mode == self::AUTOMATIC_MODE){
$string .= " " . $this->decimal . " "; // just output 'point'
}
$words = array();
foreach(str_split((string)$fraction) as $number ){
$words[] = $this->dictionary[$number];
}
$string .= implode(' ', $words);
}
// handle units, if required
if ($unit_type != '' && $support_plural_units && ($number != 1 || $fraction != null))
$unit_type .= 's';
// apply last minute formatting
$string = ($is_negative ? $this->negative : '') . $string . " " . $unit_type;
// uppercase words if set
if ($this->uppercase_words)
$string = $this->ucwords($string);
return trim($string);
}
/**
* Print out date/time related words
*
* @param string $date
* @param string $pattern
* @return string
*/
public function convertDateToWords($date, $pattern = 'l, F jS, Y') {
// get the time
$time = strtotime($date);
// adjust the pattern for testing adding non-interpreted characters
// $pattern = "l, F \u jS, Y \h";
$parts = preg_split('//', $pattern);
$good_parts = array();
for($i = 0; $i < count($parts); $i++){
$part = $parts[$i];
if ($part == "\\"){
// this is an escaped character, get the character that follows as part
$part = $parts[++$i]; // get next item as assignment
} else{
// track 'S' (st, nd, rd, th suffix), we need the item before (if item exists and is a number)
// make it read first, second, third, fourth, fifth, sixth, seventh, eighth, nineth, tenth, eleventh, twelveth...
if ($part == 'S' && $i > 0){
$prev_val = date($parts[$i - 1], $time);
if (is_numeric($prev_val)){
// numbers with different rules
$part = $this->getNumberOrdinal($prev_val);
array_pop($good_parts); // remove last item
$good_parts[] = $part; // add this item
continue;
}
}
if (trim($part) != '' && $part != ',' && ($value = date($part, $time)) !== FALSE){
if ($value != ''){
// we have an equated value
if (is_numeric($value)){
// this a number, let's convert it to text
$good_parts[] = trim($this->convertToWords($value, self::AUTOMATIC_MODE));
} else{
// this is not a number, we don't alter it
$good_parts[] = $value;
}
}
continue;
}
}
$good_parts[] = $part;
}
// echo var_export($good_parts, TRUE)."\n";
return trim(implode('', $good_parts));
}
/**
* Converts a number into the word-ordinal form
*
* @param int $number
* @return string
*/
public function getNumberOrdinal($number) {
$number = (int)abs($number); // cannot have fractions or be negative
// check if number given is in ordinal dictionary
if (array_key_exists($number, $this->ordinal_dictionary)){
// simple lookup in dictionary
$ord = $this->ordinal_dictionary[$number];
} else{
// first remove all but the last two digits
$n1 = $number % 100;
// remove all but last digit unless the number is in the teens, which all should be 'th'
$n2 = ($n1 < 20 ? $number : $number % 10);
// check if digit less than 20 is in dictionary
if (array_key_exists($n2, $this->ordinal_dictionary)){
$ord = $this->ordinal_dictionary[$n2];
if ($number > 20){
$words = $this->convertToWords($number);
// we need to account for a two-part number
$word_list = explode('-', $words);
$word_list[count($word_list) - 1] = $ord;
$ord = implode('-', $word_list);
}
} else{
// if not zero, use number straight across
if ($n2 != 0){
$ord = $this->convert($number) . 'th';
}
}
}
// apply this to finished product, not ord
if ($this->uppercase_words)
$ord = $this->ucwords($ord);
return $ord;
}
/**
* Helper method to access converting almost all words to ucfirst
*
* @param string $string
* @return string
*/
private function ucwords($string) {
return preg_replace_callback("/[a-zA-Z-]+/", array(
&$this,
'limitedUcwords'
), $string);
}
/**
* Called by preg callback
*
* @param string $match
* @return string
*/
private function limitedUcwords($match) {
$exclude = array(
'and'
); // list of words to not ucfirst
if (in_array(strtolower($match[0]), $exclude))
return $match[0];
return ucfirst($match[0]);
}
/**
* Converts a number to words regardless of other formatting
*
* @param int $number
* @return boolean
*/
private function convert($number) {
$string = '';
$number = (int)$number; // must be a whole number (no fraction, no strings)
switch (true){
case $number < 21:
$string = $this->dictionary[$number];
break;
case $number < 100:
$tens = ((int)($number / 10)) * 10;
$units = $number % 10;
$string = $this->dictionary[$tens];
if ($units){
$string .= $this->hyphen . $this->dictionary[$units];
}
break;
case $number < 1000:
$hundreds = $number / 100;
$remainder = $number % 100;
$string = $this->dictionary[$hundreds] . ' ' . $this->dictionary[100];
if ($remainder){
$string .= " " . $this->conjunction . " " . $this->convert($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int)($number / $baseUnit);
$remainder = $number % $baseUnit;
$string = $this->convert($numBaseUnits) . ' ' . $this->dictionary[$baseUnit];
if ($remainder){
$string .= $remainder < 100 ? " " . $this->conjunction . " " : $this->separator . " ";
$string .= $this->convert($remainder);
}
break;
}
return $string;
}
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.3.6 0.015 0.000 18.60 8.3.5 0.017 0.006 22.96 8.3.4 0.016 0.003 19.27 8.3.3 0.012 0.003 19.21 8.3.2 0.004 0.004 20.49 8.3.1 0.006 0.003 21.94 8.3.0 0.004 0.004 17.88 8.2.18 0.016 0.006 17.13 8.2.17 0.015 0.000 22.96 8.2.16 0.011 0.003 20.65 8.2.15 0.004 0.004 24.18 8.2.14 0.008 0.000 24.66 8.2.13 0.003 0.005 26.16 8.2.12 0.000 0.008 20.98 8.2.11 0.010 0.000 22.20 8.2.10 0.009 0.003 18.09 8.2.9 0.005 0.003 19.34 8.2.8 0.003 0.005 17.97 8.2.7 0.008 0.004 17.98 8.2.6 0.000 0.008 17.93 8.2.5 0.009 0.000 18.07 8.2.4 0.000 0.008 18.22 8.2.3 0.008 0.000 18.21 8.2.2 0.000 0.008 18.05 8.2.1 0.004 0.004 18.27 8.2.0 0.003 0.006 18.17 8.1.28 0.008 0.008 25.92 8.1.27 0.005 0.003 24.02 8.1.26 0.008 0.000 26.35 8.1.25 0.003 0.006 28.09 8.1.24 0.007 0.003 23.96 8.1.23 0.003 0.009 19.29 8.1.22 0.005 0.003 17.91 8.1.21 0.000 0.008 18.77 8.1.20 0.004 0.004 17.60 8.1.19 0.003 0.006 17.60 8.1.18 0.000 0.009 18.10 8.1.17 0.008 0.000 18.84 8.1.16 0.000 0.008 22.27 8.1.15 0.000 0.008 19.10 8.1.14 0.005 0.003 17.76 8.1.13 0.000 0.007 17.87 8.1.12 0.000 0.008 17.75 8.1.11 0.006 0.003 17.71 8.1.10 0.006 0.003 17.80 8.1.9 0.004 0.004 17.66 8.1.8 0.000 0.007 17.82 8.1.7 0.004 0.004 17.64 8.1.6 0.006 0.003 17.83 8.1.5 0.003 0.006 17.78 8.1.4 0.006 0.003 17.83 8.1.3 0.000 0.008 17.94 8.1.2 0.004 0.004 17.84 8.1.1 0.008 0.000 17.80 8.1.0 0.004 0.004 17.79 8.0.30 0.000 0.007 18.77 8.0.29 0.004 0.004 17.25 8.0.28 0.005 0.002 18.52 8.0.27 0.004 0.004 17.42 8.0.26 0.004 0.004 17.42 8.0.25 0.000 0.007 17.36 8.0.24 0.000 0.007 17.29 8.0.23 0.007 0.000 17.29 8.0.22 0.004 0.004 17.28 8.0.21 0.005 0.003 17.27 8.0.20 0.007 0.000 17.30 8.0.19 0.000 0.008 17.32 8.0.18 0.007 0.000 17.30 8.0.17 0.003 0.006 17.29 8.0.16 0.003 0.005 17.17 8.0.15 0.004 0.004 17.15 8.0.14 0.000 0.007 17.20 8.0.13 0.003 0.003 13.70 8.0.12 0.005 0.003 17.26 8.0.11 0.004 0.004 17.22 8.0.10 0.003 0.005 17.23 8.0.9 0.000 0.007 17.31 8.0.8 0.015 0.006 17.17 8.0.7 0.000 0.009 17.27 8.0.6 0.004 0.004 17.29 8.0.5 0.000 0.008 17.03 8.0.3 0.017 0.009 17.43 8.0.2 0.008 0.014 17.40 8.0.1 0.005 0.003 17.38 8.0.0 0.008 0.010 16.98 7.4.33 0.005 0.000 15.00 7.4.32 0.005 0.002 16.86 7.4.30 0.000 0.008 17.02 7.4.29 0.007 0.000 17.01 7.4.28 0.004 0.004 16.86 7.4.27 0.000 0.007 16.82 7.4.26 0.003 0.006 16.94 7.4.25 0.003 0.005 16.83 7.4.24 0.004 0.003 16.89 7.4.23 0.000 0.007 16.94 7.4.22 0.012 0.006 16.85 7.4.21 0.006 0.009 16.98 7.4.20 0.000 0.008 16.99 7.4.16 0.017 0.008 17.04 7.4.15 0.016 0.008 17.40 7.4.14 0.011 0.008 17.86 7.4.13 0.012 0.008 16.83 7.4.12 0.009 0.010 16.89 7.4.11 0.014 0.004 16.76 7.4.10 0.015 0.006 16.88 7.4.9 0.008 0.011 16.89 7.4.8 0.009 0.009 19.39 7.4.7 0.010 0.009 16.74 7.4.6 0.010 0.010 16.98 7.4.5 0.000 0.009 16.93 7.4.4 0.007 0.010 16.77 7.4.3 0.009 0.009 16.82 7.4.0 0.003 0.012 14.96 7.3.33 0.003 0.003 13.59 7.3.32 0.006 0.000 13.72 7.3.31 0.002 0.005 16.63 7.3.30 0.002 0.005 16.60 7.3.29 0.006 0.009 16.73 7.3.28 0.008 0.012 16.75 7.3.27 0.009 0.009 17.40 7.3.26 0.003 0.014 16.76 7.3.25 0.008 0.011 16.87 7.3.24 0.010 0.007 16.79 7.3.23 0.006 0.013 17.02 7.3.21 0.014 0.003 16.74 7.3.20 0.008 0.009 19.39 7.3.19 0.011 0.006 16.96 7.3.18 0.006 0.011 16.81 7.3.17 0.019 0.009 16.65 7.3.16 0.010 0.010 16.78 7.3.1 0.000 0.014 16.95 7.3.0 0.003 0.006 16.60 7.2.33 0.012 0.006 16.91 7.2.32 0.003 0.019 17.01 7.2.31 0.017 0.003 17.02 7.2.30 0.004 0.022 16.96 7.2.29 0.011 0.006 16.99 7.2.13 0.007 0.007 17.17 7.2.12 0.009 0.003 16.84 7.2.11 0.006 0.003 16.92 7.2.10 0.004 0.007 16.91 7.2.9 0.000 0.012 17.19 7.2.8 0.000 0.012 17.15 7.2.7 0.006 0.006 16.90 7.2.6 0.008 0.004 17.00 7.2.5 0.006 0.006 17.17 7.2.4 0.006 0.009 17.23 7.2.3 0.003 0.013 17.20 7.2.2 0.003 0.006 16.91 7.2.1 0.009 0.006 17.20 7.2.0 0.003 0.011 18.44 7.1.25 0.006 0.003 15.93 7.1.10 0.003 0.006 18.56 7.1.7 0.000 0.007 17.31 7.1.6 0.000 0.026 19.40 7.1.5 0.028 0.013 34.91 7.1.0 0.010 0.070 22.35 7.0.20 0.003 0.006 16.88 7.0.14 0.007 0.073 22.05 7.0.11 0.000 0.040 20.12 7.0.10 0.010 0.037 20.16 7.0.9 0.020 0.023 20.23 7.0.8 0.013 0.077 20.21 7.0.7 0.010 0.053 20.11 7.0.6 0.000 0.060 20.10 7.0.5 0.010 0.073 20.03 7.0.4 0.010 0.073 19.75 7.0.3 0.003 0.087 19.70 7.0.2 0.013 0.073 19.70 7.0.1 0.003 0.073 19.75 7.0.0 0.000 0.087 19.84 5.6.28 0.010 0.070 21.17 5.6.26 0.007 0.050 20.67 5.6.25 0.017 0.070 20.77 5.6.24 0.010 0.060 20.94 5.6.23 0.017 0.073 20.63 5.6.22 0.003 0.040 20.76 5.6.21 0.013 0.073 20.69 5.6.20 0.007 0.073 20.74 5.6.19 0.003 0.083 20.76 5.6.18 0.007 0.033 20.67 5.6.17 0.003 0.077 20.64 5.6.16 0.000 0.090 20.64 5.6.15 0.007 0.063 20.69 5.6.14 0.007 0.083 20.73 5.6.13 0.007 0.033 20.67 5.6.12 0.010 0.077 20.54 5.6.11 0.003 0.037 20.53 5.6.10 0.003 0.080 20.72 5.6.9 0.010 0.080 20.72 5.6.8 0.000 0.040 20.10 5.6.7 0.000 0.083 20.04 5.6.6 0.007 0.030 20.01 5.6.5 0.007 0.073 20.10 5.6.4 0.003 0.083 20.14 5.6.3 0.007 0.037 20.07 5.6.2 0.000 0.087 19.99 5.6.1 0.010 0.073 20.09 5.6.0 0.007 0.077 20.07 5.5.38 0.013 0.070 17.64 5.5.37 0.000 0.087 17.78 5.5.36 0.010 0.067 17.60 5.5.35 0.003 0.080 17.71 5.5.34 0.007 0.080 18.29 5.5.33 0.003 0.037 18.07 5.5.32 0.003 0.087 18.21 5.5.31 0.017 0.073 18.23 5.5.30 0.003 0.090 18.14 5.5.29 0.007 0.083 18.17 5.5.28 0.007 0.057 18.02 5.5.27 0.003 0.057 18.26 5.5.26 0.007 0.080 18.01 5.5.25 0.003 0.080 17.88 5.5.24 0.003 0.037 17.64 5.5.23 0.000 0.083 17.45 5.5.22 0.020 0.063 17.52 5.5.21 0.003 0.070 17.39 5.5.20 0.013 0.023 17.38 5.5.19 0.003 0.037 17.38 5.5.18 0.000 0.043 17.37 5.5.16 0.003 0.033 17.61 5.5.15 0.003 0.033 17.37 5.5.14 0.007 0.043 17.45 5.5.13 0.003 0.040 17.51 5.5.12 0.000 0.040 17.61 5.5.11 0.010 0.073 17.56 5.5.10 0.000 0.043 17.40 5.5.9 0.003 0.063 17.26 5.5.8 0.000 0.050 17.39 5.5.7 0.007 0.033 17.28 5.5.6 0.000 0.037 17.38 5.5.5 0.017 0.070 17.53 5.5.4 0.007 0.077 17.50 5.5.3 0.003 0.057 17.38 5.5.2 0.007 0.073 17.49 5.5.1 0.003 0.037 17.30 5.5.0 0.003 0.037 17.46 5.4.45 0.013 0.053 19.31 5.4.44 0.010 0.027 19.71 5.4.43 0.010 0.077 19.35 5.4.42 0.003 0.083 19.56 5.4.41 0.003 0.083 19.53 5.4.40 0.007 0.033 19.04 5.4.39 0.003 0.077 19.22 5.4.38 0.003 0.033 19.14 5.4.37 0.007 0.047 19.14 5.4.36 0.003 0.053 19.01 5.4.35 0.000 0.047 19.03 5.4.34 0.003 0.040 19.02 5.4.32 0.010 0.067 19.02 5.4.31 0.007 0.060 19.25 5.4.30 0.013 0.063 19.06 5.4.29 0.007 0.070 19.03 5.4.28 0.003 0.037 19.10 5.4.27 0.000 0.067 19.16 5.4.26 0.007 0.070 19.17 5.4.25 0.007 0.047 19.22 5.4.24 0.007 0.033 19.03 5.4.23 0.000 0.053 19.37 5.4.22 0.017 0.067 19.14 5.4.21 0.003 0.073 19.21 5.4.20 0.000 0.083 19.24 5.4.19 0.013 0.023 19.00 5.4.18 0.003 0.060 19.01 5.4.17 0.003 0.040 19.21 5.4.16 0.010 0.030 19.15 5.4.15 0.007 0.033 19.04 5.4.14 0.007 0.073 16.69 5.4.13 0.000 0.037 16.43 5.4.12 0.007 0.063 16.43 5.4.11 0.013 0.057 16.53 5.4.10 0.003 0.033 16.44 5.4.9 0.003 0.063 16.61 5.4.8 0.003 0.043 16.59 5.4.7 0.000 0.077 16.49 5.4.6 0.003 0.070 16.58 5.4.5 0.020 0.053 16.60 5.4.4 0.003 0.077 16.57 5.4.3 0.003 0.073 16.49 5.4.2 0.003 0.070 16.39 5.4.1 0.003 0.070 16.59 5.4.0 0.007 0.077 15.87
preferences:dark mode live preview
51.64 ms | 401 KiB | 5 Q