Home > Software engineering >  How to return the median value of 3 float values using if statements in Ada
How to return the median value of 3 float values using if statements in Ada

Time:11-29

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.

  • Related