<?php
/**
* Licensed under GNU General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author Gordon Pettey <hide@address.com>
* @copyright 2008
* @version 1.2
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
* @package Numeral
*/
/**
* Roman Numeral conversion
*
* Takes input value in either Roman or Hindu (modern western/european) numerals,
* and outputs the same value in either type. Can also do a few other things.
*
* @author Gordon Pettey <hide@address.com>
* @copyright 2008
* @version 1.2
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
* @package Numeral
*
* class numeral
*/
class numeral {
/**
* @var array Contains a list of Hindu digits.
*/
protected $htypes;
/**
* @var array Contains a list of Roman "digits".
*/
protected $rtypes;
/**
* @var string Stores current type. "R" if Roman, "H" if Hindu.
*/
protected $currenttype;
/**
* @var array List of Hindu numerals for type-checking
*/
protected $hvals;
/**
* @var array List of Roman numerals for type-checking
*/
protected $rvals;
/**
* @var array Keys are unique Roman numerals, values are Hindu equivalent
*/
protected $romarr;
/**
* @var int|string Integer or string input value.
*/
protected $inval;
/**
* function checkType
* @uses $rvals
* @uses $inval
* @uses raiseError Returns error if type is invalid
*/
private function checkType($checkvalue) {
if (is_int($checkvalue)) {
return "H";
} elseif (is_string($checkvalue)) {
$isrom = 1;
$isnum = 1;
while ($a < strlen($checkvalue)) {
if (in_array(substr($checkvalue,$a,1),$this->rvals) || in_array(substr($checkvalue,$a,2),$this->rvals)) {
$isnum = 0;
}
if (!in_array(substr($checkvalue,$a,1),$this->rvals) && !in_array(substr($checkvalue,$a,2),$this->rvals)) {
$isrom = 0;
}
$a++;
}
if ($isnum && !$isrom) {
if (is_string($this->inval)) {
$this->inval = (int) $this->inval;
}
return "H";
}
if ($isrom && !$isnum) {
return "R";
}
if (($isrom && $isnum) || !($isrom && !$isnum)) {
die($this->raiseError(1));
}
}
}
/**
* function __construct Creates an object.
* @param int|string $inval Input value if set on object creation.
* @uses $inval Stores input value.
* @uses $rtypes Stores a list of Roman "digits"
* @uses $htypes Stores a list of Hindu digits
* @uses $romarr Stores Hindu numerals referenced by Roman numerals
* @uses $hvals Stores Hindu numerals for type-checking
* @uses $rvals Stores Roman numerals for type-checking
*/
function __construct($inval = NULL) {
if (!is_null($inval)) {
$this->inval = $inval;
$this->currenttype = $this->checkType($inval);
}
$this->rtypes = array(
"R", "r", "I", "i"
);
$this->htypes = array(
"H", "h", "N", "n", "1", 1
);
$this->romarr = array(
"_M" => 1000000,
"_C_M" => 900000,
"_D" => 500000,
"_C_D" => 400000,
"_C" => 100000,
"_X_C" => 90000,
"_L" => 50000,
"_X_L" => 40000,
"_X" => 10000,
"M_X" => 9000,
"_I_X" => 9000,
"_V" => 5000,
"M_V" => 4000,
"_I_V" => 4000,
"M" => 1000,
"_I" => 1000,
"CM" => 900,
"D" => 500,
"CD" => 400,
"C" => 100,
"XC" => 90,
"L" => 50,
"XL" => 40,
"X" => 10,
"IX" => 9,
"V" => 5,
"IV" => 4,
"I" => 1
);
$this->rvals = array(
"_M","_D","_C","_L","_X","_V","M","D","C","L","X","V","I"
);
$this->hvals = array(
0,1,2,3,4,5,6,7,8,9
);
}
/**
* function raiseError Returns an error, depending on param.
* @param int $errtype Error type to return.
*/
private function raiseError($errtype) {
switch ($errtype) {
case 1:
return "INPUT NOT ROMAN OR HINDU";
break;
case 2:
return "INVALID TYPE SELECTED";
break;
}
}
/**
* function getValue Returns current value, regardless of type.
* @param int|string Optional input value.
* @uses setValue() Sets value if input param is used.
* @return int|string Current value of object.
*/
function getValue($input = NULL) {
if (!is_null($input)) { $this->setValue($input); }
return $this->inval;
}
/**
* function getType Returns type of current value, either "Roman" or "Hindu".
* @param int|string $input Optional input.
* @uses currenttype Stores current type.
* @uses setValue() Sets value if input param is used.
* @return string "Roman" or "Hindu"
*/
function getType($input = NULL) {
if (!is_null($input)) { $this->setValue($input); }
if ($this->currenttype == "R") { return "Roman"; }
if ($this->currenttype == "H") { return "Hindu"; }
}
/**
* function setValue Sets object value.
* @param int|string $inval Input value.
* @uses $inval Stores value.
* @uses $currenttype Stores value type.
*/
function setValue($inval) {
$this->inval = $inval;
$this->currenttype = $this->checkType($inval);
}
/**
* function convert Checks whether current value is Roman or Hindu, and returns opposite type.
* @param int|string $input Optional input.
* @uses setValue() Sets value if input param is used.
*/
function convert($input = NULL) {
if (!is_null($input)) { $this->setValue($input); }
if ($this->currenttype == "H") {
return $this->getRoman();
}
if ($this->currenttype == "R") {
return $this->getHindu();
}
}
/**
* function getRoman Returns object value in Roman.
* @param int|string $input Optional input.
* @uses setValue() Sets value if input param is used.
* @return string String containing Roman value.
*/
function getRoman($input = NULL) {
if ($input != NULL) { $this->setValue($input); }
if ($this->currenttype == "R") {
return $this->inval;
} else {
return $this->toRoman($this->inval);
}
}
/**
* function getHindu Returns object value in Hindu.
* @param int|string $input Optional input.
* @uses setValue() Sets value if input param is used.
* @return int Integer containing Hindu value.
*/
function getHindu($input = NULL) {
if ($input != NULL) { $this->setValue($input); }
if ($this->currenttype == "H") {
return $this->inval;
} else {
return $this->toHindu($this->inval);
}
}
/**
* function toRoman Converts input to Roman format.
* @param int $input Integer input value.
* @return string String containing Roman output.
*/
private function toRoman($input) {
$rstr = "";
foreach($this->romarr as $romkey => $hinval) {
while ($input - $hinval >= 0) {
$rstr .= $romkey;
$input -= $hinval;
}
}
return $rstr;
}
/**
* function toHindu Converts input to Hindu format.
* @param string $input String input value.
* @return int Integer containing Hindu output.
*/
private function toHindu($input) {
$hint = 0;
foreach($this->romarr as $romkey => $hinval) {
while (substr($input,0,4) == $romkey) {
$hint += $hinval;
$input = substr($input,4,strlen($input)-1);
}
while (substr($input,0,3) == $romkey) {
$hint += $hinval;
$input = substr($input,3,strlen($input)-1);
}
while (substr($input,0,2) == $romkey) {
$hint += $hinval;
$input = substr($input,2,strlen($input)-1);
}
while (substr($input,0,1) == $romkey) {
$hint += $hinval;
$input = substr($input,1,strlen($input)-1);
}
}
return $hint;
}
}
?>