# C++ converting base 10 to Roman numerals

by Math Is Hard
Tags: base, converting, numerals, roman
 P: 613 MMDCDXLVIV is correct for 2949. Point is, my algorithm is inherently simpler than yours.
 P: 1,046 2949=MMCMXLIX
Emeritus
PF Gold
P: 4,922
 Quote by Bartholomew Point is, my algorithm is inherently simpler than yours.
uh oh. them sounds like fightin' words..
P: 1,046
 Quote by Bartholomew Point is, my algorithm is inherently simpler than yours.
But I thought now we're going for tricky.
 P: 613 According to that page on roman numerals, IX is incorrect... you can't have a I and then an X, it skips the V, the same reason IMM is incorrect.
P: 1,046
 Quote by Math Is Hard uh oh. them sounds like fightin' words..
See what you started!!
Emeritus
PF Gold
P: 4,922
 Quote by gnome See what you started!!
I know. Mea culpa.
If it's any consolation I think I failed spectacularly on the C++ midterm today. Guess what was on the test - converting to Roman f'ing numerals! I couldn't remember anything. I was like a deer in the headlights I was so scared.
 P: 1,046 I didn't study that page, but I'm sure that 9 is generally written IX and not VIV.
 P: 1,046 On the other hand, it's a lot more fun than studying for an exam on computabilty, complexity, etc. -- which is what I should be doing. I'll check back later to see what Bartholomew comes up with.
 Emeritus Sci Advisor PF Gold P: 16,091 My algorithm is the best. Given an integer, look up its string representation in a table of strings.
 P: 613 Well, as I said, I don't have a c++ compiler. So rather than translate this into C++ and hope I didn't make any syntax errors in doing so, I'll just post it in Java, which I wrote it in. (No user input here since that takes several lines in Java) class RomanNumeral{ public static void main (String argv[]) { int num, i, ii; int cD[] = {1000, 500, 100, 50, 10, 5, 1}; int c[] = new int[7]; String cs = "MMMDDDCCCLLLXXXVVVIII"; num = 2949; for(i=-1;i<6;c[++i]=num/cD[i],num%=cD[i]); for(i=0;i<7;i++) System.out.print(c[i]!=4||i==0?cs.substring(i*3,i*3+c[i]):""+ cs.charAt(i*3)+cs.charAt(i*3-1)); } }
HW Helper
P: 430
 Quote by Bartholomew I'll just post it in Java
Oh no! Now everyone's posting condensed code samples in random languages – this thread is turning into the Obfuscated Roman Numeral Programming Competition...

In Python (this more-or-less does what I outlined earlier (rather inefficiently ); I think it's also a version of Hurkyl's method):
from sys import stdout
r = 'IVXLCDM'
print 'Decimal to Roman numeral conversions'
print 'Enter an integer 1-9999, press return or enter a non-integer to exit'
try:
while True:
if n > 999: stdout.write('M'*(n/1000))
n = str(n % 1000)
for (c1,c5,c10),d in [(r[i:i+3], int(n[-(i/2+1)])) for i in xrange((2*len(n)-2),-1,-2)]:
stdout.write(['', c1, c1*2, c1*3, c1+c5, c5, c5+c1, c5+c1*2, c5+c1*3, c1+c10][d])
stdout.write('\n')
except ValueError:
print 'Bye!'
 Quote by Batholomew According to that page on roman numerals, IX is incorrect... you can't have a I and then an X, it skips the V, the same reason IMM is incorrect.
From the page linked by Integral:
 The subtracted number must be no less than a tenth of the value of the number it is subtracted from. So an X can be placed to the left of a C or an L but not to the left of an M or a D.
In other words, 90 = XC not LXL, and thus 9 = IX not VIV. Just look at the page of conversions at Integral's link.
P: 1,046
You (Bartholomew) have disappointed me.

It's a few characters shorter than mine (ignoring the user chit-chat), but it's still wrong. Yes, your algorithm is simpler, but only because the language that it recognizes is simpler and as a result it fails to handle 9, 90 and 900 correctly.

Why did you think that 9 = VIV and 90 is LCL?

The Wolfram page that MathIsHard posted
http://mathworld.wolfram.com/RomanNumerals.html
clearly indicates that 9=IX and and 90=XC.

If you look at page "9" (roman-numbered) of the preface of any textbook, or the production date of any 20th century movie you'll see ix and MCM....

 Quote by Bartholomew According to that page on roman numerals, IX is incorrect... you can't have a I and then an X, it skips the V, the same reason IMM is incorrect.
What page were you referring to?
 P: 613 If you don't have a Java SDE, here's a _tentative_ translation into C++. Probably this doesn't work, but hopefully you'll be able to correct the error if that's the case. (it won't be a logic error, it does work in Java) I also refined the code slightly while translating, to shave off an additional few characters and further complicate that beautiful cout of mine . #include int main(){ int num, i; int cD[] = {1000, 500, 100, 50, 10, 5, 1}; int c[7]; string cs = "IIIVVVXXXLLLCCCDDDMMM"; cin >> num; for(i=-1;i<6;c[++i]=num/cD[i],num%=cD[i]); for(i=6;i>-1;i--) cout<<(c[6-i]!=4||i==6?cs.substr(i*3,c[6-i]):cs.substr(i*3+2,2)); return 0; }
 P: 613 Oh, I didn't see you had posted--took me a while to do that translation. 1 moment. Edit: Okay, you raise a valid point. I will think about how best to modify my method to do 9's, 90s, and 900s correctly. It will still be very short though.
 P: n/a Alright, lemme have a shot at this: #include #include using namespace std; int main(int argc, char **argv) { int *input = new int(); int *rom = new int[7]; int *steps = new int[6]; char *map = new char[7]; *map = 'M'; *(map+1)='D'; *(map+2)='C'; *(map+3)='L'; *(map+4)='X'; *(map+5)='V'; *(map+6)='I'; printf("Please enter the number that must be converted: "); scanf("%i", input); *rom = *input / 1000; *(rom + 1) = (*steps = *input % 1000) / 500; *(rom + 2) = (*(steps+1) = *steps % 500) / 100; *(rom + 3) = (*(steps+2) = *(steps+1) % 100) / 50; *(rom + 4) = (*(steps+3) = *(steps+2) % 50) / 10; *(rom + 5) = (*(steps+4) = *(steps+3) % 10) / 5; *(rom + 6) = (*(steps+4) % 5); printf("Here is your number in Roman numerals: "); for (register int i = 0; i < 6; i++) { for (register int k = 0; k < *(rom + i); k++) printf("%c", *(map + i)); }; switch(*(rom+6)) { case 1: printf("%s", "I"); break; case 2: printf("%s", "II"); break; case 3: printf("%s", "III"); break; case 4: printf("%s", "IV"); break; default: break; }; return 0; } Please compile Multi-threaded! PS: Don't be hatin' on the printf!!!
 P: 1,046 Interesting, but not correct: Please enter the number that must be converted: 1999 Here is your number in Roman numerals: MDCCCCLXXXXVIV 3 errors: DCCCC for 900, LXXXX for 90, VIV for 9 Edit: What's the "multithreaded" comment about?
 P: n/a Ah crap, didn't notice that. Awesome beta testing on your part. I meant, if your compiler supports it (I think all compilers nowadays do), like gcc 3.4.x, compile it for Multi-threaded mode (to support Intel Hyper-Threading!) and notice the performance difference. I believe the code is significantly faster if it runs multithreaded. Btw, I found this rather succint piece of code (I'm quite sure it works) here . I feel a JScript to C/C++ conversion is in order.

 Related Discussions Engineering, Comp Sci, & Technology Homework 2 History & Humanities 28 Set Theory, Logic, Probability, Statistics 15 Social Sciences 0 General Math 1