Common Ada Averaging Function

I have a function that averages a specific numerical value from an array of records. This value is either a natural or enumerated type delta. I am summarizing these values ​​correctly, but my question is: how to get the length of an array into a common type so that it can divide both integers and delta types?

+4
source share
3 answers

Your record array uses the Length attribute; this has the advantage of always working, even if your borders are somewhat odd, for example -18..3, or listing, for example, cheeses .. fruits.

Sort of:

Function Average( Input : In Array_of_Records ) Return float is -- You say you already have a summation function, so... Sum : Natural:= Summation( Input ); Begin Return Sum / Input'Length; End Average; 

You may need to convert the numeric types by specifying Float (Sum) or the like, since Ada does not do automatic “promotions” types.

+3
source

It has some flaws in it, but is it closer to what you wanted?

NWS.

 with Ada.Text_Io; procedure Main is generic type Element_T is private; Zero : Element_T; One : Element_T; type Vec_T is array (Integer range <>) of Element_T; with function "+"(Left, Right : in Element_T) return Element_T is <>; with function "/"(Left, Right : in Element_T) return Element_T is <>; package Arrayops is function Sum (Vec : in Vec_T) return Element_T; function Count (Vec : in Vec_T) return Element_T; function Average (Vec : in Vec_T) return Element_T; end Arrayops; package body Arrayops is function Sum (Vec : in Vec_T) return Element_T is S : Element_T := Zero; begin for I in Vec'First .. Vec'Last loop S := S + Vec(I); end loop; return S; end Sum; function Count (Vec : in Vec_T) return Element_T is C : Element_T := Zero; begin for I in Vec'First .. Vec'Last loop C := C + One; end loop; return C; end Count; function Average (Vec : in Vec_T) return Element_T is S : constant Element_T := Sum (Vec); Len : constant Element_T := Count (Vec); begin return S / Len; end Average; end Arrayops; type Fl_Arr_T is array (Integer range <>) of Float; package Fl_Arr is new Arrayops (Element_T => Float, Zero => 0.0, One => 1.0, Vec_T => Fl_Arr_T); type Int_Arr_T is array (Integer range <>) of Integer; package Int_Arr is new Arrayops (Element_T => Integer, Zero => 0, One => 1, Vec_T => Int_Arr_T); My_Ints : constant Int_Arr_T (1 .. 5) := (6,7,5,1,2); My_Floats : constant Fl_Arr_T (1 .. 7) := (6.1,7.2,5.3,1.4,2.5,8.7,9.7); Int_Sum : constant Integer := Int_Arr.Sum (My_Ints); Int_Count : constant Integer := Int_Arr.Count (My_Ints); Int_Avg : constant Integer := Int_Arr.Average (My_Ints); Float_Sum : constant Float := Fl_Arr.Sum (My_Floats); Float_Count : constant Float := Fl_Arr.Count (My_Floats); Float_Avg : constant Float := Fl_Arr.Average (My_Floats); begin Ada.Text_Io.Put_Line ("Integers => Sum: " & Integer'Image (Int_Sum) & ", Count: " & Integer'Image (Int_Count) & ", Avg: " & Integer'Image (Int_Avg)); Ada.Text_Io.Put_Line ("Floats => Sum: " & Float'Image (Float_Sum) & ", Count: " & Float'Image (Float_Count) & ", Avg: " & Float'Image (Float_Avg)); end Main; 

Result:

Integers => Sum: 21, Number: 5, Average: 4

Floats => Sum: 4.09000E + 01, Count: 7.00000E + 00, Avg: 5.84286E + 00

+3
source

The extension on Shark8 is a bit here ...

Ada allows you to declare array types without restriction. Sort of

 type Array_of_Records is array (Natural range <>) of My_Record; 

Gives you a type that you can use for record arrays with start and end indexes of arrays that can be in any range of Natural .

One of the great things I can do with this type is to use it as a subroutine parameter, for example:

 function Sum (Vector : in Array_of_Records) return Natural; 

OK, so inside this procedure, how do I know where the boundaries of the array are? Using attributes, for example:

 for index in Vector'first..Vector'last loop 

or

 for index in Vector'range loop 

Of course, for this to work, you must pass an array of size to your class. Assume that this is not what you have. Suppose you instead have a huge array (kind of buffer), and not all values ​​are valid? Well, you keep track of the actual values ​​and skip only those using the slice.

 Rec_Buffer : Array_of_Records (1..10_000); Last_Valid_Rec : Natural := 0; .... --// Rec_Buffer gets loaded with 2,128 values or something. We pass it into Sum --// like so: Ada.Text_IO ("Sum of vector is " & natural'image(Sum (Rec_Buffer (1..Last_Valid_Rec)); 

(warning - not compiled code)

+1
source

Source: https://habr.com/ru/post/1342545/


All Articles