Numeral systems are fascinating!
Presenting values in various numeral systems reveals some hidden aspects of these values and sometimes reveals more about our Human History and knowledge evolution.
Roman is one of these systems. (you may have a look here, here, or here)
A few years ago, I wrote a method to convert decimal numbers into roman. That worked well. The customer wanted a converter for numbering paragraphs. Up to 50 would be largely enough, he said. The developer in my head pushed me up to 9999 (sadly, I abandoned here by lack of time)
A few days ago, I saw someone wearing a T-shirt with 'XCIV' logo. And that reminded me that I never wrote the reverse conversion (from roman to decimal).
That was a good occasion to write this. And as I also have a friend who wants to practice C#, that may be a good exercise.
I found back my old code (to discover it was all to be rewritten!)… and I started working on a new version!
Roman numerals. A brief presentation
As you may know, Roman numerals building blocks are:
Roman
|
Decimal
|
I
|
1
|
V
|
5
|
X
|
10
|
L
|
50
|
C
|
100
|
D
|
500
|
M
|
1000
|
Intermediate values (like in the table below, between 1 and 10) are additions and subtractions of these basic building blocks
Roman
|
Decimal
|
|
I
|
1
|
|
II
|
2
|
1 + 1
|
III
|
3
|
1 + 1 + 1
|
IV
|
4
|
5 – 1
|
V
|
5
|
|
VI
|
6
|
5 + 1
|
VII
|
7
|
5 + 1 + 1
|
VIII
|
8
|
5 + 1 + 1 + 1
|
IX
|
9
|
10 – 1
|
X
|
10
|
|
Going beyond the M (1000) [presentation and entries]
Roman numerals were, at their era, (an evidence) hand written (probably more often engraved on hard stones!).
That surely does not mean the people did not know or need to count beyond the 1000. We better never forget that numbers and mathematics are much older than our own era… and that most of the great advances in this area had been achieved in other older civilizations!.
My problem here is just a presentation question: how can I write roman numbers beyond the M (1000)?
Old traditionalists use quirky figures that do not seem easily writable using a 'keyboard'.
Like here:
Or here:
To make presentation and entries a little easier with our era's keyboards, I decided to combine other units to create building blocks beyond the 1000. Example: To present the 1000 – 9000 sequence, I used 'XM' and 'VXM':
"XM",
|
// 10000
|
"XMXM",
|
// 20000
|
"XMXMXM",
|
// 30000
|
"XMVXM",
|
// 40000
|
"VXM",
|
// 50000
|
"VXMXM",
|
// 60000
|
"VXMXMXM",
|
// 70000
|
"VXMXMXMXM",
|
// 80000
|
"CMXM",
|
// 90000
|
For the sequence 1m – 9m, I used characters that are not in the traditional roman building blocks: The 'U', 'W' and 'Y':
"U",
|
// 1000000
|
"UU",
|
// 2000000
|
"UUU",
|
// 3000000
|
"UW",
|
// 4000000
|
"W",
|
// 5000000
|
"WU",
|
// 6000000
|
"WUU",
|
// 7000000
|
"WUUU",
|
// 8000000
|
"UY",
|
// 9000000
|
Conversion processing units
The conversion manager object (iRomanNumberDictionary in the above figure) stores a list of roman building blocks.
Each building block corresponds to a decimal sequence factor (1, 10, 100, 1000… etc.) and stores the roman elements of this sequence (see the sample tables above). It also stores the roman group level (a vital info as you will see in the code!)
Decimal to roman
Now, to convert a decimal number into its roman presentation, we proceed this way (here, using 28 as an example):
Roman to decimal
Roman to decimal is a bit trickier!
Let us take the reverse conversion of the example above ("XXVIII") for which the conversion result should be 28.
To better understand what goes on in the conversion process, I added a conversion history that explains the steps of each conversion.
Here is the processing history for XXVIII (28):
Another processing history for a greater roman number MMMXCVIII (3098):
You may download the code (WPF) HERE. Have fun extending and enhancing for the better!