# Building a Visual Basic Roman Numeral Converter

## Introduction

A popular question on developer forums is how to create a Roman Numeral converter. It may seem to be a relatively easy task, but looks are deceiving, indeed. Today, I will show you a few different ways to create a decent Roman Numeral converter with Visual Basic.

## First, Some History

A Roman Numeral is a number that is written in the way that the ancient Romans used to write numbers. This numeric system stayed the way of writing numbers in Europe until the Middle Ages. The Roman numerical system is composed of seven Latin letters which include: I (unus): one; V (quinque): five; X (decem): ten; L (quinquaginta): fifty; C (centum): one hundred; D (quingenti): five hundred; and M (mille): one thousand. By combining symbols, a Roman number is formed. There is no symbol for a zero, so there is also no need for zeros to keep place for other numbers. For example: A number such as 203 is written as CCIII.

If two letters are next to each other, each letter is worth powers of ten and the second letter is worth ten times the first. The ultimate value of this letter-group, or number, equals the second letter's value subtracted by the first letter. This means then that IX equals nine, XC is ninety, and CM becomes nine hundred.

The Roman Numeral system is additive; this means that the numbers are simply added. For example, the number 'IV' means four. Talking about the Roman number four, this number is written like that for the simple reason that four or more symbols that look the same aren't allowed to be written out. This means that you cannot have a number written as IIII—which ordinarily would mean four—but written as IV instead.

Enough history? Okay, let me move on. Let's create a project that can convert Roman Numerals to ordinary numbers.

Create a new Visual Basic Windows Forms project and add one button to the form. Add a separate class. Feel free to use your own names, but remember that my names might be different than yours.

Let me pause here and explain the methodology first.

Man, I love patterns! If you look closely, you will see the same pattern being repeated depending on what the value of the number is. Before I get too far ahead of myself, look at the following:

 1 I 2 II 3 III 4 IV 5 V 6 VI 7 VII 8 VIII 9 IX 10 X 10 X 20 XX 30 XXX 40 XL 50 L 60 LX 70 LXX 80 LXXX 90 XC 100 C 100 C 200 CC 300 CCC 400 CD 500 D 600 DC 700 DCC 800 DCCC 900 CM 1000 M

Every sequence starts with a unique symbol as the first in the sequence, so that means 1 = I, 10 = X, 100 = C. The second in the sequence has two of the same symbol, and the third in the numeric sequence has three. Then, with the fourth item, it shows the first number in the current sequence, plus the next unique symbol. The fifth shows the unique symbol for 5, 50, 500, and so on. Six through eight follow the same sequence as one to three. At nine, there is again a change as well as 10.

Seeing this pattern allows you to better think of a solution. Always look long and hard at a situation; you will find answers…

Now, to put this newfound knowledge of this pattern as well as understanding that we only have seven unique symbols to work with, is quite easy, but it is a lot of work.

## Let's Add the First Class

This class is ultimately responsible for the input of ordinary numbers and the output of Roman numbers.

```Public Class InputOutput

Private intIn As Integer
Private strOut As String

Public Sub New(intInput As Integer)

Me.intIn = intInput

End Sub

Public Property Input() As Integer

Get

Return intIn

End Get

Set(value As Integer)

intIn = value

End Set

End Property

Public Property Output() As String

Get

Return strOut

End Get

Set(value As String)

strOut = value

End Set

End Property

End Class

Public MustInherit Class RomanExpression

Public MustOverride Sub Interpret(value As InputOutput)

End Class
```

Now, we need a class to format the output of Roman numbers so that it forms the correct ultimate number. Add this class now:

```Public Class ParseDecimalToRoman

Inherits RomanExpression

Private AllExpressions As New List(Of RomanExpression)() _
From { _
New TenThousands(), _
New Thousands(), _
New Hundreds(), _
New Tens(), _
New Ones() _
}

Public Overrides Sub Interpret(value As InputOutput)

For Each reExp As RomanExpression In AllExpressions

reExp.Interpret(value)

Next

End Sub

End Class
```

Interpret outputs the information with the help of the InputOutput class. The List that was created contains classes that will make use of the same pattern I have mentioned earlier, as you will see now.

Add a class for multiples of One:

```Class Ones

Inherits Terminals

Public Overrides Function OneStrings() As String

Return "I"

End Function

Public Overrides Function FourStrings() As String

Return "IV"

End Function

Public Overrides Function FiveStrings() As String

Return "V"

End Function

Public Overrides Function NineStrings() As String

Return "IX"

End Function

Public Overrides Function Multiply() As Integer

Return 1

End Function

End Class
```

This is very, extremely basic. Object-oriented programming 101. All the properties simply output the necessary string when a change should occur. I will explain the Terminals (which this class inherits from) class a bit later. Add the other classes:

## Tens

```Class Tens

Inherits Terminals

Public Overrides Function OneStrings() As String

Return "X"

End Function

Public Overrides Function FourStrings() As String

Return "XL"

End Function

Public Overrides Function FiveStrings() As String

Return "L"

End Function

Public Overrides Function NineStrings() As String

Return "XC"

End Function

Public Overrides Function Multiply() As Integer

Return 10

End Function

End Class
```

## Hundreds

```Class Hundreds

Inherits Terminals

Public Overrides Function OneStrings() As String

Return "C"

End Function

Public Overrides Function FourStrings() As String

Return "CD"

End Function

Public Overrides Function FiveStrings() As String

Return "D"

End Function

Public Overrides Function NineStrings() As String

Return "CM"

End Function

Public Overrides Function Multiply() As Integer

Return 100

End Function

End Class
```

## Thousands

```Class Thousands

Inherits Terminals

Public Overrides Function OneStrings() As String

Return "M"

End Function

Public Overrides Function FourStrings() As String

Return "MV"

End Function

Public Overrides Function FiveStrings() As String

Return "V"

End Function

Public Overrides Function NineStrings() As String

Return "MX"

End Function

Public Overrides Function Multiply() As Integer

Return 1000

End Function

End Class
```

## Ten Thousands

```Class TenThousands

Inherits Terminals

Public Overrides Function OneStrings() As String

Return "X"

End Function

Public Overrides Function FourStrings() As String

Return "XL"

End Function

Public Overrides Function FiveStrings() As String

Return "L"

End Function

Public Overrides Function NineStrings() As String

Return "XC"

End Function

Public Overrides Function Multiply() As Integer

Return 10000

End Function

End Class
```

I'll stop here, but the same pattern applies to hundred thousands and millions.

## Putting It All Together

```Public MustInherit Class Terminals

Inherits RomanExpression

Public Overrides Sub Interpret(value As InputOutput)

While value.Input - 9 * Multiply() >= 0

value.Output += NineStrings()

value.Input -= 9 * Multiply()

End While

While value.Input - 5 * Multiply() >= 0

value.Output += FiveStrings()

value.Input -= 5 * Multiply()

End While

While value.Input - 4 * Multiply() >= 0

value.Output += FourStrings()

value.Input -= 4 * Multiply()

End While

While value.Input - Multiply() >= 0

value.Output += OneStrings()

value.Input -= Multiply()

End While

End Sub

Public MustOverride Function OneStrings() As String
Public MustOverride Function FourStrings() As String
Public MustOverride Function FiveStrings() As String
Public MustOverride Function NineStrings() As String
Public MustOverride Function Multiply() As Integer
End Class
```

This is where all the magic happens. It simply determines if the current value minus one of our pattern values multiplied by one, ten, hundred, thousand, and ten thousand. If it is, it will add the correct Roman number to the end of the string.

Add the following code behind the button you have added to Form 1 earlier:

```Public Class Form1

Private Sub Button3_Click(sender As Object, e As EventArgs) _
Handles Button3.Click

For i As Integer = 1 To 9999

Dim io As New InputOutput(i)

Dim pdrParse = New ParseDecimalToRoman()

pdrParse.Interpret(io)

Console.WriteLine("{0}" & vbTab & "{1}", i, io.Output)

Next

End Sub

End Class
```

I want to show the Roman Numbers up to 9999 into the Output window.

## Conclusion

It is amazing how something this—should I say—trivial can end up having so much logic and work involved. Don't you just love programming?

#### Hannes DuPreez

Hannes du Preez is a self-taught developer who started learning to program in the days of QBasic. He has written several articles over the years detailing his programming quests and adventures. .NET is his second love, just after his wife and kid. He has always been an avid supporter of .NET since the beginning and is an expert in VB and C#. He was given the Microsoft Most Valuable Professional Award for .NET (2008–2017). He has worked as a moderator and an article reviewer on online forums and currently works as a C# developer and writes articles for CodeGuru.com, Developer.com, DevX.com, and the Database journal.
His first book Visual Studio 2019 In Depth is currently on sale on Amazon and Bpb Publications.

You could reach him at: ojdupreez1978[at]gmail[dot]com

## Most Popular Programming Stories

• There have been no articles posted today.
• There have been no articles posted this week.