Created
February 11, 2014 17:27
-
-
Save JamesEarle/8939661 to your computer and use it in GitHub Desktop.
Rational Number Calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with | |
Ada.Text_IO, | |
Ada.Strings, | |
Ada.Strings.Fixed, | |
RATIONALS; | |
use | |
Ada.Text_IO, | |
Ada.Strings, | |
Ada.Strings.Fixed, | |
RATIONALS; | |
procedure rationalcalc is | |
A, B, C : RATIONAL; | |
Check : Boolean; | |
procedure Start is | |
type My_Float is digits 9; | |
A, B, C : RATIONAL; | |
Char : Character; | |
Check : Boolean; | |
F : My_Float; | |
begin | |
Put_Line("Welcome to the Rational Numbers Calculator!"); | |
Put("Please include '.' after each operand (e.g. 'A/B.')"); | |
New_Line(1); | |
Put("Type 'EXIT.' to leave the program, or type 'HELP.' to see a list of operators. "); | |
Put_Line("Order of input is: First Operand, Operator, Second Operand."); | |
New_Line(1); | |
A := RAT(1,1); --Initialize the A value, to be overwritten | |
while DENOM(A) /= 9999 loop | |
Put("O1: "); | |
GET_IN(A); | |
if DENOM(A) /= 9999 and DENOM(A) /= 8888 then | |
Put("Op: "); | |
Get(Char); | |
Put("O2: "); | |
GET_IN(B); | |
case Char is | |
when '+' => | |
C := A+B; | |
New_Line(1); | |
Put("= "); | |
C := NORMAL(C); | |
PUT_OUT(C); | |
Put("= "); | |
F := My_Float(NUMER(C))/My_Float(DENOM(C)); | |
Put(Trim(My_Float'Image(F),Both)); | |
New_Line(1); | |
when '-' => | |
C := A-B; | |
New_Line(1); | |
Put("= "); | |
C := NORMAL(C); | |
PUT_OUT(C); | |
Put("= "); | |
F := My_Float(NUMER(C))/My_Float(DENOM(C)); | |
Put(Trim(My_Float'Image(F),Both)); | |
New_Line(1); | |
when '*' => | |
C := A*B; | |
New_Line(1); | |
Put("= "); | |
C := NORMAL(C); | |
PUT_OUT(C); | |
Put("= "); | |
F := My_Float(NUMER(C))/My_Float(DENOM(C)); | |
Put(Trim(My_Float'Image(F),Both)); | |
New_Line(1); | |
when '/' => | |
C := A/B; | |
New_Line(1); | |
Put("= "); | |
C := NORMAL(C); | |
PUT_OUT(C); | |
Put("= "); | |
F := My_Float(NUMER(C))/My_Float(DENOM(C)); | |
Put(Trim(My_Float'Image(F),Both)); | |
New_Line(1); | |
when '<' => | |
Check := LE(A,B); | |
New_Line(1); | |
Put("= "); | |
Put_Line(Boolean'Image(Check)); | |
New_Line(1); | |
when '>' => | |
Check := GE(A,B); | |
New_Line(1); | |
Put("= "); | |
Put_Line(Boolean'Image(Check)); | |
New_Line(1); | |
when '=' => | |
Check := A=B; | |
New_Line(1); | |
Put("= "); | |
Put_Line(Boolean'Image(Check)); | |
New_Line(1); | |
when others => | |
Put_Line("Please enter a valid operation."); | |
end case; | |
end if; | |
end loop; | |
end start; | |
begin | |
Start; | |
New_Line(1); | |
Put_Line("Tests of every procedure and function below."); | |
New_Line(1); | |
Put("Provide a rational number (A/B.): "); | |
GET_IN(A); | |
New_Line(1); | |
Put("You entered: "); | |
PUT_OUT(A); | |
A := RAT(3,4); | |
B := RAT(5,8); | |
Put_Line("Testing arithmetic below. A = 3/4. B = 5/8."); | |
C := A+B; | |
Put("A + B = "); | |
PUT_OUT(C); | |
C := A-B; | |
Put("A - B = "); | |
PUT_OUT(C); | |
C := A*B; | |
Put("A * B = "); | |
PUT_OUT(C); | |
C := A/B; | |
Put("A / B = "); | |
PUT_OUT(C); | |
Check := A=B; | |
Put_Line("A = B returns " & Boolean'Image(Check)); | |
Check := NE(A,B); | |
Put_Line("A != B returns " & Boolean'Image(Check)); | |
Check := LT(A,B); | |
Put_Line("A < B returns " & Boolean'Image(Check)); | |
Check := LE(A,B); | |
Put_Line("A <= B returns " & Boolean'Image(Check)); | |
Check := GT(A,B); | |
Put_Line("A > B returns " & Boolean'Image(Check)); | |
Check := GE(A,B); | |
Put_Line("A >= B returns " & Boolean'Image(Check)); | |
A := RAT(24,10); | |
Put_Line("Testing the NORMAL function. A = 24/10"); | |
A := NORMAL(A); | |
Put("After call to NORMAL, A = "); | |
PUT_OUT(A); | |
end rationalcalc; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with | |
Ada.Text_IO, | |
Ada.Strings, | |
Ada.Strings.Fixed, | |
RATIONALS; | |
use | |
Ada.Text_IO, | |
Ada.Strings, | |
Ada.Strings.Fixed, | |
RATIONALS; | |
-- End Packages -- | |
package body RATIONALS is | |
function RAT (N, D : INTEGER) return RATIONAL is | |
Result : RATIONAL; | |
begin | |
if D = 0 then | |
raise RATIONAL_ERROR; | |
else | |
Result := RATIONAL'( N, D ); | |
end if; | |
return Result; | |
exception | |
when RATIONAL_ERROR => | |
Put_Line("RATIONAL_ERROR: Denominator cannot be zero."); | |
raise; | |
end RAT; -- Returns the given rational number from GET_IN | |
function NUMER(R : RATIONAL) return INTEGER is | |
begin | |
return R.NUM; | |
end NUMER; -- returns numerator | |
function DENOM (R : RATIONAL) return INTEGER is | |
begin | |
return R.DEN; | |
end DENOM; -- returns denominator | |
procedure GET_IN (R : out RATIONAL) is | |
type Input_String is array (Integer range 1..20) of Character; | |
Str : Input_String := (others => ' '); | |
Ctr : Integer := 1; | |
S : String(1..20) := (others => ' '); | |
C : Character; | |
T1 : String(1..20) := (others => ' '); | |
T2 : String(1..20) := (others => ' '); | |
Exit_String : Input_String := "EXIT "; | |
Help_String : Input_String := "HELP "; | |
Check : Boolean := False; | |
Numerator, Denominator : Integer; | |
begin | |
while Ctr < Str'Last loop | |
Get(C); | |
exit when C = '.'; | |
Str(Ctr) := C; | |
S(Ctr) := Str(Ctr); | |
Ctr := Ctr + 1; | |
end loop; | |
if Str = Help_String then | |
New_Line(1); | |
Put_Line("Below are the possible operators."); | |
Put_Line("+, -, *, /, <, >, =, <=, >=, !="); | |
R.NUM := 0; | |
R.DEN := 8888; | |
return; | |
end if; | |
if Str = Exit_String then | |
New_Line(1); | |
Put_Line("Thank you for using the Rationals Calculator!"); | |
R.NUM := 0; | |
R.DEN := 9999; | |
return; | |
end if; | |
for I in Integer range 1..(Ctr-1) loop | |
if S(I) = '/' then | |
Check := True; | |
else | |
if Check = False then | |
T1(I) := S(I); | |
else | |
T2(I) := S(I); | |
end if; | |
end if; | |
end loop; | |
Numerator := Integer'Value(T1); | |
Denominator := Integer'Value(T2); | |
if Denominator = 0 then | |
raise RATIONAL_ERROR; | |
else | |
R.NUM := Numerator; | |
R.DEN := Denominator; | |
end if; | |
exception | |
when RATIONAL_ERROR => | |
Put_Line("RATIONAL_ERROR: Denominator cannot be zero."); | |
raise; | |
end GET_IN; -- inputs rational number from keyboard | |
procedure PUT_OUT (R : in RATIONAL) is | |
Result : RATIONAL; | |
begin | |
Result := R; | |
if Result.NUM = Result.DEN then | |
Put_Line("1"); | |
New_Line(1); | |
elsif Result.NUM = 0 then | |
Put_Line("0"); | |
New_Line(1); | |
elsif Result.DEN = 1 then | |
Put_Line(Trim(Integer'Image(R.NUM),Both)); | |
New_Line(1); | |
else | |
Put_Line(Trim(Integer'Image(R.NUM),Both) & "/" & Trim(Integer'Image(R.DEN),Both)); | |
New_Line(1); | |
end if; | |
end PUT_OUT; -- outputs rational number (normalized) to screen | |
-- Rational Arithmetic Procedures (may raise RATIONAL_ERROR if necessary): | |
function NORMAL (R : RATIONAL) return RATIONAL is | |
Result : RATIONAL; | |
M : Integer := R.NUM; | |
N : Integer := R.DEN; | |
T, LCM : Integer; | |
begin | |
Result := R; | |
if Result.NUM = Result.DEN then | |
Result.NUM := 1; | |
Result.DEN := 1; | |
end if; | |
while (Result.NUM rem 2 = 0 and Result.DEN rem 2 = 0) loop | |
Result.NUM := Result.NUM / 2; | |
Result.DEN := Result.DEN / 2; | |
end loop; | |
if Result.NUM mod Result.DEN = 0 then | |
Result.NUM := Result.NUM / Result.DEN; | |
Result.DEN := 1; | |
end if; | |
return Result; | |
end NORMAL; -- normalizes rational number R | |
function "+" (X, Y : RATIONAL) return RATIONAL is | |
Result : RATIONAL; | |
N1,D1,N2,D2 : Integer; | |
begin | |
N1 := X.NUM * Y.DEN; | |
D1 := X.DEN * Y.DEN; | |
N2 := Y.NUM * X.DEN; | |
D2 := Y.DEN * X.DEN; | |
Result.NUM := N1 + N2; | |
Result.DEN := D2; | |
Result := NORMAL(Result); | |
return Result; | |
end "+"; | |
function "-" (X, Y : RATIONAL) return RATIONAL is | |
Result : RATIONAL; | |
N1,D1,N2,D2 : Integer; | |
begin | |
N1 := X.NUM * Y.DEN; | |
D1 := X.DEN * Y.DEN; -- 3/9 | |
N2 := Y.NUM * X.DEN; | |
D2 := Y.DEN * X.DEN; -- 6/9 | |
Result.NUM := N1 - N2; | |
Result.DEN := D2; | |
Result := NORMAL(Result); | |
return Result; | |
end "-"; | |
function "*" (X, Y : RATIONAL) return RATIONAL is | |
Result : Rational; | |
N1,D1,N2,D2 : Integer; | |
begin | |
N1 := X.NUM; | |
D1 := X.DEN; | |
N2 := Y.NUM; | |
D2 := Y.DEN; | |
Result.NUM := N1 * N2; | |
Result.DEN := D1 * D2; | |
Result := NORMAL(Result); | |
return Result; | |
end "*"; | |
function "/" (X, Y : RATIONAL) return RATIONAL is | |
Result, Reciprocal : RATIONAL; | |
N,D : Integer; | |
begin | |
N := Y.NUM; | |
D := Y.DEN; | |
Reciprocal.NUM := D; | |
Reciprocal.DEN := N; | |
Result := X*Reciprocal; | |
Result := NORMAL(Result); | |
return Result; | |
end "/"; | |
-- Relational functions: | |
function "=" (X, Y : RATIONAL) return BOOLEAN is | |
begin | |
if (X.NUM*Y.DEN = Y.NUM*X.DEN) then | |
return True; | |
else | |
return False; | |
end if; | |
end "="; | |
function NE (X, Y : RATIONAL) return BOOLEAN is | |
begin | |
if (X.NUM*Y.DEN = Y.NUM*X.DEN) then | |
return False; | |
else | |
return True; | |
end if; | |
end NE; -- not equal | |
function LT (X, Y : RATIONAL) return BOOLEAN is | |
R1,R2 : Integer; | |
begin | |
R1 := X.NUM*Y.DEN; | |
R2 := Y.NUM*X.DEN; | |
if R1 < R2 then | |
return True; | |
else | |
return False; | |
end if; | |
end LT; -- less than ( TRUE if X < Y ) | |
function LE (X, Y : RATIONAL) return BOOLEAN is | |
R1,R2 : Integer; | |
begin | |
R1 := X.NUM*Y.DEN; | |
R2 := Y.NUM*X.DEN; | |
if R1 <= R2 then | |
return True; | |
else | |
return False; | |
end if; | |
end LE; -- less equal ( TRUE if X <= Y ) | |
function GT (X, Y : RATIONAL) return BOOLEAN is | |
R1,R2 : Integer; | |
begin | |
R1 := X.NUM*Y.DEN; | |
R2 := Y.NUM*X.DEN; | |
if R1 > R2 then | |
return True; | |
else | |
return False; | |
end if; | |
end GT; -- greater than ( TRUE if X > Y ) | |
function GE (X, Y : RATIONAL) return BOOLEAN is | |
R1,R2 : Integer; | |
begin | |
R1 := X.NUM*Y.DEN; | |
R2 := Y.NUM*X.DEN; | |
if R1 >= R2 then | |
return True; | |
else | |
return False; | |
end if; | |
end GE; -- greater equal ( TRUE if X >= Y ) | |
begin | |
Put_Line(""); | |
end RATIONALS; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package RATIONALS is | |
type RATIONAL is private; | |
RATIONAL_ERROR : exception; -- raised by any subprogram below if denominator = 0 | |
function RAT (N, D : INTEGER) return RATIONAL; -- may raise RATIONAL_ERROR | |
function NUMER (R : RATIONAL) return INTEGER; -- returns numerator of a rational | |
function DENOM (R : RATIONAL) return INTEGER; -- returns denominator | |
procedure GET_IN (R : out RATIONAL); -- inputs rational number from keyboard | |
procedure PUT_OUT (R : in RATIONAL); -- outputs rational number (normalized) to screen | |
function NORMAL (R : RATIONAL) return RATIONAL; -- normalizes rational number R | |
function "+" (X, Y : RATIONAL) return RATIONAL; | |
function "-" (X, Y : RATIONAL) return RATIONAL; | |
function "*" (X, Y : RATIONAL) return RATIONAL; | |
function "/" (X, Y : RATIONAL) return RATIONAL; | |
function "=" (X, Y : RATIONAL) return BOOLEAN; | |
function NE (X, Y : RATIONAL) return BOOLEAN; -- not equal | |
function LT (X, Y : RATIONAL) return BOOLEAN; -- less than ( TRUE if X < Y ) | |
function LE (X, Y : RATIONAL) return BOOLEAN; -- less equal ( TRUE if X <= Y ) | |
function GT (X, Y : RATIONAL) return BOOLEAN; -- greater than ( TRUE if X > Y ) | |
function GE (X, Y : RATIONAL) return BOOLEAN; -- greater equal ( TRUE if X >= Y ) | |
private | |
type RATIONAL is record | |
NUM : INTEGER; -- numerator | |
DEN : INTEGER; -- denominator (cannot be zero! - see exception above) | |
end record; | |
end rationals; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment