From f11c770329edf407de1e534e286ecbfd2a3495c9 Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Tue, 7 Feb 2017 00:21:59 +1100 Subject: Rationals package added --- src/rationals.adb | 380 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/rationals.ads | 218 +++++++++++++++++++++++++++++++ 2 files changed, 598 insertions(+) create mode 100644 src/rationals.adb create mode 100644 src/rationals.ads diff --git a/src/rationals.adb b/src/rationals.adb new file mode 100644 index 0000000..2255afe --- /dev/null +++ b/src/rationals.adb @@ -0,0 +1,380 @@ + + +with Ada.Strings.Fixed; + + +package body Rationals is + + + function Reduce + (Numerator, Denominator : in Integer) + return Fraction + is + A : Integer := Numerator; + B : Integer := Denominator; + Temp : Integer; + begin + -- Euclid's algorithm + loop + Temp := A; + A := B; + B := Temp mod B; + exit when B = 0; + end loop; + return (Num => Numerator / A, Den => Denominator / A); + end Reduce; + + + + + function "+" + (Left, Right : in Fraction) + return Fraction is + begin + return Reduce + (Left.Num * Right.Den + Left.Den * Right.Num, + Left.Den * Right.Den); + end "+"; + + function "+" + (Left : in Fraction; + Right : in Integer) + return Fraction is + begin + return Reduce + (Left.Num + Left.Den * Right, + Left.Den); + end "+"; + + function "+" + (Left : in Integer; + Right : in Fraction) + return Fraction is + begin + return Reduce + (Left * Right.Den + Right.Num, + Right.Den); + end "+"; + + + + + function "-" + (Left, Right : in Fraction) + return Fraction is + begin + return Reduce + (Left.Num * Right.Den - Left.Den * Right.Num, + Left.Den * Right.Den); + end "-"; + + function "-" + (Left : in Fraction; + Right : in Integer) + return Fraction is + begin + return Reduce + (Left.Num - Left.Den * Right, + Left.Den); + end "-"; + + function "-" + (Left : in Integer; + Right : in Fraction) + return Fraction is + begin + return Reduce + (Left * Right.Den - Right.Num, + Right.Den); + end "-"; + + + + + function "-" + (Right : in Fraction) + return Fraction is + begin + return (Num => - Right.Num, Den => Right.Den); + end "-"; + + + + + function "*" + (Left, Right : in Fraction) + return Fraction is + begin + return Reduce + (Left.Num * Right.Num, + Left.Den * Right.Den); + end "*"; + + function "*" + (Left : in Fraction; + Right : in Integer) + return Fraction is + begin + return Reduce + (Left.Num * Right, + Right); + end "*"; + + function "*" + (Left : in Integer; + Right : in Fraction) + return Fraction is + begin + return Reduce + (Left * Right.Num, + Right.Den); + end "*"; + + + + + function "/" + (Left, Right : in Fraction) + return Fraction is + begin + return Reduce + (Left.Num * Right.Den, + Left.Den * Right.Num); + end "/"; + + function "/" + (Left : in Fraction; + Right : in Integer) + return Fraction is + begin + return Reduce + (Left.Num, + Left.Den * Right); + end "/"; + + function "/" + (Left : in Integer; + Right : in Fraction) + return Fraction is + begin + return Reduce + (Right.Num, + Left * Right.Den); + end "/"; + + function "/" + (Left, Right : in Integer) + return Fraction is + begin + return Reduce (Left, Right); + end "/"; + + + + + function "=" + (Left, Right : in Fraction) + return Boolean is + begin + return Left.Num = Right.Num and + Left.Den = Right.Den; + end "="; + + function "=" + (Left : in Fraction; + Right : in Integer) + return Boolean is + begin + return Left.Num = Right and Left.Den = 1; + end "="; + + function "=" + (Left : in Integer; + Right : in Fraction) + return Boolean is + begin + return Left = Right.Num and Right.Den = 1; + end "="; + + + + + function "<=" + (Left, Right : in Fraction) + return Boolean is + begin + return Left.Num * Right.Den <= Left.Den * Right.Num; + end "<="; + + function "<=" + (Left : in Fraction; + Right : in Integer) + return Boolean is + begin + return Left.Num <= Left.Den * Right; + end "<="; + + function "<=" + (Left : in Integer; + Right : in Fraction) + return Boolean is + begin + return Left * Right.Den <= Right.Num; + end "<="; + + + + + function "<" + (Left, Right : in Fraction) + return Boolean is + begin + return Left.Num * Right.Den < Left.Den * Right.Num; + end "<"; + + function "<" + (Left : in Fraction; + Right : in Integer) + return Boolean is + begin + return Left.Num < Left.Den * Right; + end "<"; + + function "<" + (Left : in Integer; + Right : in Fraction) + return Boolean is + begin + return Left * Right.Den < Right.Num; + end "<"; + + + + + function ">=" + (Left, Right : in Fraction) + return Boolean is + begin + return Left.Num * Right.Den >= Left.Den * Right.Num; + end ">="; + + function ">=" + (Left : in Fraction; + Right : in Integer) + return Boolean is + begin + return Left.Num >= Left.Den * Right; + end ">="; + + function ">=" + (Left : in Integer; + Right : in Fraction) + return Boolean is + begin + return Left * Right.Den >= Right.Num; + end ">="; + + + + + function ">" + (Left, Right : in Fraction) + return Boolean is + begin + return Left.Num * Right.Den > Left.Den * Right.Num; + end ">"; + + function ">" + (Left : in Fraction; + Right : in Integer) + return Boolean is + begin + return Left.Num > Left.Den * Right; + end ">"; + + function ">" + (Left : in Integer; + Right : in Fraction) + return Boolean is + begin + return Left * Right.Den > Right.Num; + end ">"; + + + + + function Numerator + (Item : in Fraction) + return Integer is + begin + return Item.Num; + end Numerator; + + function Denominator + (Item : in Fraction) + return Integer is + begin + return Item.Den; + end Denominator; + + function Floor + (Item : in Fraction) + return Integer is + begin + return Item.Num / Item.Den; + end Floor; + + function Ceiling + (Item : in Fraction) + return Integer is + begin + if Item.Num mod Item.Den = 0 then + return Item.Num / Item.Den; + else + return 1 + Item.Num / Item.Den; + end if; + end Ceiling; + + function Round + (Item : in Fraction) + return Integer is + begin + if Item.Num mod Item.Den > Standard."/" (Item.Den, 2) then + return 1 + Item.Num / Item.Den; + else + return Item.Num / Item.Den; + end if; + end Round; + + + + + function Image + (Item : in Fraction) + return String + is + use Ada.Strings; + use Ada.Strings.Fixed; + begin + return Trim (Integer'Image (Item.Num), Left) & '/' & + Trim (Integer'Image (Item.Den), Left); + end Image; + + function Value + (Item : in String) + return Fraction + is + use Ada.Strings; + use Ada.Strings.Fixed; + A, B, S : Integer; + begin + S := Index (Item, "/"); + A := Integer'Value (Item (Item'First .. S - 1)); + B := Integer'Value (Item (S + 1 .. Item'Last)); + return (Num => A, Den => B); + end Value; + + +end Rationals; + + diff --git a/src/rationals.ads b/src/rationals.ads new file mode 100644 index 0000000..03ac95e --- /dev/null +++ b/src/rationals.ads @@ -0,0 +1,218 @@ + + +package Rationals is + + + type Fraction is private; + + + + + function "+" + (Left, Right : in Fraction) + return Fraction; + + function "+" + (Left : in Fraction; + Right : in Integer) + return Fraction; + + function "+" + (Left : in Integer; + Right : in Fraction) + return Fraction; + + + + + function "-" + (Left, Right : in Fraction) + return Fraction; + + function "-" + (Left : in Fraction; + Right : in Integer) + return Fraction; + + function "-" + (Left : in Integer; + Right : in Fraction) + return Fraction; + + + + + function "-" + (Right : in Fraction) + return Fraction; + + + + + function "*" + (Left, Right : in Fraction) + return Fraction; + + function "*" + (Left : in Fraction; + Right : in Integer) + return Fraction; + + function "*" + (Left : in Integer; + Right : in Fraction) + return Fraction; + + + + + function "/" + (Left, Right : in Fraction) + return Fraction; + + function "/" + (Left : in Fraction; + Right : in Integer) + return Fraction; + + function "/" + (Left : in Integer; + Right : in Fraction) + return Fraction; + + function "/" + (Left, Right : in Integer) + return Fraction; + + + + + function "=" + (Left, Right : in Fraction) + return Boolean; + + function "=" + (Left : in Fraction; + Right : in Integer) + return Boolean; + + function "=" + (Left : in Integer; + Right : in Fraction) + return Boolean; + + + + + function "<=" + (Left, Right : in Fraction) + return Boolean; + + function "<=" + (Left : in Fraction; + Right : in Integer) + return Boolean; + + function "<=" + (Left : in Integer; + Right : in Fraction) + return Boolean; + + + + + function "<" + (Left, Right : in Fraction) + return Boolean; + + function "<" + (Left : in Fraction; + Right : in Integer) + return Boolean; + + function "<" + (Left : in Integer; + Right : in Fraction) + return Boolean; + + + + + function ">=" + (Left, Right : in Fraction) + return Boolean; + + function ">=" + (Left : in Fraction; + Right : in Integer) + return Boolean; + + function ">=" + (Left : in Integer; + Right : in Fraction) + return Boolean; + + + + + function ">" + (Left, Right : in Fraction) + return Boolean; + + function ">" + (Left : in Fraction; + Right : in Integer) + return Boolean; + + function ">" + (Left : in Integer; + Right : in Fraction) + return Boolean; + + + + + function Numerator + (Item : in Fraction) + return Integer; + + function Denominator + (Item : in Fraction) + return Integer; + + function Floor + (Item : in Fraction) + return Integer; + + function Ceiling + (Item : in Fraction) + return Integer; + + function Round + (Item : in Fraction) + return Integer; + + + + + function Image + (Item : in Fraction) + return String; + + function Value + (Item : in String) + return Fraction; + + +private + + + type Fraction is record + Num : Integer := 0; + Den : Integer := 1; + end record; + + +end Rationals; + + -- cgit