Ransford Okpoti's Dev Notes

August 11, 2008

Number To Words

Filed under: PHP — Tags: — admin @ 6:04 am

There comes a time when you really, really want a library to get a function/task performed for you and the results of your search on the internet does not give you what you actually want. Not in this case, am sure when you google the topic you should get a couple of interesting information, but the point i want to establish is that, being a little inquisitive to find out what is under the hood will help you know how the small small pieces join together to fulfill your needs.
The purpose of this posting is to give an insight into the PHP language by looking at variable definition, some control structures, classes and some inbuilt functions.

Naming variables in PHP is not all that different from other programming languages like Java, C# and the likes, the only exception is that all variables must start with the dollar sign, $, as demonstrated in the examples below.
The data type of a variable is determined by what value it holds and as a result you are not allowed to specify a variable’s data type before using it so you won’t find something like this anywhere

int $age = 30;

This is an example of a valid PHP code snippet

<?php
// this is a comment
/*
this is a multi-line comment
*/

$email = 'user@mailserver.com'; // a string variable
$year = 2010; // an integer variable

/* a reference variable provided the class Company
has already been defined */
$company = new Company();
?>

Syntactically, PHP’s control structures and class definitions are just like their counterparts in the other modern languages such as Java and C#.

<?php
/**
 * A demo of class definition.
 *
 * @package clients
 * @author ranskills
 */
public class Company{
	public static $numOfInstances = 0; // Class variable
	private $name; // Instance variable

	public function __construct($name){
		Company::$numOfInstances++;
		$this->name = trim($name);
	}

	/**
	 * Getter method for the name attribute
	 * @return string the name of the company
	 */
	public function getName(){
		return $this->name;
	}
}
?>

Another interesting thing, is the concept of associative arrays which allows you to use strings to index your arrays. eg.

<?php
$countries = array(
	// index => value
	'gh' => 'Ghana',
	'sa' => 'South Africa'
);
?>

Now, lets look at some codes to convert any integer to it’s equivalent in words in English.

<?php
// Yes, you can create your own exceptions in PHP
class ArrayIndexOutOfBoundsException extends Exception {
	function __construct($message,$code=0){
		parent::__construct($message,$code);
	}
}

class Integer{
	public function toText($amt){
		if(is_numeric($amt)){
			echo '<br/>'.number_format($amt,0,'.',',').'<br/>';
			$sign = $amt>0 ? '': 'Negative ';
			return $sign.$this->toQuadrillions(abs($amt));
		}
		else {
			throw new Exception('Only numeric values are allowed.');
		}
	}

	private function toOnes($amt){
		$words = array(
		0=>'Zero',
		1=>'One',
		2=>'Two',
		3=>'Three',
		4=>'Four',
		5=>'Five',
		6=>'Six',
		7=>'Seven',
		8=>'Eight',
		9=>'Nine'
		);

		if($amt>=0 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $amt<10)
		return $words[$amt];
		else
		throw new
		ArrayIndexOutOfBoundsException('Array Index not defined');
	}

	private function toTens($amt){ // handles 10 - 99
		$firstDigit  = intval($amt / 10);
		$remainder = $amt % 10;

		if($firstDigit==1){
			$words = array(
			0=>'Ten',
			1=>'Eleven',
			2=>'Twelve',
			3=>'Thirteen',
			4=>'Fourteen',
			5=>'Fifteen',
			6=>'Sixteen',
			7=>'Seventeen',
			8=>'Eighteen',
			9=>'Nineteen'
			);

			return $words[$remainder];
		}
		else if($firstDigit>=2 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $firstDigit<=9){
			$words = array(
			2=>'Twenty',
			3=>'Thirty',
			4=>'Fourty',
			5=>'Fifty',
			6=>'Sixty',
			7=>'Seventy',
			8=>'Eighty',
			9=>'Ninety'
			);

			$rest = $remainder==0? '': $this->toOnes($remainder);
			return $words[$firstDigit].' '. $rest;
		}
		else
		return $this->toOnes($amt);
	}

	private function toHundreds($amt){
		$ones = intval($amt / 100);
		$remainder = $amt % 100;

		if($ones>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $ones<10){
			$rest = $remainder==0 ? '': $this->toTens($remainder);
			return $this->toOnes($ones).' Hundred '. $rest;
		}
		else
		return $this->toTens($amt);
	}

	private function toThousands($amt){
		$hundreds = intval($amt / 1000);
		$remainder = $amt % 1000;

		if($hundreds>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $hundreds<1000){
			$rest = $remainder==0 ? '': $this->toHundreds($remainder);
			return $this->toHundreds($hundreds).' Thousand '. $rest;
		}
		else
		return $this->toHundreds($amt);
	}

	private function toMillions($amt){
		$hundreds = intval($amt / pow(1000, 2));
		$remainder = $amt % pow(1000, 2);

		if($hundreds>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $hundreds<1000){
			$rest = $remainder==0 ? '': $this->toThousands($remainder);
			return $this->toHundreds($hundreds).' Million '. $rest;
		}
		else
		return $this->toThousands($amt);
	}

	private function toBillions($amt){
		$hundreds = intval($amt / pow(1000, 3));
		/* Note:taking the modulos results in a negative value, but
		this seems to work pretty fine*/

		$remainder = $amt - $hundreds * pow(1000, 3);

		if($hundreds>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $hundreds<1000){
			$rest = $remainder==0 ? '': $this->toMillions($remainder);
			return $this->toHundreds($hundreds).' Billion '. $rest;
		}
		else
		return $this->toMillions($amt);
	}

	private function toTrillions($amt){
		$hundreds = intval($amt / pow(1000, 4));
		$remainder = $amt - $hundreds * pow(1000, 4);

		if($hundreds>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $hundreds<1000){
			$rest = $remainder==0 ? '': $this->toBillions($remainder);
			return $this->toHundreds($hundreds).' Trillion '. $rest;
		}
		else
		return $this->toBillions($amt);
	}

	private function toQuadrillions($amt){
		$hundreds = intval($amt / pow(1000, 5));
		$remainder = $amt - $hundreds * pow(1000, 5);

		if($hundreds>=1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $hundreds<1000){
			$rest = $remainder==0 ? '': $this->toTrillions($remainder);
			return $this->toHundreds($hundreds).' Quadrillion '. $rest;
		}
		else
		return $this->toTrillions($amt);
	}

}

$obj = new Integer();

echo $obj->toText(5234567);
echo $obj->toText(-4191770001230128);
?>

This is the output of the above code when run

5,234,567
Five Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven

-4,191,770,001,230,128
Negative Four Quadrillion One Hundred Ninety One Trillion Seven Hundred Seventy Billion One Million Two Hundred Thirty Thousand One Hundred Twenty Eight

With this knowledge, you can attempt to write a program to convert an amount to words including the name of the currency.

Powered by WordPress