Roman Numeral to Decimal Conversion
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:
- 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.
- Convert each term of the grouped Roman numerals to decimal numbers:
- MMM = 3000
- DCCC = 800
- LXXX = 80
- VIII = 8
- Add the values of the thousands, hundreds, tens, and ones.
- The example above yields the decimal number of : 3000+800+80+8 = 3,888.
Thousands | Hundreds | Tens | Ones |
---|---|---|---|
MMM = 3000 | CM = 900 | XC = 90 | IX = 9 |
MM = 2000 | DCCC = 800 | LXXX = 80 | VIII = 8 |
M = 1000 | DCC = 700 | LXX = 70 | VII = 7 |
DC = 600 | LX = 60 | VI = 6 | |
D = 500 | L = 50 | V = 5 | |
CD = 400 | XL = 40 | IV = 4 | |
CCC = 300 | XXX = 30 | III = 3 | |
CC = 200 | XX = 20 | II = 2 | |
C = 100 | X = 10 | I = 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;
}