**I just announced the new *** Learn Spring * course, focused on the fundamentals of Spring 5 and Spring Boot 2:

*Learn Spring*course, focused on the fundamentals of Spring 5 and Spring Boot 2:

**>> CHECK OUT THE COURSE**

Last modified: April 30, 2019

The ancient Romans developed their own numeric system called Roman numerals. The system uses letters with different values to represent numbers. Roman numerals are still used today in some minor applications.

In this tutorial, we'll implement **simple converters that will transform numbers from one system to the other.**

In the Roman system, we have **7 symbols that represent numbers**:

*I*represents 1*V*represents 5*X*represents 10*L*represents 50*C*represents 100*D*represents 500*M*represents 1000

Originally, people used to represent a 4 with IIII or 40 with XXXX. This can be quite uncomfortable to read. It's also easy to mistake four symbols next to each other for three symbols.

**Roman numerals use subtractive notation **to avoid such mistakes. Instead of saying *four times one* (IIII), one can say that it's *one less than five* (IV).

How's it important from our perspective? It's important because instead of simply adding numbers symbol by symbol, we might need to check the next symbol to determine if the number should be added or subtracted.

Let's define an enum to represent the Roman Numerals:

enum RomanNumeral { I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000); private int value; RomanNumeral(int value) { this.value = value; } public int getValue() { return value; } public static List<RomanNumeral> getReverseSortedValues() { return Arrays.stream(values()) .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed()) .collect(Collectors.toList()); } }

Notice that we've defined additional symbols to help out with subtractive notation. We have also defined an additional method named *getReverseSortedValues()*.

This method will allow us to explicitly retrieve the defined Roman numerals in descending value order.

**Roman numerals can only represent integers between 1 to 4000**. We can use the following algorithm to convert a Roman numeral to an Arabic number (iterating through symbols in reverse order from *M* to *I*):

LET numeral be the input String representing an Roman Numeral LET symbol be initialy set to RomanNumeral.values()[0] WHILE numeral.length > 0: IF numeral starts with symbol's name: add symbol's value to the result remove the symbol's name from the numeral's beginning ELSE: set symbol to the next symbol

Next, we can implement the algorithm in Java:

public static int romanToArabic(String input) { String romanNumeral = input.toUpperCase(); int result = 0; List<RomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; while ((romanNumeral.length() > 0) && (i < romanNumerals.size())) { RomanNumeral symbol = romanNumerals.get(i); if (romanNumeral.startsWith(symbol.name())) { result += symbol.getValue(); romanNumeral = romanNumeral.substring(symbol.name().length()); } else { i++; } } if (romanNumeral.length() > 0) { throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral"); } return result; }

Finally, we can test the implementation:

@Test public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() { String roman2018 = "MMXVIII"; int result = RomanArabicConverter.romanToArabic(roman2018); assertThat(result).isEqualTo(2018); }

We can use the following algorithm to convert from Arabic to Roman numerals (iterating through symbols in reverse order from *M* to *I*):

LET number be an integer between 1 and 4000 LET symbol be RomanNumeral.values()[0] LET result be an empty String WHILE number > 0: IF symbol's value <= number: append the result with the symbol's name subtract symbol's value from number ELSE: pick the next symbol

Next, we can now implement the algorithm:

public static String arabicToRoman(int number) { if ((number <= 0) || (number > 4000)) { throw new IllegalArgumentException(number + " is not in range (0,4000]"); } List<RomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; StringBuilder sb = new StringBuilder(); while ((number > 0) && (i < romanNumerals.size())) { RomanNumeral currentSymbol = romanNumerals.get(i); if (currentSymbol.getValue() <= number) { sb.append(currentSymbol.name()); number -= currentSymbol.getValue(); } else { i++; } } return sb.toString(); }

Finally, we can test the implementation:

@Test public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() { int arabic1999 = 1999; String result = RomanArabicConverter.arabicToRoman(arabic1999); assertThat(result).isEqualTo("MCMXCIX"); }

In this quick article, we've shown how to convert between Roman and Arabic numerals.

We have used an *enum *to represent the set of Roman numerals and we have created a utility class to perform the conversions.

The complete implementation and all tests can be found over on GitHub.