Reputation:
I'm trying to create a package in ADA. I have three files, adb(main program), ads(package), and adb(body package). I can not see any problems with my main and package files. However, in my body package, I have trouble in writing a function that adds the values of P1 and P2 together and then returns its value.
My main program:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Price_Handling; use Price_Handling;
procedure Test_Price_Plus is
P1, P2 : Price_Type;
begin
P1.Dollar:= 19;
P1.Cents:= 50;
P2 := (Dollar => 10, Cents=> 0);
Put("P1 is ");
Put(P1);
New_Line;
Put("P2 is ");
Put(P2);
New_Line;
Put("If we add P1 and P2, then we get: ");
Put(P1 + P2);
New_Line;
end Test_Price_Plus;
My package:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
package Price_Handling is
type Price_Type is private;
procedure Get(Item: out Price_Type);
function "+"(Left, Right: in Price_Type) return Price_Type; -- Left(Dollar), Right(Cents)
private
type Price_Type is
record
Dollar, Cents: Integer;
end record;
end Price_Handling;
My Package Body:
Package Body Price_Handling is
procedure Put(Item:in Price_Type) is
begin
Put(Item.Dollar); Put(":");
Put(Item.Cents);
end Put;
function "+"(Left, Right: in Price_Type) return Price_type is
begin
-- Need to write a function that adds P1 and P2 together and return its value
end "+";
Upvotes: 2
Views: 125
Reputation: 5031
Another approach for this problem is to convert the dollars and cents for each instance of Price_Type to a total number of cents. Simply add the two cents values then convert the result back to dollars and cents.
package Price_Handling is
type Price_Type is private;
function "+" (Left, Right : Price_Type) return Price_Type;
procedure Get(Item : out Price_type);
procedure Print(Item : in Price_Type);
private
subtype Cents_Type is Integer range 0..99;
type Price_Type is record
Dollars : Natural := 0;
Cents : Cents_Type := 0;
end record;
end Price_Handling;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
package body Price_Handling is
---------
-- "+" --
---------
function "+" (Left, Right : Price_Type) return Price_Type is
function To_Cents ( Item : Price_type) return Natural is
Temp : Natural := 100 * Item.Dollars + Item.Cents ;
begin
return Temp;
end To_Cents;
function To_Price(Item : in Natural) return Price_Type is
Dollars : Natural;
Cents : Cents_Type;
begin
Dollars := Item / 100;
Cents := Item mod 100;
return (Dollars, Cents);
end To_Price;
begin
return To_Price(To_Cents(Left) + To_Cents(Right));
end "+";
---------
-- Get --
---------
procedure Get (Item : out Price_type) is
begin
Put("Enter the dollars for the price: ");
Get(Item.Dollars);
Put("Enter the cents for the price: ");
Get(Item.Cents);
end Get;
-----------
-- Print --
-----------
procedure Print (Item : in Price_Type) is
begin
Put(Item => Item.Dollars, Width => 1);
Put (".");
if Item.Cents < 10 then
Put ("0");
end if;
Put (Item => Item.Cents, Width => 1);
end Print;
end Price_Handling;
with Price_Handling; use Price_Handling;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
P1 , P2 : Price_Type;
begin
Get(P1);
Get(P2);
Put("The sum of P1 and P2 is: ");
Print(P1 + P2);
New_Line;
end Main;
An example of executing this program produces the following output:
Enter the dollars for the price: 10
Enter the cents for the price: 41
Enter the dollars for the price: 0
Enter the cents for the price: 32
The sum of P1 and P2 is: 10.73
Another example showing proper incrementation of the dollars amount when the two cents amounts sum to more than a dollar is:
Enter the dollars for the price: 10
Enter the cents for the price: 52
Enter the dollars for the price: 3
Enter the cents for the price: 95
The sum of P1 and P2 is: 14.47
Upvotes: 1
Reputation: 3641
The easiest way for newcomers is probably just create a dummy result value and return it:
function "+"(Left, Right: in Price_Type) return Price_type is
Result : Price_Type;
begin
Result.Dollars := Left.Dollars + Right.Dollars;
Result.Cents := Left.Cents + Right.Cents;
-- If your cents are higher than 100, then we
-- need to increment dollars and adjust the cents
-- count
if Result.Cents > 99 then
Result.Dollars := Result.Dollars + 1;
Result.Cents := Result.Cents - 100;
end if;
return Result;
end "+";
However, this is really weak. Your Price_type is not design using types that can protect you from errors. If you want to leverage Ada's safety aspects, consider making a Cents subtype that restricts you to 0 to 99:
subtype Cents_Type is Natural range 0 .. 99;
That way, if you make a programming error and put in a value higher than 99 or negative, then the program will catch it and raise an exception. Same for dollars. Make a new type for non negative values:
subtype Dollars_Type is Natural;
Now update your record to use those types and also default initialize them:
type Price_Type is record
Dollars : Dollars_Type := 0;
Cents : Cents_Type := 0;
end record;
Then if you do that, you can update the + function to use a dummy variable to hold the cents in case you do go over 99 while adding them together.
function "+"(Left, Right: in Price_Type) return Price_type is
Result : Price_Type;
Cents_With_Overflow : Natural;
begin
Result.Dollars := Left.Dollars + Right.Dollars;
Cents_With_Overflow := Left.Cents + Right.Cents;
-- If your cents are higher than 100, then we
-- need to increment dollars and adjust the cents
-- count
if Cents_With_Overflow > 99 then
Result.Dollars := Result.Dollars + 1;
Result.Cents := Cents_With_Overflow - 100;
else
Result.Cents := Cents_With_Overflow;
end if;
return Result;
end "+";
Upvotes: 5