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.
When the user
selects "Roman Numerals to Decimal Number" for the conversion type,
note that the captions change and the reverse conversion is performed:
Example of
invalid input:
Download Visual Basic 6 sample source code
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.
Post new comment