Roman Numerals ↔ IntegerLoading saved progress…

Roman Numerals ↔ Integer

Roman numerals build numbers from seven letters — I (1), V (5), X (10), L (50), C (100), D (500), M (1000) — written largest-first and mostly added together, so XVI is 10 + 5 + 1 = 16. The twist is subtractive notation: a smaller symbol placed before a larger one is subtracted, which is why 4 is IV (not IIII) and 9 is IX. There are exactly six such pairs — IV, IX, XL, XC, CD, CM. You will convert both directions, packaged on one object as romanInteger = { toRoman, fromRoman }. See Roman numerals for background.

Signature

romanInteger.toRoman(num)    // integer (1–3999) -> Roman numeral string
romanInteger.fromRoman(str)  // Roman numeral string -> integer

fromRoman is the exact inverse of toRoman: fromRoman(toRoman(n)) returns n.

Examples

romanInteger.toRoman(4);      // 'IV'
romanInteger.toRoman(58);     // 'LVIII'   (50 + 5 + 1 + 1 + 1)
romanInteger.toRoman(1994);   // 'MCMXCIV' (1000 + 900 + 90 + 4)
romanInteger.toRoman(3999);   // 'MMMCMXCIX'

romanInteger.fromRoman('IX');       // 9
romanInteger.fromRoman('LVIII');    // 58
romanInteger.fromRoman('MCMXCIV');  // 1994

Notes

  • The seven symbolsI=1, V=5, X=10, L=50, C=100, D=500, M=1000.
  • Six subtractive pairsIV=4, IX=9, XL=40, XC=90, CD=400, CM=900. A smaller symbol before a larger one is subtracted; everywhere else symbols are added.
  • Range — standard numerals cover 1 to 3999. There is no zero and no standard notation above 3999 (that needs the vinculum), so you can assume the input stays in range.
  • Well-formed inputfromRoman may assume its argument is a valid, canonical Roman numeral; you do not need to reject malformed strings.
  • Round-tripfromRoman(toRoman(n)) must equal n for every n in 1..3999. Build both functions yourself; no libraries.

FAQ

Why put the subtractive pairs like CM and IV in the value table?
Baking the six subtractive combinations (CM, CD, XC, XL, IX, IV) into the ordered value/symbol table lets toRoman stay a single greedy loop: at every step it takes the largest value that fits and subtracts it. Without those rows you would emit DCCCC for 900 and then have to patch it into CM with fragile string replacements.
How does fromRoman know when to subtract?
It compares each symbol with the one to its right. Roman numerals are written largest-first, so if a symbol is smaller than the next one it must be a subtractive prefix — the I in IV or the X in XC — and its value is subtracted instead of added. Every other symbol is added.
What range of numbers does this handle?
Standard Roman numerals cover 1 to 3999. There is no symbol for zero and no standard way to write numbers above 3999 without the vinculum (an overbar meaning times a thousand), so both are out of scope here.
Loading editor…