# C++ converting base 10 to Roman numerals

1. Feb 2, 2005

### Math Is Hard

Staff Emeritus
Hi,
I just began working on a little program to convert base 10 number to Roman numerals. I couldn't figure out how to make a loop to count how many Ms, Ds, Cs etc. so I wrote it out the long way for now.
I can see a lot a repetition and an obvious pattern in my divisors, since I am dividing by
103 , (103)/2 , 102 , (102)/2 ,etc.
but I can't figure out a loop that will handle this properly. Any suggestions?
(note: I haven't written the logic for the last piece of it yet which will deal with the order of the numbers, for instance, converting VIIII to IX.)

Thanks for any advice on handling the loop. Here's what I did:

Code (Text):

# include <iostream>

using namespace std;

//converts base 10 to romans

int main()
{
int num;
int quotient;
int M = 0;
int D = 0;
int C = 0;
int L = 0;
int X = 0;
int V = 0;
int I = 0;

cin >> num;

quotient = num/1000;
M = quotient;
num = num % 1000;

quotient = num/500;
D = quotient;
num = num % 500;

quotient = num/100;
C = quotient;
num = num % 100;

quotient = num/50;
L = quotient;
num = num % 50;

quotient = num/10;
X = quotient;
num = num % 10;

quotient = num/5;
V = quotient;
num = num % 5;

I = num;

for (int m = 0; m < M; m++)
cout << "M";
for (int d = 0; d < D; d++)
cout << "D";
for (int c = 0; c < C; c++)
cout << "C";
for (int l = 0; l < L; l++)
cout << "L";
for (int x = 0; x < X; x++)
cout << "X";
for (int v = 0; v < V; v++)
cout << "V";
for (int i = 0; i < I; i++)
cout << "I";

return 0;
}

2. Feb 2, 2005

### Hurkyl

Staff Emeritus
The trick is to make an auxilliary array of the constants you need.

int divisor[] = { 1000, 500, 100, 50, 10, 5, 1 };
char symbol[] = "MDCLXVI";

I'll give you a chance to take it from here.

3. Feb 2, 2005

### Math Is Hard

Staff Emeritus
Hey Hurkyl, thanks for your response.

sorry, I should have mentioned this in my first post: No arrays allowed yet.
Technically we're not supposed to know what an array is yet.
Think there might be another way?

4. Feb 2, 2005

### Hurkyl

Staff Emeritus
Well... you could write a function that contains the replicated logic, and then call the function a few times with the parameters. Or, you could put them into a file, and read them from the file instead of from an array...

5. Feb 2, 2005

### Math Is Hard

Staff Emeritus
ok, I'll think on that. That should make things a little bit nicer (and shorter!). Thanks!

6. Feb 2, 2005

### Bartholomew

You can't have a loop because you have the separate variables M D C L X V I. There is no good way to access the M in the first iteration, the D in the second, etc. You could use 2 arrays, one to store the number of M's, D's, C's, etc. and the other to store the letters 'M,' 'D,' 'C,' etc., and that would let you do a loop. But unless you were specifically asked to use a loop, I don't think you should.

You can tighten the code by not initializing any of the M's, D's, etc. to 0 since they are assigned values later in the code before they are used.

Also, you can write

quotient = num/5;
V = quotient;
num = num % 5;

as

V = num/5;
num %= 5;

getting rid of the quotient variable.

If you do need a loop, it would go something like this (currentDivide set to 1000 to begin with):
for(i = 0; i < 7; i++)
{
(do something with your array of letters here)
if(i % 2 == 0)
currentDivide /= 2;
else
currentDivide /= 5;
}

7. Feb 2, 2005

### Bartholomew

But I think you should focus on the second part of the problem. Your program would convert 499 into CCCCLXXXXVIIII, and there is not an easy way to go from there to the correct answer, ID, so you should convert it to ID as you go rather than afterwards.

Edit: nevermind, ID is not the standard representation for 499

Last edited: Feb 2, 2005
8. Feb 2, 2005

### Integral

Staff Emeritus
Instead of dividing by 1000 do a loop that subtracts 1000, each loop add a M, check to see if you are below 1000, then start subtracting 500. etc. You will need to condsider the logic needed to get the order of the Roman Numeral symbols right.

I did this some years ago in quick basic, Sorry lost the code... Hum... I still have a collection 5.25 floppies I might be lucky and still have it somewhere.

9. Feb 2, 2005

### Bartholomew

No, the way she did it is more concise than that would be.

10. Feb 2, 2005

### Math Is Hard

Staff Emeritus
OK, thanks! I am going to play around with some of those suggestions, but if I get stuck at least I have my long-winded version to use.

11. Feb 2, 2005

### Integral

Staff Emeritus
Surely you jest! We are converting to Roman numerals aren't we?

Can you tell me exactly what the difference between subtraction and division is? Does your CPU know the difference?

12. Feb 2, 2005

### Bartholomew

Well, probably my CPU does know the difference. But I was talking more about shorter source code.

13. Feb 2, 2005

### Integral

Staff Emeritus
Actually your CPU does division by successive subtractions.

I am not sure that the division algorithm is more efficient. Since you will have to do some form of a loop based on the result of the division to create the final answer. This way you do a while loop subtracting the appropriate amount and build the result as you go, you can even throw in the ordering logic. The subtraction saves machine cycles....LOL as if that is a concern for this problem.

I would recommend doing it the way that easiest to code. That comes down to what works for, and makes the most sense to, the programmer.

14. Feb 2, 2005

### Bartholomew

I'm not familiar with the specifics of my computer's innards but I'm willing to bet that it has division instructions which are more efficient than successive subtraction. Long division by hand, for example, is quicker than repeated subtraction by hand.

Personally, I'm used to dividing and using %.

15. Feb 2, 2005

### gnome

I think this involves too many special cases to have "elegant" code. You have to deal separately with thousands, nine-hundreds, five-hundreds, four-hundreds, hundreds, nineties, fifties, forties, tens, nine, five, four and one; Integral's way is best.

16. Feb 2, 2005

### Math Is Hard

Staff Emeritus
I'm trying to work out the rest of the Roman numeral formatting now to put the I before the V or the I before the X. I'm stumped on that so far but I think I'm just burning out now. Maybe if I sleep on it... :zzz: .. sometimes I'll have an idea in the morning.

17. Feb 3, 2005

### gnome

It is interesting. And now it's even more complicated. So which system of "Roman" numerals are you supposed to convert to?

18. Feb 3, 2005

### gnome

"...now to put the I before the V or the I before the X..." or the X before the C (or L) or the C before the M (or D) and so on...

That's why Integral suggested building the string while whittling down the decimal number. Or, if you're not up to strings yet, just print each character or pair of characters in the same loop with the subtraction. In other words, if you have nine-hundred-something, subtract nine hundred, print "CM" and then continue processing the "something".

19. Feb 3, 2005

### Integral

Staff Emeritus
Ya'll got me wondering aobut correct form of Roman numerals, I had a pretty good sense of how it works but was not certian. I found http://www.wilkiecollins.demon.co.uk/roman/front.htm [Broken]

check out the conversion calculator (I scored X/X on the little test!)

Also look at the 1999 question.

according to this page ID is not the best form of 499 it would be CDXCIX

Last edited by a moderator: May 1, 2017
20. Feb 3, 2005

### gnome

Yeah, that's what my program does. And MCMXCIX for 1999.