If `MDCCCXII`

and `MMV`

are Greek to you, you 're not far off. The ancient Romans counted their numbers using letters! The numbers that we use are called Arabic numbers, as the Europeans learnt them from the Arabs, although they were invented in India. The Romans had a very different system of numbering. They didn't have the number `0`

(zero), or negative numbers, or fractions. In fact, in their first numbering system they only had integer numbers between `1`

and `3999`

inclusive. No other numbers were ever needed.

In later centuries, several systems were devised to remedy this. Different symbols were introduced for 5000 and the bigger numbers, but no agreed. The best known system was to put a horizontal line over one of the existing letters, which meant to multiply it by `1,000`

, so `V`

meant `5,000`

and `X`

would be `10,000`

. The custom however fell into disuse even before the empire fell, probably because the same system was sometimes used to indicate the letters were to be interpreted as numbers, or simply because the largest numbers expressed in the Roman system are dates.

Arabic | Roman |
---|---|

1 | I |

5 | V |

10 | X |

50 | L |

100 | C |

500 | D |

1000 | M |

This highly confusing situation has now been solved with this little beauty of a Javascript conversion utility. Simply enter a decimal or Roman number in the appropriate box, and the other box will update as you type!

For an interactive animation, click ‘Down’ or ‘Up’ and the form will start counting.

The conversion takes place in the functions `toroman`

and `toarabic`

. Other parts of the script set a few global variables, and attach the appropriate event handlers to the various form controls.

var tid, f = document.forms.f.elements, vals = { 'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000 }; // original: Dougie Lawson, http://web.ukonline.co.uk/dougie.lawson/ function toroman( num ) { num = parseInt( num, 10); if( num > 0 && num < 6000 ) { var mill = [ '', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM' ], cent = [ '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM' ], tens = [ '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC' ], ones = [ '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' ], m, c, t, r = function(n) { n = (num - (num % n ) ) / n; return n; }; m = r(1000); num = num % 1000; c = r(100); num = num % 100; t = r(10); return mill[m] + cent[c] + tens[t] + ones[ num%10 ]; } else { return 'Numbers from 1 to 5999 only please.'; } } //original: Giles Edkins, 2001 function toarabic( num ) { num = num.toUpperCase().replace( /[^IVXLCDM]/g, '' ).replace( /VV/g, 'X' ).replace( /LL/g, 'C' ).replace( /DD/g, 'M' ); var bits = [], i = 0, j = 0, k, l, n = num.length, last = 9999, rep = 0, sum = 0, valid = 1; for( ; i < n; i++ ) { if( !( bits[j] = vals[ num.charAt(i) ] ) ) { valid = 0; break; } if(j > 0) { k = bits[j]; l = bits[j - 1]; if( k===l * 5 || k===l * 10 ) { bits[--j] = k - l; } } j++; } if( valid ) { for( i = 0; i < j; i++ ) { k = bits[i]; sum += k; if( (last < k) || (rep > 1 && last == k) || (last == k && k != 1 && k != 10 && k != 100 && k != 1000) || last == k * 4 || last == k * 9 || last * 4 == k * 9 || last * 5 == k * 9 ) { valid = 0; break; } rep = (last == k) ? rep + 1 : 0; last = k; } } return valid ? sum : 'Enter a proper Roman number please.'; } function convert( n ) { if( n.search && n.search.substring(1) ) { n = n.search.substring(1); } else { n = f.arabic.value || new Date().getFullYear(); } if( isNaN( +n ) ) { f.roman.value = n; f.arabic.value = toarabic( f.roman.value ); } else { f.arabic.value = n; f.roman.value = toroman( f.arabic.value ); } return false; } function count( n ) { var m = +f.arabic.value + n; if( m<1 ) { m = 5999; } if( m>5999 ) { m = 1; } f.arabic.value = m; f.roman.value = toroman( m ); f.stopc.disabled = false; tid = window.setTimeout( 'count(' + n + ');', 400 ); } function stopcount() { window.clearTimeout( tid ); f.stopc.disabled = true; } function focused() { stopcount(); this.select(); } f.arabic.onfocus = focused; f.roman.onfocus = focused; f.arabic.onkeyup = function( e ) { this.form.elements.roman.value = toroman( this.value ); } f.roman.onkeyup = function( e ) { e = e || window.event || {}; var k = String.fromCharCode( e.keyCode || e.which ).toUpperCase(); if( k>='A' && k<='Z' && !vals[ k ] ) { this.value = this.oldvalue || ''; } else { this.form.elements.arabic.value = toarabic( this.value ); } this.oldvalue = this.value; } window.onunload = stopcount; convert( location );

To offer this conversion tool to others with your values pre-filled, simply offer them a link to `http://4umi.com/web/javascript/convertroman.php?2005`

where the part after the question mark (`?`

) is either the decimal or the Roman number that you would like them to see converted. The script will then find this number while the page is loading in the browser, copy it to the appropriate box and perform the desired conversion.

Need to convert `MCLI`

and `XIV`

into human readable numbers more often than you visit this page? Then a small and elegant stand-alone solution is the Roman Numeral Converter.

- The file: http://www.kaejae-worx.com/~don/programs/rnc11.zip

On Windows systems, right-click the above link, choose Save Target *A*s… and select a location on your disk to copy the `.zip`

file to. Then (run a virusscan and) unzip and doubleclick the resulting `.exe`

file. In case the original is unavailable, a local copy is 4umi.com/web/javascript/convertroman.zip.

A neat little bit of Visual Basic programming, to sort the `M`

's from the `L`

's and `I`

's.