Numbers_Roman
[ class tree: Numbers_Roman ] [ index: Numbers_Roman ] [ all elements ]

Source for file Roman.php

Documentation is available at Roman.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors :  David Costa <gurugeek@php.net>                            |
  17. // |            Sterling Hughes <sterling@php.net>                        |
  18. // +----------------------------------------------------------------------+
  19. // $Id: Roman.php,v 1.14 2004/04/28 13:13:08 danielc Exp $
  20.  
  21. // {{{ Numbers_Roman
  22.  
  23. /**
  24.  * Provides utilities to convert roman numerals to
  25.  * arabic numbers and convert arabic numbers to roman numerals.
  26.  *
  27.  * Supports lower case input and output and some furthers conversion
  28.  * functions.
  29.  *
  30.  * @access public
  31.  * @author David Costa <gurugeek@php.net>
  32.  * @author Sterling Hughes <sterling@php.net>
  33.  * @package Numbers_Roman
  34.  */
  35. {
  36.     // {{{ toNumber()
  37.  
  38.     /**
  39.      * Converts a roman numeral to a number
  40.      *
  41.      * @param  string  $roman The roman numeral to convert
  42.      *                         lower cased numerals are converted into
  43.      *                         uppercase
  44.      * @return integer $num   The number corresponding to the
  45.      *                         given roman numeral
  46.      * @access public
  47.      */
  48.     function toNumber($roman)
  49.     {
  50.         $roman strtoupper($roman);
  51.  
  52.         /*
  53.          * Replacing the Numerals representing an integer higher then 4000
  54.          * e.g. _X represent 10 000 _L  represent 50 000 etc
  55.          * we first convert them into single characters
  56.          */
  57.         $roman str_replace('_V''S'$roman);
  58.         $roman str_replace('_X''R'$roman);
  59.         $roman str_replace('_L''Q'$roman);
  60.         $roman str_replace('_C''P'$roman);
  61.         $roman str_replace('_D''O'$roman);
  62.         $roman str_replace('_M''N'$roman);
  63.  
  64.         $conv = array(
  65.             array('letter' => 'I''number' => 1),
  66.             array('letter' => 'V''number' => 5),
  67.             array('letter' => 'X''number' => 10),
  68.             array('letter' => 'L''number' => 50),
  69.             array('letter' => 'C''number' => 100),
  70.             array('letter' => 'D''number' => 500),
  71.             array('letter' => 'M''number' => 1000),
  72.             array('letter' => 'S''number' => 5000),
  73.             array('letter' => 'R''number' => 10000),
  74.             array('letter' => 'Q''number' => 50000),
  75.             array('letter' => 'P''number' => 100000),
  76.             array('letter' => 'O''number' => 500000),
  77.             array('letter' => 'N''number' => 1000000),
  78.             array('letter' => 0'number' => 0)
  79.         );
  80.  
  81.         $arabic = 0;
  82.         $state = 0;
  83.         $sidx = 0;
  84.         $len strlen($roman- 1;
  85.  
  86.         while ($len >= 0{
  87.             $i = 0;
  88.             $sidx $len;
  89.  
  90.             while ($conv[$i]['number'> 0{
  91.                 if (strtoupper($roman[$sidx]== $conv[$i]['letter']{
  92.                     if ($state $conv[$i]['number']{
  93.                         $arabic -= $conv[$i]['number'];
  94.                     else {
  95.                         $arabic += $conv[$i]['number'];
  96.                         $state $conv[$i]['number'];
  97.                     }
  98.                 }
  99.                 $i++;
  100.             }
  101.             $len--;
  102.         }
  103.  
  104.         return $arabic;
  105.     }
  106.  
  107.     // }}}
  108.     // {{{ toRoman()
  109.  
  110.     /**
  111.      * A backwards compatibility alias for toNumeral()
  112.      *
  113.      * @access private
  114.      */
  115.     function toRoman($num$uppercase = true)
  116.     {
  117.         return $this->toNumeral($num$uppercase);
  118.     }
  119.  
  120.     // }}}
  121.     // {{{ toNumeral()
  122.  
  123.     /**
  124.      * Converts a number to its roman numeral representation
  125.      *
  126.      * @param  integer $num         An integer between 0 and 3999
  127.      *                               inclusive that should be converted
  128.      *                               to a roman numeral integers higher than
  129.      *                               3999 are supported from version 0.1.2
  130.      *            Note:
  131.      *            For an accurate result the integer shouldn't be higher
  132.      *            than 5 999 999. Higher integers are still converted but
  133.      *            they do not reflect an historically correct Roman Numeral.
  134.      *
  135.      * @param  bool    $uppercase   Uppercase output: default true
  136.      *
  137.      * @param  bool    $html        Enable html overscore required for
  138.      *                               integers over 3999. default true
  139.      * @return string  $roman The corresponding roman numeral
  140.      *
  141.      * @access public
  142.      */
  143.     function toNumeral($num$uppercase = true$html = true)
  144.     {
  145.         $conv = array(10 => array('X''C''M'),
  146.         5 => array('V''L''D'),
  147.         1 => array('I''X''C'));
  148.         $roman '';
  149.  
  150.         if ($num < 0{
  151.             return '';
  152.         }
  153.  
  154.         $num = (int) $num;
  155.  
  156.         $digit = (int) ($num / 1000);
  157.         $num -= $digit * 1000;
  158.         while ($digit > 0{
  159.             $roman .= 'M';
  160.             $digit--;
  161.         }
  162.  
  163.         for ($i = 2; $i >= 0; $i--{
  164.             $power pow(10$i);
  165.             $digit = (int) ($num $power);
  166.             $num -= $digit $power;
  167.  
  168.             if (($digit == 9|| ($digit == 4)) {
  169.                 $roman .= $conv[1][$i$conv[$digit+1][$i];
  170.             else {
  171.                 if ($digit >= 5{
  172.                     $roman .= $conv[5][$i];
  173.                     $digit -= 5;
  174.                 }
  175.  
  176.                 while ($digit > 0{
  177.                     $roman .= $conv[1][$i];
  178.                     $digit--;
  179.                 }
  180.             }
  181.         }
  182.  
  183.         /*
  184.          * Preparing the conversion of big integers over 3999.
  185.          * One of the systems used by the Romans  to represent 4000 and
  186.          * bigger numbers was to add an overscore on the numerals.
  187.          * Because of the non ansi equivalent if the html output option
  188.          * is true we will return the overline in the html code if false
  189.          * we will return a _ to represent the overscore to convert from
  190.          * numeral to arabic we will always expect the _ as a
  191.          * representation of the html overscore.
  192.          */
  193.         if ($html == true{
  194.             $over '<span style="text-decoration:overline;">';
  195.             $overe '</span>';
  196.         elseif ($html == false{
  197.             $over '_';
  198.             $overe '';
  199.         }
  200.  
  201.         /*
  202.          * Replacing the previously produced multiple MM with the
  203.          * relevant numeral e.g. for 1 000 000 the roman numeral is _M
  204.          * (overscore on the M) for 900 000 is _C_M (overscore on both
  205.          * the C and the M) We initially set the replace to AFS which
  206.          * will be later replaced with the M.
  207.          *
  208.          * 500 000 is   _D (overscore D) in Roman Numeral
  209.          * 400 000 is _C_D (overscore on both C and D) in Roman Numeral
  210.          * 100 000 is   _C (overscore C) in Roman Numeral
  211.          *  90 000 is _X_C (overscore on both X and C) in Roman Numeral
  212.          *  50 000 is   _L (overscore L) in Roman Numeral
  213.          *  40 000 is _X_L (overscore on both X and L) in Roman Numeral
  214.          *  10 000 is   _X (overscore X) in Roman Numeral
  215.          *   5 000 is   _V (overscore V) in Roman Numeral
  216.          *   4 000 is M _V (overscore on the V only) in Roman Numeral
  217.          *
  218.          * For an accurate result the integer shouldn't be higher then
  219.          * 5 999 999. Higher integers are still converted but they do not
  220.          * reflect an historically correct Roman Numeral.
  221.          */
  222.         $roman str_replace(str_repeat('M'1000),
  223.                              $over.'AFS'.$overe$roman);
  224.         $roman str_replace(str_repeat('M'900),
  225.                              $over.'C'.$overe.$over.'AFS'.$overe$roman);
  226.         $roman str_replace(str_repeat('M'500),
  227.                              $over.'D'.$overe$roman);
  228.         $roman str_replace(str_repeat('M'400),
  229.                              $over.'C'.$overe.$over.'D'.$overe$roman);
  230.         $roman str_replace(str_repeat('M'100),
  231.                              $over.'C'.$overe$roman);
  232.         $roman str_replace(str_repeat('M'90),
  233.                              $over.'X'.$overe.$over.'C'.$overe$roman);
  234.         $roman str_replace(str_repeat('M'50),
  235.                              $over.'L'.$overe$roman);
  236.         $roman str_replace(str_repeat('M'40),
  237.                              $over.'X'.$overe.$over.'L'.$overe$roman);
  238.         $roman str_replace(str_repeat('M'10),
  239.                              $over.'X'.$overe$roman);
  240.         $roman str_replace(str_repeat('M'5),
  241.                              $over.'V'.$overe$roman);
  242.         $roman str_replace(str_repeat('M'4),
  243.                              'M'.$over.'V'.$overe$roman);
  244.  
  245.         /*
  246.          * Replacing AFS with M used in both 1 000 000
  247.          * and 900 000
  248.          */
  249.         $roman str_replace('AFS''M'$roman);
  250.  
  251.         /*
  252.          * Checking for lowercase output
  253.          */
  254.         if ($uppercase == false{
  255.             $roman strtolower($roman);
  256.         }
  257.  
  258.         return $roman;
  259.     }
  260.  
  261.     // }}}
  262.  
  263. }
  264.  
  265. // }}}
  266.  
  267. /*
  268.  * Local variables:
  269.  * tab-width: 4
  270.  * c-basic-offset: 4
  271.  * End:
  272.  */
  273.  
  274. ?>

Documentation generated on Mon, 11 Mar 2019 10:16:08 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.