Pascal: Converting from Denary to Roman Numerals

First version without functions:

program denary_roman;

var thousands, hundreds, tens, units:array[1..10] of string;
num:integer;
th, hun, tns, unts:integer;
roman_number:string;
response:char;

begin
 thousands[1]:=''; //zero
 thousands[2]:='M';
 thousands[3]:='MM';
 thousands[4]:='MMM';
 hundreds[1]:='';
 hundreds[2]:='C';
 hundreds[3]:='CC';
 hundreds[4]:='CCC';
 hundreds[5]:='CD';
 hundreds[6]:='D';
 hundreds[7]:='DC';
 hundreds[8]:='DCC';
 hundreds[9]:='DCCC';
 hundreds[10]:='CM';
 tens[1]:='';
 tens[2]:='X';
 tens[3]:='XX';
 tens[4]:='XXX';
 tens[5]:='XL';
 tens[6]:='L';
 tens[7]:='LX';
 tens[8]:='LXX';
 tens[9]:='LXXX';
 tens[10]:='XC';
 units[1]:='';
 units[2]:='I';
 units[3]:='II';
 units[4]:='III';
 units[5]:='IV';
 units[6]:='V';
 units[7]:='VI';
 units[8]:='VII';
 units[9]:='VIII';
 units[10]:='IX';

 repeat
  writeln('Enter an integer up to 3499');
  readln(num);
  th:= num div 1000 + 1;
  hun:= num mod 1000 div 100 + 1;
  tns:= num mod 100 div 10 + 1;
  unts:= num mod 10 + 1;
  roman_number:= thousands[th] + hundreds[hun] + tens[tns] + units[unts];
  writeln(roman_number);
  writeln('Another?');
  readln(response);
 until response in ['n','N'];
end.

 

Second version with procedure and function; function uses a compressed version of the div and mod operations.

program roman_numerals;

var
  thousands, hundreds, tens, units: array [1..10] of string;
  roman:string;
  n:integer;
  another : char;

procedure initialise;
begin
  thousands[1]:='';
  thousands[2] := 'M';
  thousands[3] := 'MM';
  thousands[4] := 'MMM';
  hundreds[1]:='';
  hundreds[2]:='C';
  hundreds[3]:='CC';
  hundreds[4]:='CCC';
  hundreds[5]:='CD';
  hundreds[6]:='D';
  hundreds[7]:='DC';
  hundreds[8]:='DCC';
  hundreds[9]:='DCCC';
  hundreds[10]:='CM';
  tens[1]:='';
  tens[2]:='X';
  tens[3]:='XX';
  tens[4]:='XXX';
  tens[5]:='XL';
  tens[6]:='L';
  tens[7]:='LX';
  tens[8]:='LXX';
  tens[9]:='LXXX';
  tens[10]:='XC';
  units[1]:='';
  units[2]:='I';
  units[3]:='II';
  units[4]:='III';
  units[5]:='IV';
  units[6]:='V';
  units[7]:='VI';
  units[8]:='VII';
  units[9]:='VIII';
  units[10]:='IX';
end;

function toroman(dn:integer):string;
begin
  toroman := thousands[dn div 1000 + 1] +
    hundreds[dn mod 1000 div 100 + 1] +
      tens[dn mod 100 div 10 + 1] +
        units[dn mod 10 + 1];
end;

begin
  initialise;
  repeat
    repeat
      writeln ('Enter number to convert to Roman numerals, max 3,999');
      readln (n);
      if not ((n < 4000) and (n >= 0))
        then writeln ('Out of range, try again');
      until (n < 4000) and (n >= 0);
    roman := toroman(n);
    writeln (roman);
    writeln ('Another conversion? y/n');
    readln (another);
  until another = 'n';
end.

The Roman numerals are stored in arrays for thousands, hundreds, tens and units so V is in units[6], CC is in hundreds[3] and so on. The extra 1 in this is due to the need for zero in denary, which does not appear in Roman numerals. The function toroman takes a denary number and converts it to roman by working out the index of each of the four arrays.

For example, 1000 is found from thousands [1000 div 1000 + 1]; 1000 div 1000 is 1, +1 = 2 so we use thousands[2] = 'M'.

2200 is (2200 div 1000) = 2, + 1 = 3 so we use thousands[3] = 'MM'. We nd concatenate the hundreds part: (2200 mod 1000 div 100) = (200 div 100) = 2, + 1 = 3 so we use hundreds[3] = 'CC'.

2230 is MM + CC + (2230 mod 100) = 30, div 10 = 3, + 1 = 4 so we use tens[4] = 'XXX'.

2236 is MMCCXXX + (2236 mod 10) = 6, + 1 = 7 so we use units[7] = 'VI': MMCCXXXVI.

Back to questions