Skip to content

How to Convert Roman Numerals to Decimal in Batch Script

Learn how to create a Batch script that converts Roman numerals (like MCMXCIV) to decimal numbers (1994) using a character-by-character parsing strategy with subtraction rules.

Roman numerals (I, V, X, L, C, D, M) are still widely used in formal documents, clock faces, book chapters, and legal numbering. Converting a Roman numeral string like MCMXCIV into its decimal equivalent (1994) requires a specific parsing rule: if a smaller value appears before a larger value, it is subtracted rather than added (e.g., IV = 4, not 6).

In this guide, we will demonstrate how to parse and convert Roman numerals to decimal using a character-by-character scan.

The Strategy: The Look-Ahead Rule

  1. Map each Roman character to its value (I=1, V=5, X=10, etc.).
  2. Scan the string from left to right.
  3. If the current value is less than the next value, subtract it (e.g., IV means $5 - 1 = 4$).
  4. Otherwise, add it.

Implementation Script

@echo off
setlocal enabledelayedexpansion

set /p "roman=Enter Roman numeral: "

:: Normalize to uppercase (Batch variables are case-insensitive, but this helps display)
set "input=!roman!"
for %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    set "input=!input:%%A=%%A!"
)

:: 1. Define Value Map
set "V_I=1"
set "V_V=5"
set "V_X=10"
set "V_L=50"
set "V_C=100"
set "V_D=500"
set "V_M=1000"

:: 2. Initialize
set /a total=0
set /a idx=0

:: Get the length
set /a len=0
set "tmp=!input!"
:len_loop
if defined tmp (
    set "tmp=!tmp:~1!"
    set /a "len+=1"
    goto :len_loop
)

:: 3. The Parsing Loop
:parse_loop
if !idx! GEQ !len! goto :show_result

:: Resolve current character and its value using for-loop resolution
for %%I in (!idx!) do set "ch=!input:~%%I,1!"
for %%C in (!ch!) do set "currVal=!V_%%C!"

:: Basic validation
if "!currVal!"=="" (
    echo [ERROR] Invalid Roman numeral character: "!ch!"
    pause & exit /b 1
)

:: Look ahead to next character for subtraction logic (e.g. IV)
set /a "nextIdx=idx+1"
set "nextVal=0"
if !nextIdx! LSS !len! (
    for %%I in (!nextIdx!) do set "nch=!input:~%%I,1!"
    for %%C in (!nch!) do set "nextVal=!V_%%C!"
)

:: Apply Roman subtraction rules
if !currVal! LSS !nextVal! (
    set /a total-=currVal
) else (
    set /a total+=currVal
)

set /a "idx+=1"
goto :parse_loop

:show_result
echo.
echo ==========================================
echo ROMAN:   !input!
echo DECIMAL: !total!
echo ==========================================
pause

Why Convert Roman Numerals?

  1. Document Parsing: If you scan through a legal document's table of contents (I, II, III, IV), you might need to convert those chapter numbers to integers for indexing or sorting.
  2. Historical Data: Dates on old manuscripts or government cornerstones are often in Roman numerals. Converting them allows for mathematical date comparison.
  3. Educational Tools: Building a Roman-to-Decimal converter is a great way to demonstrate lookup tables and conditional logic in Batch.

Important Considerations

  1. Case Sensitivity: Batch variables are case-insensitive, but the lookup keys (V_I, V_V, etc.) assume uppercase Roman characters. This guide normalizes input to uppercase before parsing.
  2. Invalid Input: This script does not fully validate that the input is a properly formed Roman numeral. For example, IIII will be accepted (yielding 4), even though the conventional form is IV.
  3. Maximum Value: The largest standard Roman numeral is MMMCMXCIX (3999). Values above this require a non-standard bar notation.

Conclusion

Converting Roman numerals to decimal numbers is a rewarding exercise in conditional logic and lookup-table design. By implementing the "Look-Ahead Subtraction" rule, you build a parser that can translate an ancient numbering system into modern integers. This technique demonstrates the power of Batch variable mapping and conditional arithmetic, providing a foundation for building text parsers and format converters of any complexity.

Navigation