BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Algorithms and Data Structures
.NET 1.1+

Convert a Number into Roman Numerals

Roman numerals are an ancient number system but still have uses in the modern world. Roman numerals are used to represent dates, adorn clock faces and for indexing. This article describes an algorithm and C# code to convert a number into Roman numerals.

Roman Numerals System

Although the Roman numerals system is very old, it still does appear in some circumstances. In filmmaking, it is usual to use the Roman equivalent of the year of production for the final copyright notice. In publishing, contents page and index numbering is often presented in this manner.

The Roman system used a series of letters to represent numbers. The key letters were as follows:

LetterValueRoman
Ioneunus
Vfivequique
Xtendecem
Lfiftyquinquaginta
Cone hundredcentum
Dfive hundredquingenti
Mone thousandmille

Combining Numerals

The numerals can be combined to create all of the numbers between one and four thousand using a set of simple rules. The first rule is that the letters can be repeated several times, with the values of each being additive. This means that I is one, II means two and III is three. However, in the modern representations IIII is not correct for four, as we will see in the third rule.

NB: IIII is used on a clock face. Various reasons are given for this including the aesthetics of the numeral and to give some symmetry of the clock.

The second rule states that the larger numerals must be placed to the left of the smaller numerals to continue the additive combination. So VI equals six and MDCLXI is 1,661.

The third rule allows for a small-value numeral to be placed to the left of a larger value. Where this occurs, for example IX, the smaller numeral is subtracted from the larger. This means that IX is nine and IV is four. This rule cannot be used universally, however. The subtracted digit must be at least one tenth of the value of the larger numeral. Accordingly, ninety-nine is not IC but rather XCIX. The XC part represents ninety and the IX adds the nine.

To represent numbers of four thousand or greater, lines are added to each letter. For example, a line above a letter multiplies its value by one thousand. To represent 15,015 the Roman numerals are XVXV.

Finally, there is very little information that suggests that the system originally had a notation for zero. However, the letter N has been used to represent zero in a text from around 725AD. This will be used in the algorithm.

Algorithm Goals

The algorithm converts an integer value into Roman numerals using a recursive process. The resultant value is returned as a string to the calling function. To remove the problems of displaying Roman numerals of four thousand or greater, a restriction to values between zero and 3,999 is enforced. This should be a large enough range for most applications.

The Algorithm and the Code

Preparation

Depending upon how you wish to use this algorithm, you may want to create it in a new class, incorporate it in an existing class or simply hide it behind a form event. To keep the code simple and short, this article assumes you have a class of some kind prepared and are adding a new method to that class. The code simply declares a new public method that accepts the integer to be converted as its only parameter.

To prepare, create or identify the class that you will add the method to, then add the following declaration code:

// Converts an integer value into Roman numerals
public string NumberToRoman(int number)
{
}

NB: If you are creating or adding to a utilities class, you may wish to adjust the declaration to make the method static. If you do, all of the other declarations detailed below must also be marked as static.

Validating the Integer

The number being converted must be within the previously specified range. If a value outside of the range were provided, the resulting string would be incorrect, so a validation rule is incorporated that throws an argument exception. Add the following validation code within the method:

// Validate
if (number < 0 || number > 3999)
    throw new ArgumentException("Value must be in the range 0 - 3,999.");

Checking for Zero

If the parameter passed to the method is zero, the result will always be 'N'. This rule is dealt with separately to the main conversion process for simplicity. The following code, added to the method, checks for a zero value and, if it is found, returns the result immediately:

if (number == 0) return "N";

Setting Up Key Values

The algorithm will work by comparing a series of values to the number being converted. Each item in the series represents a specific Roman numeral letter or a letter pair representing a subtraction. The key numerals will be M (1000), CM (900), D (500), CD (400), C (100), XC (90), L (50), XL (40), X (10), IX (9), V (5), IV (4) and I (1). To hold these values and link the integer to the numeral, we will create two arrays. This could also be achieved with a collection such as a SortedList.

// Set up key numerals and numeral pairs
int[] values = new int[] { 1000, 900, 500, 400, 100,90, 50, 40, 10, 9, 5, 4, 1 };
string[] numerals = new string[]
    { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
4 October 2007