Posted By

Scooter on 05/19/08


Tagged

roman numerals


Versions (?)

Who likes this?

3 people have marked this snippet as a favorite

Bron
wizard04
LordBumpet


Roman Numerals


 / Published in: PHP
 

URL: http://reusablecode.blogspot.com/search/label/roman%20numerals

A library of functions for converting between Arabic and Roman numerals.

  1. <?php
  2. /*
  3.   PHP Roman Numeral Library
  4.  
  5.   Copyright (c) 2008, reusablecode.blogspot.com; some rights reserved.
  6.  
  7.   This work is licensed under the Creative Commons Attribution License. To view
  8.   a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or
  9.   send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
  10.   94305, USA.
  11.   */
  12.  
  13. // Convert Arabic numerals into Roman numerals.
  14. function roman($arabic)
  15. {
  16. $fractions = Array("", "�", "��", "���", "����", "�����", "S", "S�", "S��", "S���", "S����", "S�����", "I");
  17. $ones = Array("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX");
  18. $tens = Array("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC");
  19. $hundreds = Array("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM");
  20. $thousands = Array("", "M", "MM", "MMM", "MMMM");
  21.  
  22. if ($arabic > 4999)
  23. {
  24. // For large numbers (five thousand and above), a bar is placed above a base numeral to indicate multiplication by 1000.
  25. // Since it is not possible to illustrate this in plain ASCII, this function will refuse to convert numbers above 4999.
  26. die("Cannot represent numbers larger than 4999 in plain ASCII.");
  27. }
  28. elseif ($arabic == 0)
  29. {
  30. // About 725, Bede or one of his colleagues used the letter N, the initial of nullae,
  31. // in a table of epacts, all written in Roman numerals, to indicate zero.
  32. return "N";
  33. }
  34. else
  35. {
  36. // Handle fractions that will round up to 1.
  37. if (round(fmod($arabic, 1) * 12) == 12)
  38. {
  39. $arabic = round($arabic);
  40. }
  41.  
  42. // With special cases out of the way, we can proceed.
  43. // NOTE: modulous operator (%) only supports integers, so fmod() had to be used instead to support floating point.
  44. $roman = $thousands[($arabic - fmod($arabic, 1000)) / 1000];
  45. $arabic = fmod($arabic, 1000);
  46. $roman .= $hundreds[($arabic - fmod($arabic, 100)) / 100];
  47. $arabic = fmod($arabic, 100);
  48. $roman .= $tens[($arabic - fmod($arabic, 10)) / 10];
  49. $arabic = fmod($arabic, 10);
  50. $roman .= $ones[($arabic - fmod($arabic, 1)) / 1];
  51. $arabic = fmod($arabic, 1);
  52.  
  53. // Handling for fractions.
  54. if ($arabic > 0)
  55. {
  56. $roman .= $fractions[round($arabic * 12)];
  57. }
  58.  
  59. return $roman;
  60. }
  61. }
  62.  
  63. // Expand subtractive notation in Roman numerals.
  64. function roman_expand($roman)
  65. {
  66. $roman = str_replace("CM", "DCCCC", $roman);
  67. $roman = str_replace("CD", "CCCC", $roman);
  68. $roman = str_replace("XC", "LXXXX", $roman);
  69. $roman = str_replace("XL", "XXXX", $roman);
  70. $roman = str_replace("IX", "VIIII", $roman);
  71. $roman = str_replace("IV", "IIII", $roman);
  72. return $roman;
  73. }
  74.  
  75. // Compress Roman numerals using subtractive notation.
  76. function roman_compress($roman)
  77. {
  78. $roman = str_replace("DCCCC", "CM", $roman);
  79. $roman = str_replace("CCCC", "CD", $roman);
  80. $roman = str_replace("LXXXX", "XC", $roman);
  81. $roman = str_replace("XXXX", "XL", $roman);
  82. $roman = str_replace("VIIII", "IX", $roman);
  83. $roman = str_replace("IIII", "IV", $roman);
  84. return $roman;
  85. }
  86.  
  87. // Convert Roman numerals into Arabic numerals.
  88. function arabic($roman)
  89. {
  90. $result = 0;
  91.  
  92. // Remove subtractive notation.
  93. $roman = roman_expand($roman);
  94.  
  95. // Calculate for each numeral.
  96. $result += substr_count($roman, 'M') * 1000;
  97. $result += substr_count($roman, 'D') * 500;
  98. $result += substr_count($roman, 'C') * 100;
  99. $result += substr_count($roman, 'L') * 50;
  100. $result += substr_count($roman, 'X') * 10;
  101. $result += substr_count($roman, 'V') * 5;
  102. $result += substr_count($roman, 'I');
  103. return $result;
  104. }
  105.  
  106. // Validate a roman numeral.
  107. function isRoman($roman)
  108. {
  109. return preg_match("/[MDCLXVI]/u", $roman);
  110. }
  111. ?>

Report this snippet  

You need to login to post a comment.