Location: PHPKode > scripts > Arabic and Roman Numeral Convertor > arabic-and-roman-numeral-convertor/arroconvertor.class.php
<?php
/*************************************************************
*              Arabic/Roman Numeral Convertor                *
*                                                            *
* For converting between integers and Roman Numerals as well *
* as checking the validity of Roman Numerals.                *
*                                                            *
*     1    I                                                 *
*     5    V         5,000     V                             *
*     10   X         10,000    X                             *
*     50   L         50,000    L                             *
*     100  C         100,000   C                             *
*     500  D         500,000   D                             *
*     1000 M         1,000,000 M                             *
*                                                            *
* Copyright (C)  Dmitry Zarezenko, 2005                      *
*       E-mail : hide@address.com                    *
*************************************************************/

require ("error.class.php");

class ArRoConvertor{
   // Constructor
	function ArRoConvertor (){
	
	}

	/***********************************
	* These first arrays are used by   *
	* the functions which convert      *
	* roman numerals into arabic.      *
	***********************************/
	
	var $counter= Array();
	var $romans = Array("I" => 1, "V" => 5, "X" => 10, "L" => 50, "C" => 100, "D" => 500, "M" => 1000, "" => 0);
	var $subs   = Array("I" => true, "X" => true, "C" => true, "M" => true);
	
	/***********************************
	* This first function is a pretty  *
	* simple and generic function used *
	* to define and throw errors       *
	***********************************/
	
	function createError($ErrorName, $ErrorMessage) {
		$theError = new Error();
		$theError->name = $ErrorName;
		$theError->message = $ErrorMessage;
		$theError->throw();
	}
	
	/***********************************
	* These next four functions are    *
	* used to test for errors in the   *
	* input and convert roman numerals *
	* into arabic integers.            *
	***********************************/
	
	function checkRom($Rcur, $Rnext, $lSub, $n, $l) {
		if (!isSet($this->romans[$Rcur]) || (!isSet($this->romans[$Rnext]) && (($n+1) < $l))) {
			$this->createError("InputError", "Not a Roman Numeral");
		}
		else if ($this->romans[$Rcur] >= $lSub) {
			$this->createError("InputError", "Not a Properly Formed Numeral");
		}
	}
	
	function testSub($cR, $nR, $pR) {
	   if (isSet ($this->romans[$cR]) && isSet ($this->romans[$nR]) && isSet ($this->romans[$pR])){
			if ($this->romans[$cR] < $this->romans[$nR]) {
				if (($this->romans[$pR] == $this->romans[$nR]) && ($this->subs[$nR] != true)) {
					$this->createError("InputError", "Not a Properly Formed Numeral");
				}
				else if (($this->subs[$cR] == true) && (10*$this->romans[$cR] >= $this->romans[$nR])) {
					return true;
				}
				else {
					$this->createError("InputError", "Not a Properly Formed Numeral");
					return false;
				}
			}
		}
		return false;
	}
	
	function testRom($rome) {
	   if (!isSet ($this->counter[$rome])) return false;
		if ($this->counter[$rome] < 3) {
			return true;
		}
		else {
			$this->createError("InputError", "Not a Properly Formed Numeral");
		}
		return false;
	}
	
	function RomanToArabic ($rNumb) {
		$this->counter["I"] = 0;
		$this->counter["V"] = 2;
		$this->counter["X"] = 0;
		$this->counter["L"] = 2;
		$this->counter["C"] = 0;
		$this->counter["D"] = 2;
		$this->counter["M"] = -1000000000; // Negative infinity
		$intNumb = 0;
		$lastNumb = 1000000000; // Positive infinity
		$thisNumb = 0;
		$lastSub = 1000000000; // Positive infinity
	
		$rNumb= strtoupper ($rNumb);
		/*$tmpNumb= preg_replace ( "/[^IVXLCDM]/m", '', $rNumb);
		if ($tmpNumb!= $rNumb) $this->createError("Warning", "$rNumb is not a Roman numeral, was changed on $tmpNumb");
		$rNumb= $tmpNumb;*/
		$len= strlen ($rNumb);
		for ($i= 0; $i< $len; $i++){
			$currentR = $rNumb[$i];
			@$nextR    = $rNumb[$i+1];
			@$prevR    = $rNumb[$i-1];
	
			$this->checkRom ($currentR, $nextR, $lastSub, $i, $len);
			if ($this->testSub ($currentR, $nextR, $prevR)) {
				$thisNumb = $this->romans[$nextR] - $this->romans[$currentR];
				$i ++;
				$lastSub = $this->romans[$currentR];
			}
			else if ($this->testRom($currentR)){
				$thisNumb = $this->romans[$currentR];
				$this->counter[$currentR] ++;
			}
			if ($thisNumb > $lastNumb) {
				$this->createError("InputError", "Not a Properly Formed Numeral");
			}
			else {
				$intNumb += $thisNumb;
				$lastNumb = $thisNumb;
			}
		}
		return $intNumb;
	}
	
	/***********************************
	* The next two functions are used  *
	* for converting an arabic integer *
	* into a roman Numeral.            *
	***********************************/
	
	function Cut($num, $n){
		return ($num - ($num % $n ) ) / $n;
	}
	
	function ArabicToRoman ($aNumb) {
	   if (!is_int ($aNumb)){
			$this->createError("InputError", "$aNumb is not a Arabic Integer");
			return "";
		}
		$rNumb= "";
		while ($aNumb> 5999) { $rNumb.= "M"; $aNumb-= 1000;}
		if(($aNumb > 0)) {
			$mill = Array("", "M", "MM", "MMM", "MMMM", "MMMMM");
			$cent = Array("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM");
			$tens = Array("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC");
			$ones = Array("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX");
	
			$m = $this->Cut($aNumb, 1000); $aNumb%= 1000;
			$c = $this->Cut($aNumb, 100); $aNumb%= 100;
			$t = $this->Cut($aNumb, 10); $aNumb%= 10;
			
			return $rNumb . $mill[$m] . $cent[$c] . $tens[$t] . $ones[$aNumb];
		}
		else {
		   $this->createError("InputError", "Numbers from 1 to 5999 only please.");
			return "";
		}
	}
}

?>
Return current item: Arabic and Roman Numeral Convertor