In this problem you will design and implement a Roman numeral calculator. Most people are unaware that the subtractive Roman numeral notation commonly in use today (such as IV Meaning 4) was only rarely used during the time of the Roman Republic and Empire. For ease of calculation, the Romans most frequently used a purely additive notation in which a number was simply the sum of its digits (4 equals IIII in this notation).
Each number starts with the digit of highest value and ends with the one of smallest value. This is the notation we will use in this problem.
Your program will input two Roman numbers and an arithmetic operator and print out the result of the operation, also as a Roman number. The values of the Roman digits are as follows:
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
Thus, the number MDCCCCLXXXVIIII represents 1989. The arithmetic operators that your program should recognize in the input are +, -, * and /. These should perform the Pascal operations of integer addition, subtraction, multiplication and division.
One way of approaching this problem is to convert the Roman numbers into integers, perform the required operation, and then convert the result back into Roman number for printing. The following might be a sample run of the program, for an interactive system.
Enter the first number:
MCCXXVI
The first number is 1226
Enter the second number:
LXVIIII
The second number is 69
Enter the desired arithmetic operation:
+
The sum of MCCXXVI and LXVIIII is MCCLXXXXV (1295)
[code]PROGRAM Roman_Numbers1;
TYPE
indexType = 1..7;
RomanNumberArray = array [indexType] of char;
RomansNumbers = (I,V,X,L,C,D,M);
VAR
RomansNu : RomansNumbers;
RomansNo : RomanNumberArray;
first,second,Oper: char; {Oper = arithmetic operation}
realnumber1,realnumber2,sum : integer;
index : indexType;
Procedure Read_Romans_Numbers_to_Real;
BEGIN
writeln('Enter The First Number: ');
readln(first);
Case first Of
'I': realnumber1:= 1;
'V': realnumber1:= 5;
'X': realnumber1:= 10;
'L': realnumber1:= 50;
'C': realnumber1:= 100;
'D': realnumber1:= 500;
'M': realnumber1:= 1000;
else writeln('Roman Numerals Are Just I,V,X,L,C,D,M');
writeln('The First Number is',realnumber);
write('Enter The Second Number:'); readln(second);
Case second Of
'I': realnumber2:= 1;
'V': realnumber2:= 5;
'X': realnumber2:= 10;
'L': realnumber2:= 50;
'C': realnumber2:= 100;
'D': realnumber2:= 500;
'M': realnumber2:= 1000;
else writeln('Roman Numerals Are Just I,V,X,L,C,D,M');
end;
writeln('The Second Number is',realnumber2);
end;
write('Enter The Arithmetic Operation:');
readln(oper);
Case oper of
'+': sum := 'realnumber1'+'realnumber2';
'-': sum := 'realnumber1'-'realnumber2';
'*': sum := 'realnumber1'*'realnumber2';
'/': sum := 'realnumber1'/'realnumber2';
else writeln('The Arithmetic Operations are +,-,*,/.');
end;
write('The Sum Of ',first,'and',second,'is',sum);
End;
End;[/code]
Comments
[code][color=Blue]
{$A+,B-,D-,E-,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V-,X+,Y-}
{Compiler directives}
const _sym_=['O','M','D','C','L','X','V','I','-'];
{Roman numbers do not support zero, so added here for the sake of the calculator, negative sign also added}
{Supports negative numbers}
function int_2_roman({inpu}t:integer):string;
var i:byte;
s:string;
begin
s:='O';
if t<>0 then begin
if t<0 then s:='-' else s:='';
t:=abs(t);
if ((t div 1000)>0) then begin
for i:=1 to t div 1000 do s:=s+'M';
t:=t-(t div 1000) * 1000;
end;
if ((t div 500)>0) then begin
for i:=1 to t div 500 do s:=s+'D';
t:=t-(t div 500) * 500;
end;
if ((t div 100)>0) then begin
for i:=1 to t div 100 do s:=s+'C';
t:=t-(t div 100) * 100;
end;
if ((t div 50)>0) then begin
for i:=1 to t div 50 do s:=s+'L';
t:=t-(t div 50) * 50;
end;
if ((t div 10)>0) then begin
for i:=1 to t div 10 do s:=s+'X';
t:=t-(t div 10) * 10;
end;
if ((t div 5)>0) then begin
for i:=1 to t div 5 do s:=s+'V';
t:=t-(t div 5) * 5;
end;
for i:=1 to t do s:=s+'I';
end;
int_2_roman:=s;
end;
{Returns false if incorrect input, doesn't support negative numbers}
function roman_2_int(s:string;var {outpu}t:integer):boolean;
var i:byte;
error:boolean;
begin
error:=false;
t:=0;
if ord(s[0])>0 then begin
for i:=1 to ord(s[0]) do
if not(s[i] in _sym_) then error:=true;
if not(error) then begin
for i:=1 to ord(s[0]) do
case upcase(s[i]) of
'M':inc(t,1000);
'D':inc(t,500);
'C':inc(t,100);
'L':inc(t,50);
'X':inc(t,10);
'V':inc(t,5);
'I':inc(t);
end;{case}
end;
end;
roman_2_int:=not(error);
end;
[/color][/code]
function Roman(x:integer):string;
{ Paul Robinson, Viridian Development Corporation, 2013-03-18
if your compiler doesn't include 'result' as a standard
variable for the return value of a function, uncomment
the next line }
{ var result: string }
begin
result := '';
while x >= 1000 do
begin result := result+'m'; x := x - 1000 end;
if x >= 900 then
begin result := result+'cm'; x := x - 900 end;
if x >= 500 then
begin result := result+'d'; x := x - 500 end;
if x >= 400 then
begin result := result+'cd'; x := x - 400 end;
while x >= 100 do
begin result := result+'c'; x := x - 100 end;
if x >= 90 then
begin result := result+'xc'; x := x - 90 end;
if x >= 50 then
begin result := result+'l'; x := x - 50 end;
if x >= 40 then
begin result := result+'xl'; x := x - 40 end;
while x >= 10 do
begin result := result+'x'; x := x - 10 end;
if x >= 9 then
begin result := result+'ix'; x := x - 9 end;
if x >= 5 then
begin result := result+'v'; x := x - 5 end;
if x >= 4 then
begin result := result+'iv'; x := x - 5 end;
while x >= 1 do
begin result := result+'i'; x := x - 1 end;
{if result is not in your compiler for a return value
uncomment the following line }
{ roman := result;}
end;