Roman Numeral to Decimal Conversion

thomas-bormans-JsTmUnHdVYQ-unsplash

Introduction

This page details the steps to convert a Roman numeral to a decimal number. MATLAB and C++ code is provided.

The Algorithm

The steps for converting a Roman numeral to a decimal number are very easy, and are as follows:

  1. Group the Roman numerals into thousands, hundreds, tens, and ones (use the table below to identify the Roman numeral groupings).
    • MMMDCCCLXXXVIII can be grouped into the following categories: MMM, DCCC, LXXX, VIII.
  2. Convert each term of the grouped Roman numerals to decimal numbers:
    • MMM = 3000
    • DCCC = 800
    • LXXX = 80
    • VIII = 8
  3. Add the values of the thousands, hundreds, tens, and ones.
    • The example above yields the decimal number of : 3000+800+80+8 = 3,888.
ThousandsHundredsTensOnes
MMM = 3000CM = 900XC = 90IX = 9
MM = 2000DCCC = 800LXXX = 80VIII = 8
M = 1000DCC = 700LXX = 70VII = 7
DC = 600LX = 60VI = 6
D = 500L = 50V = 5
CD = 400XL = 40IV = 4
CCC = 300XXX = 30III = 3
CC = 200XX = 20II = 2
C = 100X = 10I = 1

The MATLAB Code

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Author   : David Marcus, PE
% Date     : 02 FEB 2020
% Rev      : 1 - Initial Release
%%%%%%%%%%%%%%% roman2decimal %%%%%%%%%%%%%%%
%
%%%%% Inputs %%%%%
%
%%% roman: Roman numeral string to convert (number between 1 and 3999)
%
%%%%% Outputs %%%%%
%
%%% decimal: Number converted from Roman numerals

function decimal = roman2decimal(roman)

%%% Obtain input from user

if nargin < 1
    roman = inputdlg('Enter Roman Numeral to Convert',...
        'Roman Numeral to Decimal Converter');
    roman_num_str = roman{1};
else
    roman_num_str = roman;
end

%%% Define Roman Numerals in Decimal Form

M = 1000;
D = 500;
C = 100;
L = 50;
X = 10;
V = 5;
I = 1;

thousands_value = 0;
hundreds_value = 0;
tens_value = 0;
ones_value = 0;

next_index = 1;
numerals_used = 0;

% Check thousands
if (length(roman_num_str) >= 3) && (strcmp(roman_num_str(1:3),'MMM') == 1)
    thousands_value = M+M+M;
    next_index = 4;
    numerals_used = 3;
elseif (length(roman_num_str) >= 2) && (strcmp(roman_num_str(1:2),'MM') == 1)
    thousands_value = M+M;
    next_index = 3;
    numerals_used = 2;
elseif (length(roman_num_str) >= 1) && (strcmp(roman_num_str(1),'M') == 1)
    thousands_value = M;
    next_index = 2;
    numerals_used = 1;
end

% Check hundreds
if ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'CM') == 1)
    hundreds_value = M-C;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+4)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+3),'DCCC') == 1)
    hundreds_value = D+C+C+C;
    next_index = next_index+4;
    numerals_used = numerals_used+4;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'DCC') == 1)
    hundreds_value = D+C+C;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'DC') == 1)
    hundreds_value = D+C;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'D') == 1)
    hundreds_value = D;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'CD') == 1)
    hundreds_value = D-C;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'CCC') == 1)
    hundreds_value = C+C+C;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'CC') == 1)
    hundreds_value = C+C;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'C') == 1)
    hundreds_value = C;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
end

% Check tens
if ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'XC') == 1)
    tens_value = C-X;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+4)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+3),'LXXX') == 1)
    tens_value = L+X+X+X;
    next_index = next_index+4;
    numerals_used = numerals_used+4;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'LXX') == 1)
    tens_value = L+X+X;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'LX') == 1)
    tens_value = L+X;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'L') == 1)
    tens_value = L;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'XL') == 1)
    tens_value = L-X;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'XXX') == 1)
    tens_value = X+X+X;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'XX') == 1)
    tens_value = X+X;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'X') == 1)
    tens_value = X;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
end

% Check ones
if ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'IX') == 1)
    ones_value = X-I;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+4)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+3),'VIII') == 1)
    ones_value = V+I+I+I;
    next_index = next_index+4;
    numerals_used = numerals_used+4;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'VII') == 1)
    ones_value = V+I+I;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'VI') == 1)
    ones_value = V+I;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'V') == 1)
    ones_value = V;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'IV') == 1)
    ones_value = V-I;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+3)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+2),'III') == 1)
    ones_value = I+I+I;
    next_index = next_index+3;
    numerals_used = numerals_used+3;
elseif ((numerals_used+2)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index:next_index+1),'II') == 1)
    ones_value = I+I;
    next_index = next_index+2;
    numerals_used = numerals_used+2;
elseif ((numerals_used+1)<=length(roman_num_str)) && ...
        (strcmp(roman_num_str(next_index),'I') == 1)
    ones_value = I;
    next_index = next_index+1;
    numerals_used = numerals_used+1;
end

if ((next_index-1) ~= length(roman_num_str)) || ...
        numerals_used ~= length(roman_num_str)
    disp('Not a valid Roman numeral!');
    return
end

decimal_array = [thousands_value hundreds_value tens_value ones_value];

decimal = sum(decimal_array);

message = 'The Roman numeral %s, in decimal, is %d\n ';
fprintf(message,roman_num_str,decimal);

The C++ Code

//
//  main.cpp
//  vector_test
//
//  Created by David Marcus, PE on 2/9/20.
//  Copyright © 2020 David Marcus, PE. All rights reserved.
//

#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

int main() {
    string roman;
    
    cout << "Enter a Roman Numeral to Convert.\n";
    cin >> roman;
    
    double roman_str_length = roman.length();
    
    // Define Roman Numerals in Decimal Form
    
    int M = 1000;
    int D = 500;
    int C = 100;
    int L = 50;
    int X = 10;
    int V = 5;
    int I = 1;
    
    int thousands_value = 0;
    int hundreds_value = 0;
    int tens_value = 0;
    int ones_value = 0;
    
    int next_index = 0;
    int numerals_used = 0;
    

    
    // Check thousands
    if ((roman_str_length >= 3) && (roman[0]=='M') && (roman[1]=='M') && (roman[2]=='M'))
    {
        thousands_value = M+M+M;
        next_index = 3;
        numerals_used = 3;
    }
    else if ((roman_str_length >= 2) && (roman[0]=='M') && (roman[1]=='M'))
    {
        thousands_value = M+M;
        next_index = 2;
        numerals_used = 2;
    }
    else if ((roman_str_length >= 1) && (roman[0]=='M'))
    {
        thousands_value = M;
        next_index = 1;
        numerals_used = 1;
    }
    
    // Check hundreds
    if ((numerals_used+2)<=(roman_str_length) && (roman[next_index] == 'C') && (roman[next_index+1] == 'M'))
    {
        hundreds_value = M-C;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+4)<=roman_str_length) && (roman[next_index] == 'D') && (roman[next_index+1] == 'C') && (roman[next_index+2] == 'C') && (roman[next_index+3] == 'C'))
    {
        hundreds_value = D+C+C+C;
        next_index = next_index+4;
        numerals_used = numerals_used+4;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'D') && (roman[next_index+1] == 'C') && (roman[next_index+2] == 'C'))
    {
        hundreds_value = D+C+C;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'D') && (roman[next_index+1] == 'C'))
    {
        hundreds_value = D+C;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'D'))
    {
        hundreds_value = D;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'C') && (roman[next_index+1] == 'D'))
    {
        hundreds_value = D-C;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'C') && (roman[next_index+1] == 'C') && (roman[next_index+2] == 'C'))
    {
        hundreds_value = C+C+C;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'C') && (roman[next_index+1] == 'C'))
    {
        hundreds_value = C+C;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'C'))
    {
        hundreds_value = C;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }

// Check tens
    if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'X') && (roman[next_index+1] == 'C'))
    {
        tens_value = C-X;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+4)<=roman_str_length) && (roman[next_index] == 'L') && (roman[next_index+1] == 'X') && (roman[next_index+2] == 'X') && (roman[next_index+3] == 'X'))
    {
        tens_value = L+X+X+X;
        next_index = next_index+4;
        numerals_used = numerals_used+4;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'L') && (roman[next_index+1] == 'X') && (roman[next_index+2] == 'X'))
    {
        tens_value = L+X+X;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'L') && (roman[next_index+1] == 'X'))
    {
        tens_value = L+X;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'L'))
    {
        tens_value = L;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'X') && (roman[next_index+1] == 'L'))
    {
        tens_value = L-X;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'X') && (roman[next_index+1] == 'X') && (roman[next_index+2] == 'X'))
    {
        tens_value = X+X+X;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'X') && (roman[next_index+1] == 'X'))
    {
        tens_value = X+X;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'X'))
    {
        tens_value = X;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }
    
//    % Check ones
    if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'I') && (roman[next_index+1] == 'X'))
    {
        ones_value = X-I;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+4)<=roman_str_length) && (roman[next_index] == 'V') && (roman[next_index+1] == 'I') && (roman[next_index+2] == 'I') && (roman[next_index+3] == 'I'))
    {
        ones_value = V+I+I+I;
        next_index = next_index+4;
        numerals_used = numerals_used+4;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'V') && (roman[next_index+1] == 'I') && (roman[next_index+2] == 'I'))
    {
        ones_value = V+I+I;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'V') && (roman[next_index+1] == 'I'))
    {
        ones_value = V+I;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'V'))
    {
        ones_value = V;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'I') && (roman[next_index+1] == 'V'))
    {
        ones_value = V-I;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+3)<=roman_str_length) && (roman[next_index] == 'I') && (roman[next_index+1] == 'I') && (roman[next_index+2] == 'I'))
    {
        ones_value = I+I+I;
        next_index = next_index+3;
        numerals_used = numerals_used+3;
    }
    else if (((numerals_used+2)<=roman_str_length) && (roman[next_index] == 'I') && (roman[next_index+1] == 'I'))
    {
        ones_value = I+I;
        next_index = next_index+2;
        numerals_used = numerals_used+2;
    }
    else if (((numerals_used+1)<=roman_str_length) && (roman[next_index] == 'I'))
    {
        ones_value = I;
        next_index = next_index+1;
        numerals_used = numerals_used+1;
    }
    
    if ((next_index != roman_str_length) || (numerals_used != roman_str_length))
    {
        cout << "Not a valid Roman numeral!\n";
        return 0;
    }

    int decimal = thousands_value+hundreds_value+tens_value+ones_value;

    cout << "The Roman Numeral " << roman << ", in decimal form, is " << decimal << ".\n";
    
    return 0;
}

David Marcus

David Marcus is the creator of EEmaginations, and is a Professional Electrical Engineer working in the aerospace industry. David has a passion for solving engineering problems, and helping others succeed educationally and professionally.

Leave a Comment