My assignment is to create a subprogram that takes in 3 float values in returns the median of those 3 float values as an integer using if statements. I´ve tried a couple of ways to write this if statement but it just gives me a random value back of those 3 values I put in. My code:
function Median(Fl1, Fl2, Fl3: in Float) return Integer is
begin
if Fl3 >= Fl1 then
if Fl1 >= Fl2 then
return Integer(Fl1);
else
return Integer(Fl2);
end if;
elsif Fl1 >= Fl3 then
if Fl3 >= Fl2 then
return Integer(Fl3);
else
return Integer(Fl2);
end if;
elsif Fl2 >= Fl3 then
if Fl3 >= Fl1 then
return Integer(Fl3);
else
return Integer(Fl1);
end if;
end if;
end Median;
How can I rewrite this to work?
CodePudding user response:
As this is not coursework, here is the short solution that combines a few conditional statements with one use of Float'Min and one use of Float'Max. I've inserted some "null" branches to explain the logic and renamed the parameters to IMO make for easier reading.
function Median (A, B, C : in Float) return Integer is
X : Float;
-- This will be the median.
begin
X := Float'Min (B, C);
if A <= X then
-- The smallest value is A, so the median is the
-- smaller of B and C, which is already in X.
null;
else
-- The smallest value is not A.
X := Float'Max (B, C);
if A >= X then
-- The largest value is A, so the median is the
-- larger of B and C, which is already in X.
null;
else
-- The A parameter is neither the smallest nor
-- the largest value, so it is the median.
X := A;
end if;
end if;
return Integer (X);
end Median;
I agree with Simon that using 'Min and 'Max may be considered out of bounds if one interprets the problem statement very strictly. But of course each use of 'Min or 'Max can easily be replaced with a conditional expression.
CodePudding user response:
You need to find the minimum and maximum values. The one value which is neither the minimum or the maximum will be the median value.
Note that converting the median value to an integer means this function cannot distinguish between a list of values such as 1.2, 1.1, 1.3. The result will be 1, no matter which value the function chooses.
The following example uses if statements and loops to arrive at the answer.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
procedure Main is
function Median (Fl1, Fl2, Fl3 : in Float) return Integer is
type fl_status is record
Value : Float;
Is_Median : Boolean := True;
end record;
Status_List : array (1 .. 3) of fl_status;
Max : Float := Float'Max (Fl1, Float'Max (Fl2, Fl3));
Min : Float := Float'Min (Fl1, Float'Min (Fl2, Fl3));
Result : Integer;
begin
Status_List (1) := (Fl1, True);
Status_List (2) := (Fl2, True);
Status_List (3) := (Fl3, True);
-- mark the maximum value as not the median
for I in Status_List'Range loop
if Status_List (I).Value = Max then
Status_List (I).Is_Median := False;
exit;
end if;
end loop;
-- mark the minimum value as not the median
for I in Status_List'Range loop
if Status_List (I).Value = Min then
Status_List (I).Is_Median := False;
exit;
end if;
end loop;
-- Return the median value as an integer
for I in Status_List'Range loop
if Status_List (I).Is_Median then
Result := Integer (Status_List (I).Value);
exit;
end if;
end loop;
return Result;
end Median;
begin
Put_Line ("Median value is: " & Integer'Image (Median (11.1, 1.2, -1.3)));
end Main;
The value of Max is determined using the Float'Max attribute. The value of Min is determined using the Float'Min attribute. The value which is neither the min or the max is therefore the median.
NOTE: since this appeared to use too few explicit if conditions I offer a solution without the use of the 'Min and 'Max attributes.
with Ada.Text_IO; use Ada.Text_IO;
procedure Median_If is
function Median (Fl1, Fl2, Fl3 : in Float) return Integer is
type fl_status is record
Value : Float;
Is_Median : Boolean := True;
end record;
Status_List : array (1 .. 3) of fl_status;
Max : Float;
Min : Float;
Result : Integer;
begin
Status_List (1) := (Fl1, True);
Status_List (2) := (Fl2, True);
Status_List (3) := (Fl3, True);
-- find max value
if Fl1 > Fl2 and then Fl1 > Fl3 then
Max := Fl1;
elsif Fl2 > Fl1 and then Fl2 > Fl3 then
Max := Fl2;
else
Max := Fl3;
end if;
-- find min value
if Fl1 < Fl2 and then Fl1 < Fl3 then
Min := Fl1;
elsif Fl2 < Fl1 and then Fl2 < Fl3 then
Min := Fl2;
else
Min := Fl3;
end if;
-- mark the maximum value as not the median
for I in Status_List'Range loop
if Status_List (I).Value = Max then
Status_List (I).Is_Median := False;
exit;
end if;
end loop;
-- mark the minimum value as not the median
for I in Status_List'Range loop
if Status_List (I).Value = Min then
Status_List (I).Is_Median := False;
exit;
end if;
end loop;
-- Return the median value as an integer
for I in Status_List'Range loop
if Status_List (I).Is_Median then
Result := Integer (Status_List (I).Value);
exit;
end if;
end loop;
return Result;
end Median;
begin
Put_Line
("The median value is: " & Integer'Image (Median (11.0, -1.0, 1.0)));
end Median_If;
The change in this version simply uses an if/elsif logic structure replacing the 'Max and 'Min attributes.