Roman Numeral Converter

Convert a number to a Roman numeral or a numeral back to a number, with strict standard-form validation and overline notation above 3,999.

๐ŸŒ Espaรฑol

๐Ÿ”’ Private by design: your text is processed locally in your browser and never uploaded to any server.

Thirteen pairs, and one direction of travel

Roman numerals reduce to a table of thirteen value and symbol pairs, applied greedily from the largest down. A thousand is M, nine hundred is CM, five hundred is D, four hundred is CD, and so on down to a bare I.

That table is the whole encoder. Take the number, repeatedly subtract the largest pair that fits, and append its symbol. Decoding walks the string instead, adding each symbolโ€™s value unless it is smaller than the one after it, in which case it is subtracted.

The table itself was not written from memory and trusted. It was checked by encoding every integer from zero to 3,999 and decoding each result back, confirming both that every value round-trips and that a list of deliberately malformed strings is rejected.

Converting in either direction

  1. Paste your number or numeral into the box. The action button stays disabled while it is empty.
  2. Optionally tick the current year checkbox, which converts this year and ignores whatever you typed.
  3. Click Roman Numeral Converter.
  4. Read the report. It restates what you entered, gives the conversion, and prints a short summary of the rules underneath.
  5. Click Copy to clipboard to take the result.
  6. Process another clears both boxes.

There is no direction selector because there does not need to be one. Digits mean you want a numeral; numeral letters mean you want a number. Lower case letters are accepted and treated as their capitals.

Strict, and here is why

Historical Roman numerals were never standardised in the way modern usage implies. Additive forms like IIII appear on inscriptions and on almost every analogue clock face. Various subtractive shortcuts turn up that no modern reference allows.

This converter accepts only the modern standard form and refuses everything else with a specific explanation. That is a real decision with a real cost, since it will reject a numeral somebody genuinely wrote, and it is the more useful default for two reasons.

The first is that a lenient parser cannot tell you when your input is wrong. If IIII, IIIII and VIIII all decode happily, the tool has no way to flag the one you mistyped. The second is that conversion is usually a checking exercise, and a checker that accepts anything checks nothing.

The rules are stated in the report itself rather than only here, so a rejection comes with the criteria attached.

Above 3,999, the bar goes on

Standard subtractive notation runs out at 3,999. The thousands position tops out at three Ms, and a fourth M is not allowed.

The classical answer is the vinculum, a bar drawn over a group of numerals to multiply its value by a thousand. So numbers from 4,000 upward are split: the thousands part is encoded as an ordinary numeral and overlined, and the remainder under a thousand follows it plainly. That puts the ceiling at 3,999,999, which is the largest value a single bar reaches.

Plain text cannot express a bar spanning several characters, so each letter of the overlined group carries its own combining overline mark. In most fonts those marks join into one continuous line, which is exactly the intended appearance. In a few they do not, and the letters remain correct while the bar looks broken.

Decoding accepts the same notation and enforces its shape: the overlined characters must form one contiguous run at the start, and the plain remainder that follows must not contain an M, since every full thousand is already accounted for by the overlined group.

Errors that reach you

There is a detail here worth knowing about, because it explains why the output looks the way it does.

The shared layout around this tool replaces any error a tool throws with one fixed generic sentence. That would swallow every message this converter produces, which are the most useful thing it has to say: which letter is not valid, why a particular repetition is not standard form, what value an out-of-range numeral came to.

So nothing is thrown. Every failure is folded into an error section of the report instead, where it survives intact. If your numeral is refused, the report tells you specifically what was wrong with it.

For number bases rather than numerals, Base Converter handles binary, octal, decimal and hexadecimal. For spelling a number out in words rather than symbols, Number to Words is the direct equivalent.

Unit Converter covers physical quantities across six categories, and Timestamp Converter handles dates and epoch values, which is the other place people meet a number written in an unfamiliar form. The rest is on the text tools hub.

See it in action

Screenshot of the Roman Numeral Converter tool with the sample input โ€œ2026โ€, Use current year instead of the text below (you still have to type something in the box to enable the button, see FAQ) set to off
Roman Numeral Converter mid-process: the sample input โ€œ2026โ€, Use current year instead of the text below (you still have to type something in the box to enable the button, see FAQ) set to off.
Screenshot of the Roman Numeral Converter result screen showing the generated output โ€œ=== INPUT === 2026 (interpreted as a number) ===โ€ฆโ€
The finished result: the generated output โ€œ=== INPUT === 2026 (interpreted as a number) ===โ€ฆโ€. The download link is a local blob URL โ€” the file never leaves your device.

Frequently asked questions

Do I have to say which direction I want?

No, it works it out. A plain string of digits is a number and a string of the seven numeral letters is a numeral, and the two character sets never overlap, so the direction is unambiguous without asking. Anything that is neither is reported as unrecognised rather than guessed at.

Why is four written as IV rather than IIII?

Because the standard subtractive form is what this accepts, and IIII is rejected with an explanation rather than quietly converted. Clock faces famously use IIII, and various historical inscriptions use additive forms freely, but there is one modern standard and being strict about it is more useful than being permissive. A tool that accepts anything cannot tell you when your input is wrong.

What exactly counts as standard form?

M, C, X and I may repeat up to three times in a row, and D, L and V never repeat at all. Only six subtractive pairs are allowed, being the nine hundred, four hundred, ninety, forty, nine and four combinations. Symbols are otherwise written largest first and added. Anything else, including four Ms in a row or a doubled V, is refused.

How are numbers above 3,999 written?

With the classical vinculum, a bar over a group of numerals that multiplies its value by a thousand. The thousands part is encoded as an ordinary numeral and then overlined, with the remainder written plainly after it. The ceiling is 3,999,999, which is the largest value that convention reaches with a single bar.

The overline looks broken in some places. Why?

Because plain text has no way to start and stop an overline, so each letter carries its own combining overline character. Most fonts draw those marks as one continuous bar across adjacent letters, which is what you want. Some renderers space them out or fail to draw them at all, in which case the letters are still correct and the bar is missing.

Why is there no zero?

Because the system has no symbol for it and never did. Roman numerals are an additive tally rather than a positional system, so there is nothing for a placeholder digit to do. The supported range starts at 1, and asking for 0 or a negative number returns an explanation rather than an empty string.

Why does the current year option still need me to type something?

Because the action button is disabled while the text box is empty, and that behaviour belongs to the shared layout rather than to this tool. Typing any single character satisfies it, and the character is then ignored in favour of the year. The report says explicitly that your text was ignored, so the output is never ambiguous about what was converted.

Related tools