     with BitsAKD;
     with ErroAKD;
     with FloaAKD;  use FloaAKD;
     with TextAKD;  use TextAKD;

     package body TypeAKD is
     ---------------------------------------------------------------------------
     -- Copyright (C) 1994 David Wallace Croft.  All rights reserved.
     ---------------------------------------------------------------------------

     function  "+" ( A, B : in Array_Float ) return Array_Float is
     ---------------------------------------------------------------------------
       Temp : Array_Float ( A'range );
     begin
       for index in A'range loop
	 Temp ( index ) := A ( index ) + B ( index );
       end loop;
       return Temp;
     exception
       when Constraint_Error =>
	 ErroAKD.Notify ( "TypeAKD.""+""", "Constraint_Error" );
	 raise;
     end "+";

     function  "*" ( A : in float; B : in Array_Float ) return Array_Float is
     ---------------------------------------------------------------------------
       Temp : Array_Float ( B'range );
     begin
       for index in B'range loop
	 Temp ( index ) := A * B ( index );
       end loop;
       return Temp;
     end "*";

     function  "*" ( A : in float;
		     B : in Array_Float_2 ) return Array_Float_2 is
     ---------------------------------------------------------------------------
       Temp : Array_Float_2 ( B'range ( 1 ), B'range ( 2 ) );
     begin
       for index_1 in B'range ( 1 ) loop
	 for index_2 in B'range ( 2 ) loop
	   Temp ( index_1, index_2 ) := A * B ( index_1, index_2 );
	 end loop;
       end loop;
       return Temp;
     end "*";

     function  "*" ( A : in Array_Float_2;
		     B : in Array_Float ) return Array_Float is
     ---------------------------------------------------------------------------
     Temp : Array_Float ( B'range ) := ( others => 0.0 );
     ---------------------------------------------------------------------------
     begin
       for index_1 in A'range ( 1 ) loop
	 for index_2 in A'range ( 2 ) loop
	   Temp ( index_1 ) := Temp ( index_1 )
	     + A ( index_1, index_2 ) * B ( index_2 );
	 end loop;
       end loop;
       return Temp;
     exception
       when Constraint_Error =>
	 ErroAKD.Notify ( "TypeAKD.""*"" ( Array_Float_2, Array_Float )",
	   "Constraint_Error" );
	 raise;
     end "*";

     procedure Array_Boolean_Show ( Item : in Array_Boolean ) is
     ---------------------------------------------------------------------------
     begin
       for index in Item'range loop
	 if Item ( index ) then
	   Put ( '1' );
	 else
	   Put ( '0' );
	 end if;
       end loop;
       Put_Line ( "" );
     end Array_Boolean_Show;

     function  Array_Boolean_To_Integer ( Item : in Array_Boolean )
		 return integer is
     ---------------------------------------------------------------------------
       Temp : integer := 0;
     begin
       for index in Item'range loop
	 if Item ( index ) then
	   Temp := Temp + ( 2 ** ( Item'last - index ) );
	 end if;
       end loop;
       return Temp;
     end Array_Boolean_To_Integer;

     procedure Array_Float_Show ( Item : in Array_Float ) is
     ---------------------------------------------------------------------------
     begin
       for index in Item'range loop
	 Put ( Item ( index ), 2, 2, 2 );
	 Put ( ' ' );
       end loop;
       Put_Line ( "" );
     end Array_Float_Show;

     procedure Array_Float_2_Show ( Item : in Array_Float_2 ) is
     ---------------------------------------------------------------------------
     begin
       for index1 in Item'range ( 1 ) loop
	 for index2 in Item'range ( 2 ) loop
	   Put ( Item ( index1, index2 ), 2, 2, 2 );
	   Put ( ' ' );
	 end loop;
	 Put_Line ( "" );
       end loop;
     end Array_Float_2_Show;

     procedure Boolean_Average (
		 Totals  : in out Array_Integer;
		 Current : in     Array_Boolean;
		 Count   : in     integer;
		 Average :    out Array_Boolean ) is
     ---------------------------------------------------------------------------
     begin
       for index in Totals'range loop
	 Totals ( index ) := Totals ( index ) + boolean'pos ( Current ( index));
	 Average ( index )
	   := float ( Totals ( index ) ) / float ( Count ) >= 0.5;
       end loop;
     end Boolean_Average;

     function  Int32_Stretch
		 ( IntXX    : in Int32;
		   Num_Bits : in positive
		 ) return Int32 is
     ---------------------------------------------------------------------------
     -- Stretches signed ( two's-complement ) integers of weird bit lengths
     -- to 32 bits by dropping extraneous bits and then padding it with 0's if
     -- positive or 1's if negative.  Num_Bits is from 1 to 31.
     -- Examples:
     --   Int32_Stretch ( 16#12345678#,  4 ) ==> 16#00000008# ==> 16#FFFFFFF8#
     --   Int32_Stretch ( 16#7C23BB34#, 27 ) ==> 16#0423BB34# ==> 16#FC23BB34#
     ---------------------------------------------------------------------------
       Temp     :          Int32 := IntXX;
       Mask     : constant Int32 := ( 2 ** Num_Bits ) - 1;
       Sign_Bit : constant Int32 := 2 ** ( Num_Bits - 1 );
     begin
       Temp := BitsAKD."And" ( Temp, Mask );
       if BitsAKD."And" ( Temp, Sign_Bit ) = Sign_Bit then
	 Temp := BitsAKD."Or" ( Temp, BitsAKD."Not" ( Mask ) );
       end if;
       return Temp;
     end Int32_Stretch;

     function  Uns32_To_Float ( Unsigned_Int32 : in Int32 ) return float is
     ---------------------------------------------------------------------------
     -- Converts an unsigned 32-bit integer ( 0..(2**32)-1 ) to a float without
     -- making it negative if it is between 2**31 and (2**32)-1.
     ---------------------------------------------------------------------------
     begin
       if Unsigned_Int32 < 0 then -- if between 2**31 and (2**32)-1 then...
	 return ( 2.0 ** 32 ) - float ( abs ( Unsigned_Int32 ) );
       else
	 return float ( Unsigned_Int32 );
       end if;
     end Uns32_To_Float;


     ---------------------------------------------------------------------------
     ---------------------------------------------------------------------------
     end TypeAKD;
