Decimal to Roman Numeral Conversion

rome-1520894_1920

Introduction

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

The Algorithm

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

  1. Write decimal number in expanded form.
    • 1,234 = 1000+200+30+4
  2. Convert each term of expanded form number into Roman numerals (use the table below to make the conversion process easier).
    • 1000 = M
    • 200 = CC
    • 30 = XXX
    • 4 = IV
  3. Concatenate Roman numeral terms.
    • 1,234 = MCCXXXIV
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
%%%%%%%%%%%%%%% decimal2roman %%%%%%%%%%%%%%%
%
%%%%% Inputs %%%%%
%
%%% number: Decimal number to convert (number between 1 and 3999)
%
%%%%% Outputs %%%%%
%
%%% roman: Roman numeral

function roman = decimal2roman(number)

if nargin < 1
    number = inputdlg('Enter Number to Convert','Number to Roman Numeral Converter');
    number = str2double(number{1});
end

M = 1000;
C = 100;
X = 10;

% Convert number to expanded form
if (number >= 1000) && (number <= 3999)
    
    thousands_digit = floor(number/1000);
    thousands_value = thousands_digit*M;
    
    hundreds_digit = floor((number-thousands_value)/100);
    hundreds_value = hundreds_digit*C;
    
    tens_digit = floor((number-thousands_value-hundreds_value)/10);
    tens_value = tens_digit*X;
    
    ones_value = floor(number-thousands_value-hundreds_value-tens_value);
    
    number_breakdown = [thousands_value hundreds_value tens_value ones_value];
    number_breakdown = number_breakdown(number_breakdown~=0);
    
    number_length = length(number_breakdown);
    
elseif (number >= 100) && (number <= 999)

    hundreds_digit = floor(number/100);
    hundreds_value = hundreds_digit*C;
    
    tens_digit = floor((number-hundreds_value)/10);
    tens_value = tens_digit*X;
    
    ones_value = floor(number-hundreds_value-tens_value);
    
    number_breakdown = [hundreds_value tens_value ones_value];
    number_breakdown = number_breakdown(number_breakdown~=0);
    
    number_length = length(number_breakdown);
    
elseif (number >= 10) && (number <= 99)

    tens_digit = floor(number/10);
    tens_value = tens_digit*X;
    
    ones_value = floor(number-tens_value);
    
    number_breakdown = [tens_value ones_value];
    number_breakdown = number_breakdown(number_breakdown~=0);
    
    number_length = length(number_breakdown);
    
elseif (number <= 9) && (number >= 1)
    number_length = 1;

    number_breakdown = number;
    
end

lookup_table_decimal = [1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 ...
    100 200 300 400 500 600 700 800 900 1000 2000 3000];
lookup_table_roman = ["I","II","III","IV","V","VI","VII","VIII","IX",...
    "X","XX","XXX","XL","L","LX","LXX","LXXX","XC","C","CC","CCC","CD","D",...
    "DC","DCC","DCCC","CM","M","MM","MMM"];

[~,ind] = ismember(number_breakdown,lookup_table_decimal);

roman = lookup_table_roman(ind);

if number_length == 4
    roman = strcat(roman(1),roman(2),roman(3),roman(4));
elseif number_length == 3
    roman = strcat(roman(1),roman(2),roman(3));
elseif number_length == 2
    roman = strcat(roman(1),roman(2));
end

roman = roman{1};

message = 'The number %d, in Roman numerals, is %s\n ';
fprintf(message,number,roman);

The C++ Code

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

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

using namespace std;

int main() {
    int decimal;
    
    cout << "Enter a number between 1 and 3999.\n";
    cin >> decimal;
    
    int M = 1000;
    int C = 100;
    int X = 10;
    
    // Convert decimal decimal to expanded form
    
    int thousands_digit = 0;
    int thousands_value = 0;
    int hundreds_digit = 0;
    int hundreds_value = 0;
    int tens_digit = 0;
    int tens_value = 0;
    int ones_value = 0;
    
    int i;
    
    double decimal_length = 0;
    vector<int> decimal_breakdown;
    
    // Convert number to expanded form
    if (0 >= decimal || decimal >= 4000)
    {
        cout << "Not a valid number.\n";
        return 0;
    }
    if (1000 <= decimal && decimal <= 3999)
    {
        thousands_digit = floor(decimal/1000);
        thousands_value = thousands_digit*M;
        
        hundreds_digit = floor((decimal-thousands_value)/100);
        hundreds_value = hundreds_digit*C;
        
        tens_digit = floor((decimal-thousands_value-hundreds_value)/10);
        tens_value = tens_digit*X;
        
        ones_value = floor(decimal-thousands_value-hundreds_value-tens_value);
        decimal_breakdown = {thousands_value,hundreds_value,tens_value,ones_value};
        
        for (i=0;i<decimal_breakdown.size();i++)
        {
            if (decimal_breakdown.at(i)==0)
            {
                decimal_breakdown.erase(decimal_breakdown.begin()+i);
                i--;
            }
        }
        decimal_length = decimal_breakdown.size();
    }
    
    else if (100 <= decimal && decimal <= 999)
    {
        hundreds_digit = floor(decimal/100);
        hundreds_value = hundreds_digit*C;
        
        tens_digit = floor((decimal-hundreds_value)/10);
        tens_value = tens_digit*X;
        
        ones_value = floor(decimal-hundreds_value-tens_value);
        decimal_breakdown = {hundreds_value,tens_value,ones_value};
        
        for (i=0;i<decimal_breakdown.size();i++)
        {
            if (decimal_breakdown.at(i)==0)
            {
                decimal_breakdown.erase(decimal_breakdown.begin()+i);
                i--;
            }
        }
        decimal_length = decimal_breakdown.size();
    }
    
    else if (10 <= decimal && decimal <= 99)
    {
        tens_digit = floor(decimal/10);
        tens_value = tens_digit*X;
        
        ones_value = floor(decimal-tens_value);
        decimal_breakdown = {tens_value,ones_value};
        
        for (i=0;i<decimal_breakdown.size();i++)
        {
            if (decimal_breakdown.at(i)==0)
            {
                decimal_breakdown.erase(decimal_breakdown.begin()+i);
                i--;
            }
        }
        decimal_length = decimal_breakdown.size();
    }
    
    else if (1 <= decimal && decimal <= 9)
    {
        decimal_breakdown = {decimal};
        decimal_length = decimal_breakdown.size();
    }
    
    vector<int> lookup_table_decimal = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000};
    vector<string> lookup_table_roman = {"I","II","III","IV","V","VI","VII","VIII","IX", "X","XX","XXX","XL","L","LX","LXX","LXXX","XC","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","M","MM","MMM"};
    
    // Find indices of lookup table where expanded decimal terms exist
    vector<long> index_vector;
    vector<int>::iterator it;
    
    for (i=0;i<decimal_breakdown.size();i++)
    {
    it = find(lookup_table_decimal.begin(), lookup_table_decimal.end(), decimal_breakdown.at(i));
        index_vector.push_back(distance(lookup_table_decimal.begin(),it));
    }
    
    // Create vector string of converted decimal number
    string roman;
    
    if (decimal_length == 4)
    {
        roman = lookup_table_roman.at(index_vector.at(0))+lookup_table_roman.at(index_vector.at(1))+lookup_table_roman.at(index_vector.at(2))+lookup_table_roman.at(index_vector.at(3));
    }
    
    else if (decimal_length == 3)
    {
        roman = lookup_table_roman.at(index_vector.at(0))+lookup_table_roman.at(index_vector.at(1))+lookup_table_roman.at(index_vector.at(2));
    }
    
    else if (decimal_length == 2)
    {
        roman = lookup_table_roman.at(index_vector.at(0))+lookup_table_roman.at(index_vector.at(1));
    }
    
    else if (decimal_length == 1)
    {
        roman = lookup_table_roman.at(index_vector.at(0));
    }
    
    cout << "The decimal number " << decimal << " in Roman numerals, is " << roman << ".\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