Roman Numeral Converter

Level:
Level3

Written By TheVBProgramer .

This VB6 program converts an integer in the range of 1 through 3999 to its equivalent in Roman numerals. It also converts a Roman numeral string to its decimal equivalent.

The rules for Roman numerals are as follows:

  • The basic symbols are I (= 1), V (= 5), X (= 10), L (= 50), C (= 100), D (= 500), and M (= 1000).
  • If a letter is immediately followed by one of equal or lesser value, the two numbers are added; thus, XX = 20, XV = 15, VI = 6.
  • If a letter is immediately followed by one of greater value, the first is subtracted from the second; thus IV = 4, XL = 40, CM = 900.
  • A bar over a letter multiplies it by 1000; thus, an X with a bar over it = 10,000. Such numbers will not be addressed by this project.

Examples:

The numbers from 1 to 10 are: I, II, III, IV, V, VI, VII, VIII, IX, X.

XLVII = 47, CXVI = 116, MCXX = 1120, MCMXIV = 1914.

Note that a given symbol appears no more than three times consecutively in a number.  This is why 4 is written as "IV" instead of "IIII", and 40 is written as "XL" instead of "XXXX".

Probably the most challenging part of converting a Roman Numerals number to decimal is not the conversion itself, but rather validating the input. Basic validation would include converting keystroke input to uppercase and allowing only the characters I, V, X, L, C, D, and M to be entered. Beyond that, the following rules should be applied:

  • D, L, or V may each only appear at most one time in the string
  • M, C, X, or I may appear no more that three times consecutively in the string
  • The following pairs of letters are invalid in all cases: IL, IC, ID, IM, XD, XM, VX, VL, VC, VD, VM, LC, LD, LM, DM.
  • Once a letter has been subtracted from, neither it nor its "5 counterpart" may appear again in the string - so neither X nor V can follow IX, neither C nor L may follow XC, and neither M nor D may follow CM.
  • Once a letter has been used as a subtraction modifier, it cannot appear again in the string - so C cannot follow CD or CM, X cannot follow XL or XC, and I cannot follow IV or IX.
  • Once I, X, or C (or their "5-counterparts" V, L, and D) appears in a string, the I, X, or C cannot subsequently be used as subtraction modifiers - so IV or IX cannot follow I or V, XL or XC cannot follow X or L, and CD or CM cannot follow C or D.

Sample runs are shown below.

VB6 screen1

When the user selects "Roman Numerals to Decimal Number" for the conversion type, note that the captions change and the reverse conversion is performed:

VB6 screen2

Example of invalid input:

VB6 screen3

VB6 screen4

 

Download Visual Basic 6 sample source code  

If you enjoyed this post, subscribe for updates (it's free)

Rules etc.

I was about to sound off about your "rules" which were wrong when I scrolled down and read the corrections. Basically, any of the not-5 (or powers of 10 if you prefer) numbers can only appear (once) before the next two values greater than itself. So I can appear before X or V but not L or greater, etc. And only once, so IX is valid IIX isn't, and nor is IXIX. (I am going by what the excel roman() method produces for "classic" style.)
I don't think it is strictly true to say you can't have four of anything - if you look at a clock face, you will often see IIII rather than IV, for reasons of symmetry and asthetics. I'm not sure about XXXX though.
You might also like to ponder on the fact that Roman numerals have their own treatment in unicode, v. 2160 thru 2188. This includes lower and upper case separately, as well as big numbers and archaic ones.

hi guys,,i need help.. hOw to

hi guys,,i need help.. hOw to convert integer into string in vb6..i need a sample code..morE powEr and God bless yOu..

amazing vb programming technics

i enjoy this technical programming techniques, amazing.

I stand corrected

Hello, this is Bruce, the author of this Roman Numerals project. This is one of several tutorials I have on my own site (thevbprogrammer.com), that I share here based on an agreement with the webmaster of this site.

First, thanks to the original poster for pointing out this glitch, and secondly to the others who took the time to think about this and to come up with corrections to the rules. I have reviewed what I originally wrote along with all of your valuable comments here, and from what I can see, the correction to the erroneous rule should be this:

"Once a letter has been used as a subtraction modifier, that letter cannot appear again in the string, unless that letter itself is subtracted from. For example, CDC is not valid (you would be subtracting 100 from 500, then adding it right back) – but CDXC (for 490) is valid. Similarly, XCX is not valid, but XCIX is.
To summarize:
C cannot follow CM or CD except in case of XC.
X cannot follow XC or XL except in the case of IX."

The other rules still stand, although I found they could use some rewording.

I have since updated this project on my site, and corrected the erroneous rule (and reworded some of the other rules) in the corresponding write-up. The updated page is here:
http://www.thevbprogrammer.com/Ch08/08-10-RomanNumerals.htm
On this same page, the corrected code can be downloaded as well (in the second spot that says "Download the solution for this project here." - toward the bottom of the document).

Error in the rules

While the rules outlines seemed pretty helpful there is at least one MAJOR error.

The one rule states:
Once a letter has been used as a subtraction modifier, it cannot appear again in the string - so C cannot follow CD or CM, X cannot follow XL or XC, and I cannot follow IV or IX.

This is erroneous for C, consider the example of 490. 400 is calculated by 500-100, thus CD, 90 is calculated by 100-10, thus XC. In the case of 490, CDXC the C does follow after it had been used in negation, this is perfectly ligit.

You can even test this by running their source code, convert 490 to Roman Numerals & you will see that it appears as CDXC, then try converting that number back again & it will report that error (even try the entry above the block (Enter a Roman Numeral between I and MMMCMXCIX). There is that XC yet again.

Great Point

That is a great point. How would you change the code to fix it? If you figure out a solution let me know. I would love to post it on the site (and give you credit!). Or if you want to write a whole new tutorial that does a better job you can do so and Submit it to this site.

Rule Modification

Well I’ve been at this page all week & didn’t realize anyone had responded bc my cache did not refresh. I’ve never programmed in Visual Basic so I don’t think I would be any help for creating a different version of the program. I’m actually working on a similar project at school but in a different programming language.

I’ve discovered that there are a few more instances that fail under the current VB program, consider XLIX or IXC. The rules that have been outlined I believe are still useable, I think they just need to be extended to include special cases.

For instance, I would simply extend that one rule to include a check where instances of XC is accepted after a CM or CD, instances of IX accepted after a XL or XC.

Also there is an issue with a format like IXC or XCD, which is allowed with this particular version, since it appears to the program like I is subtracting from X and X subtracting from C.

The way I see it, rule (or bullet point) 4 and 5 are similar enough that they could be joined together to form a single rule. I found this method to be more helpful but others may disagree.

The rule I would write for the 4th bullet point would be something like:

After IX neither X, V, I, C, nor L can follow. (M is caught in the previous rule).
After XC neither C, L nor M can follow, nor can X follow except in the case of IX (we don’t want XCM to occur).
After CM neither M nor D can follow, nor can C except in the case of XC.
After IV, I cannot follow. (we don’t have to worry about larger values after this point because of the other rules in place).
After XL, X cannot follow except in the case of IX
After CD, C cannot follow except in the case of XC.

----------------------------------------------------------------
This is the way I implemented this rule in my program:
If IX occurs, check for:
instances of X and return error if found
instances of V and return error if found
instances of I and return error if found
instances of C and return error if found (catch the IXC error)
instances of L and return error if found (same idea, no large value after a smaller one).

If XC occurs check for:
instances of C and return error if found
instances of L and return error if found
instances of X and return error if found EXCEPT in the case of IX
instances of M and return error if found
instances of D and return error if found

If CM occurs check for:
instances of M and return error if found
instances of D and return error if found
instances of C and return error if found except in the case of XC

If IV occurs check for instances of I and return error if found

If XL occurs check for instances of X and return error if found EXCEPT in the case of IX

If CD occurs check for instances of C and return error if found XC.
-----------------------------------
Perhaps there's a better way to say all that, but it made it a lot easier to implement. I notice some sites attempt to create the larger value before the lesser value rule, where XC would be larger than the IX and thus XCIX would be valid, but those sites fail to catch other errors such as XCX, since XC is still greater than X. In practical terms I've found setting out a list of rules similar to those above to be the easiest to implement and modify. The initial rules are good, they maybe just need a little refinement. Its surprising how many websites actually don't have a very good Roman Numeral validation system.

I hope that this has been helpful.

Well said. Thanks for

Well said. Thanks for contributing back these great rules. Maybe I will try to get around to implementing them in some VB6 code at some time. Otherwise if anyone else gets these working please email me or post a comment on here so that we can update the code. Thanks again Steve, your comments have been very helpful. Just out of curiosity what language are you writing your Roman Numeral Converter in?

Converter Program

I've been writing a converter in the wonderful language of Prolog, probably not as popular a language as VB but it loves rules.