Roman Numerals

From CodeCodex

PHP[edit]

<highlightsyntax> <?php

   /*
   PHP Roman Numeral Library
   Copyright (c) 2008, reusablecode.blogspot.com; some rights reserved.
   This work is licensed under the Creative Commons Attribution License. To view
   a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or
   send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
   94305, USA.
   */
   // Convert Arabic numerals into Roman numerals.
   function roman($arabic)
   {
       $fractions = Array("", "•", "••", "•••", "••••", "•••••", "S", "S•", "S••", "S•••", "S••••", "S•••••", "I");
       $ones = Array("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX");
       $tens = Array("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC");
       $hundreds = Array("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM");
       $thousands = Array("", "M", "MM", "MMM", "MMMM");
       
       if ($arabic > 4999)
       {
           // For large numbers (five thousand and above), a bar is placed above a base numeral to indicate multiplication by 1000.
           // Since it is not possible to illustrate this in plain ASCII, this function will refuse to convert numbers above 4999.
           die("Cannot represent numbers larger than 4999 in plain ASCII.");
       }
       elseif ($arabic == 0)
       {
           // About 725, Bede or one of his colleagues used the letter N, the initial of nullae,
           // in a table of epacts, all written in Roman numerals, to indicate zero.
           return "N";
       }
       else
       {
           // Handle fractions that will round up to 1.
           if (round(fmod($arabic, 1) * 12) == 12)
           {
               $arabic = round($arabic);
           }
           // With special cases out of the way, we can proceed.
           // NOTE: modulous operator (%) only supports integers, so fmod() had to be used instead to support floating point.
           $roman = $thousands[($arabic - fmod($arabic, 1000)) / 1000];
           $arabic = fmod($arabic, 1000);
           $roman .= $hundreds[($arabic - fmod($arabic, 100)) / 100];
           $arabic = fmod($arabic, 100);
           $roman .= $tens[($arabic - fmod($arabic, 10)) / 10];
           $arabic = fmod($arabic, 10);
           $roman .= $ones[($arabic - fmod($arabic, 1)) / 1];
           $arabic = fmod($arabic, 1);
           // Handling for fractions.
           if ($arabic > 0)
           {
               $roman .= $fractions[round($arabic * 12)];
           }
           return $roman;
       }
   }
   
   // Expand subtractive notation in Roman numerals.
   function roman_expand($roman)
   {
       $roman = str_replace("CM", "DCCCC", $roman);
       $roman = str_replace("CD", "CCCC", $roman);
       $roman = str_replace("XC", "LXXXX", $roman);
       $roman = str_replace("XL", "XXXX", $roman);
       $roman = str_replace("IX", "VIIII", $roman);
       $roman = str_replace("IV", "IIII", $roman);
       return $roman;
   }
   // Compress Roman numerals using subtractive notation.
   function roman_compress($roman)
   {
       $roman = str_replace("DCCCC", "CM", $roman);
       $roman = str_replace("CCCC", "CD", $roman);
       $roman = str_replace("LXXXX", "XC", $roman);
       $roman = str_replace("XXXX", "XL", $roman);
       $roman = str_replace("VIIII", "IX", $roman);
       $roman = str_replace("IIII", "IV", $roman);
       return $roman;
   }
   
   // Convert Roman numerals into Arabic numerals.
   function arabic($roman)
   {
       $result = 0;
       
       // Remove subtractive notation.
       $roman = roman_expand($roman);
       
       // Calculate for each numeral.
       $result += substr_count($roman, 'M') * 1000;
       $result += substr_count($roman, 'D') * 500;
       $result += substr_count($roman, 'C') * 100;
       $result += substr_count($roman, 'L') * 50;
       $result += substr_count($roman, 'X') * 10;
       $result += substr_count($roman, 'V') * 5;
       $result += substr_count($roman, 'I');
       return $result;
   }

?>

</pre>