Conversion of roman numerals

Version Française

On this page, you'll find a roman numeral converter, an explanation of the algorithm and a Java implementation.

Convert your numbers

To convert a number into roman numerals, enter a number between 1 and 3999 in the "Arab" area and click on the down arrow.
To convert a roman number into arab numerals, enter the number in the "Roman" area and click on the up arrow.

Your browser does not support Java Applets.
Download Java.

How it works

The above program uses the following algorithm. This algorithm implements the conversion rules explained in the wikipedia article about roman numerals. The algorithm begins by giving the computer the knowledge of basic roman numerals {I, V, X, L, C, D, M} and the following combinations of roman numerals: {IV, IX, XL, XC, CD, CM}.The reunion of those basic roman numbers and combinations forms a list of elementary roman numbers, whose values decline as follows:

Elementary
roman
numbers
Corresponding
values
M 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

Arab-Roman Conversion

Let's begin with the conversion of arab numerals into roman numerals. In this direction of conversion, the user enters a integer between 1 and 3999.

The algorithm verifies if the number to convert is greater than or equal to the value of the greatest elementary roman number.
If it is, it concatenates to the result the elementary roman number and it withdraws the corresponding value to the initial number.
If it isn't, it jumps to the immediately inferior value.
And so on, until the rest of the initial number gets to zero:

Rest Result
2684 -
1684 M
684 MM
184 MMD
84 MMDC
34 MMDCL
24 MMDCLX
14 MMDCLXX
4 MMDCLXXX
0 MMDCLXXXIV

Roman-Arab Conversion

For the opposite conversion, from roman numerals to arab numerals, the algorithm follows a similar process.
To begin with, the algorithm verifies if the roman number to convert begins with the greatest elementary roman number.
If it does, it adds to the result the corresponding value and increases the verification position with the length of the elementary roman number.
If it doesn't, it verifies with the elementary roman number immediately inferior.
And so on, until the verification position is the end of the initial roman number.

Verification

As described above, the algorithm converts not only valid roman numbers but invalid roman numbers composed of elementary roman numbers as well. For example, the conversion of "IIIIIII" to "7" is incorrect. Thus, we must verify that the given roman number to convert is valid.

To verify the validity of a roman number, the algorithm proceeds in the following way. The conversion of an arab number into roman numerals being bijective, the algorithm converts the given roman number to arab and then converts it to roman numerals. If the result is identical to the initial roman number, the number is valid. If not, it's invalid.

Implementation in Java

The above algorithm can be implemented in Java in the following way. In the listing bellow, the elementary roman numbers and their equivalents are indicated in blue, the conversion operations in red and the verification in green.

public class RomanNumber {

   private final static String[] BASIC_ROMAN_NUMBERS = { "M", "CM", "D", "CD",
         "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
   private final static int[] BASIC_VALUES = { 1000, 900, 500, 400, 100, 90,
         50, 40, 10, 9, 5, 4, 1 };

   private int value;
   private String romanString;

   public RomanNumber(int value) throws IllegalArgumentException {
      if (1 <= value && value <= 3999) {
         this.value = value;
      } else {
         throw new IllegalArgumentException("" + value);
      }
   

   public RomanNumber(String s) throws IllegalArgumentException {
      String r = s.toUpperCase();
      int index = 0;
      for (int i = 0; i < BASIC_ROMAN_NUMBERS.length; i++) {
         while (r.startsWith(BASIC_ROMAN_NUMBERS[i], index)) {
            this.value += BASIC_VALUES[i];
            index += BASIC_ROMAN_NUMBERS[i].length();
         }
      }

      // Verifies whether the input string is a valid roman number or not.
      RomanNumber tempVerify;
      try {
         tempVerify = new RomanNumber(this.value);
      } catch (IllegalArgumentException e) {
         throw new IllegalRomanNumeralException(s);
      }
      if ((verifyString = tempVerify.toRomanValue()).equals(r)) {
         this.romanString = r;
      } else {
         throw new IllegalRomanNumeralException(s,verifyString);
      }

  }

  public String toRomanValue() {
      if (this.romanString == null) {
         this.romanString = "";
         int remainder = this.value;
         for (int i = 0; i < BASIC_VALUES.length; i++) {
            while (remainder >= BASIC_VALUES[i]) {
               this.romanString += BASIC_ROMAN_NUMBERS[i];
               remainder -= BASIC_VALUES[i];
            }
         }

      }
      return this.romanString;
   }
   
   public int getValue() {
      return this.value;
   }
}

Download the source code and the demonstration program.

For those who prefer to execute the demonstration program with Java Web Start, here's the JNLP version. If the link doesn't work, try "Save target as..."

Add to Google

Thanks

I'd like to thank Jean-Pierre Norguet for his help with the design of the algorithm and the writing of this article.

Questions

If you have any question about the algorithm, don't hesitate to contact me.

MoxLotus.