-2

How can I translate or process a roman number to a decimal number in words and vice versa? I want to do this in C. The idea is to get the number or the letters and process it.

Here is an example:

MDXXIII = One thousand five hundred and twenty-three
One thousand five hundred and twenty-one = MDXXI
fullmoon
  • 25
  • 5
  • This is still unclear, do you want to change the roman numerals to decimals **numbers** or **decimal number as word strings**? – Krish Munot Aug 21 '16 at 03:34
  • 2
    See [Trouble implementing a recursive call in C](http://stackoverflow.com/questions/28219838/trouble-implementing-a-recursive-call-in-c/) which is, despite its title, about converting a number in Roman numerals to decimal/binary. Recursion is not necessary; iteration is fine. ("To iterate is human; to recurse, divine", but the Romans were human, not divine.) – Jonathan Leffler Aug 21 '16 at 06:27
  • Note that converting an integer into words is a separate problem from converting an integer to roman numerals; the converse is also true. The conversion from roman numerals to integer requires error checking in a way that the formatting does not. The same applies (in spades ♠︎, redoubled) to converting words into a integer. You need 4 separate converters, therefore. – Jonathan Leffler Aug 21 '16 at 14:28
  • This topic has been [covered before](http://stackoverflow.com/questions/9073150/converting-roman-numerals-to-decimal) although Java was used there. – 500 - Internal Server Error Aug 22 '16 at 01:10

2 Answers2

2

From decimal to roman is quite simple; the other way around is a bit more tricky.

There are several sets of rules for roman numerals; let's take the most common one:

  • the signs for the multiples of five and ten are
    • I one
    • V five
    • X ten
    • L fifty
    • C one hundred
    • D five hundred
    • M one thousand
  • values in between can be done by concatenation of multiples of the same character
    • II two
    • III three
    • XX twenty
    • XXX thirty
  • values in between can be done by concatenation of multiples of different characters
    • VI six
    • IV four
    • XI eleven
    • DI fifty one
    • CX one hundred and ten
    • XC ninety
  • some combinations are forbidden, better: only the following combinations are allowed
    • ab if a >= b (e.g.: II, VI)
    • ba if 5b = a or 10b = a (e.g.: IV, XD, IX, XC)
  • exceptions:
    • sometimes the maximal number of concatenated symbols of the same value is three (e.g.: III and IV, XXX and XD) or four (e.g.: IIII instead of IV and XXXX instead of XD) but never more or less.

Hint: the conversion of one base to another base is best done from the smallest to the largest part of the number.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
1

A simple way to do this is by reading the entire roman number string and then processing the strings from the back.

Eg: XIV you start with V, = 5 move back 1, now it's I, I is less than V so now subtract off 1, which is 4. Then you move back to X, and now X is greater than I, so add 10 to the earlier value (which was 4), which then becomes 4+10 = 14.

Step 1: Start
Step 2: read the roman numerical as string
Step 3: find length of the roman numerical
Step 4: for each character in the string

 1. if(char = I) then decimal = 1
 2. if(char = V) then decimal = 5    
 3. if(char = X) then decimal = 10  
 4. if(char = L) then decimal = 50  
 5. if(char = C) then decimal = 100  
 6. if(char = D) then decimal = 500  
 7. if(char = M) then decimal = 1000  
 8. otherwise invalid character

Step 5: repeat step 4 until the length of the string
Step 6: k = char[length - 1]
Step 7: for each character of decimal string

  1. if(decimal[i] > decimal[i - 1]) then k = k - decimal[i - 1]

  2. else if(decimal[i] = decimal[i - 1 or decimal[i] < decimal[i - 1) then k = k + decimall[i - 1]

Step 8: repeat step 7 until the length of decimal string
Step 9: print decimal value
Step 10: Stop

VIVEK-MDU
  • 2,483
  • 3
  • 36
  • 63
Krish Munot
  • 1,093
  • 2
  • 18
  • 29
  • 2
    This code does not compile. That makes it tricky to validate that it works properly — I'm suspicious of the algorithm described as it doesn't match the one I use. I tried to fix the code, but my fixed version doesn't convert 'ix' (or 'IX') — I'd like to know whether your fixed version does. I also got the result -9 from converting 'XI'; again, I'm willing to accept that I didn't guess the correct fix, but it's crucial that you provide working code. (These aren't even the torture-tests I had in mind — they're basic counting, except I started with 9 instead of 1. Actually, 'I' causes trouble.) – Jonathan Leffler Aug 21 '16 at 06:11
  • @JonathanLeffler: Thanks for checking it, I have updated my answer and added a generic algorithm instead. – Krish Munot Aug 21 '16 at 08:19
  • 1
    I've removed my down-vote, but I'm not yet convinced by the algorithm (but neither have I yet worked out where it is wrong). My suspicion is that it doesn't do sufficient validation (so it might interpret IXMMCLDIIX or similar nonsense). – Jonathan Leffler Aug 21 '16 at 16:34