Ada Endianness浮点数/整数

时间:2018-10-09 09:04:40

标签: endianness ada

我是Ada的新开发人员,如果我不够清楚,请原谅我。 我面临一个问题,我不知道从哪里来过错。我首先解释一下上下文: 我拥有一套针对qemu(BE)的测试。我希望使用pragma Default_Scalar_Storage_Order(High_Order_First)在PC本机(x86)上执行它们。我注意到我的某些测试效果很好,但包括float在内的测试却并非如此。为简单起见,我编写了一个包含FLOAT和INT的测试。

with AUNIT.ASSERTIONS; use AUNIT.ASSERTIONS;
with BASIC_TYPES;
with BASIC_TYPES.STREAM;
with INTERFACES;
with ADA.INTEGER_TEXT_IO;
with ADA.FLOAT_TEXT_IO;
with ADA.TEXT_IO;
with STREAMS;
with SYSTEM;

package body TEST.TEST is

   function Integer2Hexa(Hex_Int : Integer; Bits_Nbr : Integer) return String is
   Hexa : String(1..Bits_Nbr);
   begin
      Ada.Integer_Text_IO.Put(Hexa,Hex_Int,16);
      return Hexa;
   end Integer2Hexa;

   function NAME (T : TEST) return AUNIT.MESSAGE_STRING is
      pragma UNREFERENCED (T);
   begin
      return AUNIT.FORMAT ("Test package");
   end NAME;

   IntegerNbr : BASIC_TYPES.INT32_T;
   FloatNbr : INTERFACES.IEEE_Float_32;

   procedure RUN_TEST (T : in out TEST) is

      PACKED_ARRAY : BASIC_TYPES.UINT8_ARRAY_NC_T (1 .. 8) := (others => 0);
      MY_STREAM    : STREAMS.STREAM_T;

      use type BASIC_TYPES.UINT8_ARRAY_NC_T;

   begin

      IntegerNbr := 479037433;
      FloatNbr := 2.0012151e+09;

      ADA.TEXT_IO.PUT_LINE ("Default bit order: " & SYSTEM.Default_Bit_Order'IMG);

      ADA.TEXT_IO.PUT_LINE ("Integer size : " & INTEGER'IMAGE (INTEGER'SIZE));

      ADA.TEXT_IO.PUT ("16#4EEE903D#"); -- 2.0012151e+09 in FLOAT BIG ENDIAN
      ADA.TEXT_IO.PUT (Integer2Hexa(Integer(IntegerNbr),32)); -- 16#1C8D87F9# in INT BIG ENDIAN
      ADA.TEXT_IO.NEW_LINE;

      -- Init the stream
      STREAMS.INIT (MY_STREAM      => MY_STREAM,
                    STREAM_ADDRESS => PACKED_ARRAY (PACKED_ARRAY'FIRST)'ADDRESS,
                    STREAM_SIZE    => PACKED_ARRAY'LENGTH);

      BASIC_TYPES.STREAM.WRITE_FLOAT_T (MY_STREAM  => MY_STREAM,
                                      ITEM       => FloatNbr,
                                      ALIGN_MODE => STREAMS.PACK);

      BASIC_TYPES.STREAM.WRITE_INT32_T (MY_STREAM  => MY_STREAM,
                                      ITEM       => IntegerNbr,
                                      ALIGN_MODE => STREAMS.PACK);


      if (not ASSERT(PACKED_ARRAY = (16#4e#,  16#ee#,  16#90#,  16#3d#,  16#1c#,  16#8d#,  16#87#,  16#f9#), "PACKED_ARRAY incorrect")) then
         for I in PACKED_ARRAY'RANGE loop
            ADA.TEXT_IO.PUT (Integer2Hexa(Integer(PACKED_ARRAY (I)),8));
         end loop;
         ADA.TEXT_IO.NEW_LINE;

      end if;

   end RUN_TEST;

end TEST.TEST;

我注意到INT的编写正确,但FLOAT并非如此(它是用Little Endian编写的)。确实在出口我应该有

16#4e#, 16#ee#, 16#90#, 16#3d#, 16#1c#, 16#8d#, 16#87#, 16#f9#

但我知道

16#3d#, 16#90#, 16#ee#, 16#4e#, 16#1c#, 16#8d#, 16#87#, 16#f9#

我使用此网站来确认结果:https://www.scadacore.com/tools/programming-calculators/online-hex-converter/

我不知道由于编译指示而导致的转换是否正确用于FLOAT。我使用PRAGMA.txt中的文本在软件包Compiler的gpr文件中调用它:pragma Default_Scalar_Storage_Order(High_Order_First);

   package Compiler is
      for Local_Configuration_Pragmas use "PRAGMAS.txt";
      for Switches ("ada") use ("-g");
   end Compiler;

问题是否出在我使用编译指示的方式上?

这是被调用的过程:

       procedure WRITE_FLOAT_T
         (MY_STREAM  : in out STREAMS.STREAM_T;
          ITEM       : in BASIC_TYPES.FLOAT_T;
          ALIGN_MODE : in STREAMS.ALIGN_MODE_T)
       is

          pragma UNREFERENCED (ALIGN_MODE);

          -- Temporary types for non pack case
          type TMP_TYPE_T is new STANDARD.FLOAT;
          for TMP_TYPE_T'VALUE_SIZE use FLOAT_T_SIZE_C;
          TMP_TYPE : TMP_TYPE_T;
          subtype BITS_FIELD_T is STREAMS.BIT_FIELD_ARR_NC_T (1 .. STREAMS.SIZE_T (FLOAT_T_SIZE_C));

          function TO_BITS_ARRAY is new UNCHECKED_CONVERSION (TMP_TYPE_T,
                                                              BITS_FIELD_T);


       begin

          -- Convert item to a temporary type
          TMP_TYPE := TMP_TYPE_T(ITEM);
          STREAMS.WRITE (MY_STREAM  => MY_STREAM,
                         DATA       => TO_BITS_ARRAY(TMP_TYPE));

       end WRITE_FLOAT_T;

   procedure WRITE (MY_STREAM : in out STREAM_T;
                    DATA      : in BIT_FIELD_ARR_NC_T) is

   begin

      if (MY_STREAM.ERROR_CODE = NO_ERROR)
        and then (MY_STREAM.WRITE_OFFSET + DATA'LENGTH - 1 <= MY_STREAM.STREAM_SIZE * 8) then

         if (MY_STREAM.WRITE_OFFSET mod 8 = 1) and then (DATA'LENGTH mod 8 = 0) then

            -- Byte mode
            WRITE_BYTES(MY_STREAM => MY_STREAM,
                        DATA      => DATA);

         else

            -- Bit mode
            WRITE_BITS(MY_STREAM => MY_STREAM,
                       DATA      => DATA);

         end if;

      elsif (MY_STREAM.ERROR_CODE = NO_ERROR) then

         -- Update ERROR_CODE on first error
         MY_STREAM.ERROR_CODE := END_ERROR;

      end if;

   end WRITE;

   procedure WRITE_BYTES (MY_STREAM : in out STREAM_T;
                          DATA      : in BIT_FIELD_ARR_NC_T) is

      BYTE_FIELD_ARR : BYTE_FIELD_ARR_NC_T (1 .. MY_STREAM.STREAM_SIZE);
      for BYTE_FIELD_ARR'ADDRESS use MY_STREAM.STREAM_ADDRESS;

      TMP_BYTE_FIELD_ARR : BYTE_FIELD_ARR_NC_T (1 .. DATA'LENGTH / 8);
      for TMP_BYTE_FIELD_ARR'ADDRESS use DATA'ADDRESS;

   begin

      -- Write byte field
      BYTE_FIELD_ARR ((MY_STREAM.WRITE_OFFSET + 7) / 8 .. (MY_STREAM.WRITE_OFFSET + 7) / 8 + (DATA'LENGTH / 8) - 1) := TMP_BYTE_FIELD_ARR;
      MY_STREAM.WRITE_OFFSET := MY_STREAM.WRITE_OFFSET + DATA'LENGTH;

   end WRITE_BYTES;

提前谢谢!

Q.Dherb

4 个答案:

答案 0 :(得分:1)

根据Scalar_Storage_Order的文档:

此实现定义的属性仅适用于数组和记录。这意味着它对标量类型(如Float或Integer)的内存布局没有影响。无论Default_Scalar_Storage_Order属性的值如何,在大字节序计算机上,16#12345678#整数将表示为12 34 56 78,在低字节序计算机上,它将表示为78 56 34 12。

对于数组,它确定每个标量分量的storage_element的顺序(通常是字节)。对于您而言,所有数组组件的大小均小于或等于存储元素,这意味着Scalar_Storage_Order子句无效。

以下是显示此子句对数组的影响的示例:

with Ada.Text_IO;
with System;
with Interfaces;
with Ada.Streams;
with Ada.Integer_Text_IO;

procedure Scalar_Storage_Element_Exemple is

   type T_U16_Arr_Le is array (Positive range <>) of Interfaces.Unsigned_16
     with Component_Size => 16, Scalar_Storage_Order => System.Low_Order_First;
   type T_U16_Arr_Be is array (Positive range <>) of Interfaces.Unsigned_16
     with Component_Size => 16, Scalar_Storage_Order => System.High_Order_First;

   type T_U8_Arr_Le is array (Positive range <>) of Interfaces.Unsigned_8
     with Component_Size => 8, Scalar_Storage_Order => System.Low_Order_First;
   type T_U8_Arr_Be is array (Positive range <>) of Interfaces.Unsigned_8
     with Component_Size => 8, Scalar_Storage_Order => System.High_Order_First;

   Arr_16_LE : T_U16_Arr_Le (1 .. 2) := (16#1234#, 16#5678#);
   Arr_16_BE : T_U16_Arr_Be (1 .. 2) := (16#1234#, 16#5678#);

   Arr_8_LE : T_U8_Arr_Le (1 .. 4) := (16#12#, 16#34#, 16#56#, 16#78#);
   Arr_8_BE : T_U8_Arr_Be (1 .. 4) := (16#12#, 16#34#, 16#56#, 16#78#);

   Sea_16_LE : Ada.Streams.Stream_Element_Array (1 .. 4) with Address => Arr_16_LE'Address;
   Sea_16_BE : Ada.Streams.Stream_Element_Array (1 .. 4) with Address => Arr_16_BE'Address;

   Sea_8_LE : Ada.Streams.Stream_Element_Array (1 .. 4) with Address => Arr_8_LE'Address;
   Sea_8_BE : Ada.Streams.Stream_Element_Array (1 .. 4) with Address => Arr_8_BE'Address;

   function byte2Hexa(byte : Integer) return String is
      Hexa : String(1..8);
   begin
      Ada.Integer_Text_IO.Put(Hexa,byte,16);
      return Hexa;
   end byte2Hexa;

begin

   for byte of Sea_16_LE loop
      Ada.Text_IO.Put(byte2Hexa(Integer(byte)));
   end loop;
   -- display 16#34#  16#12#  16#78#  16#56#
   -- each item of the array is in LE

   Ada.Text_IO.New_Line;

   for byte of Sea_16_BE loop
      Ada.Text_IO.Put(byte2Hexa(Integer(byte)));
   end loop;
   -- 16#12#  16#34#  16#56#  16#78#
   -- each item of the array is in BE

   Ada.Text_IO.New_Line;

   for byte of Sea_8_LE loop
      Ada.Text_IO.Put(byte2Hexa(Integer(byte)));
   end loop;
   -- 16#12#  16#34#  16#56#  16#78#
   -- no effect as size of component is inferior or equal to storage_element size

   Ada.Text_IO.New_Line;

   for byte of Sea_8_BE loop
      Ada.Text_IO.Put(byte2Hexa(Integer(byte)));
   end loop;
   -- 16#12#  16#34#  16#56#  16#78#
   -- no effect as size of component is inferior or equal to storage_element size

end Scalar_Storage_Element_Exemple;

您的float序列化可在您的QEMU上使用,因为您已经在使用BE。因此,Scalar_Storage_Order仅用于确认,没有作用。

它在x86上不起作用,因为本机字节序为LE,并且如前所述,BE Scalar_Storage_Order子句对所涉及的类型无效。因此最终结果是LE浮点数。

假设您使用相同的逻辑进行序列化(未提供相关代码,因此我认为它是不同的),那么Integer或Float在此处的行为应类似。

答案 1 :(得分:0)

这还不是很清楚,因为您已经包含了许多令人困惑的细节,但是我认为您正在尝试以与字节序无关的方式写入流,以便进行通信(通过网络?)在不同字节序的机器之间。

过程WRITE_FLOAT_T的问题在于它的ITEM是普通浮点数,因此Scalar_Storage_Order没有任何作用。

The way I've used Scalar_Storage_Order是要声明我要发送的记录,

type SNTP_Packet is record
   -- contents
end record
  with
    Bit_Order => System.High_Order_First,
    Scalar_Storage_Order => System.High_Order_First,
    Size => 48 * 8;
for SNTP_Packet use record
   -- placement of content
end record;

subtype Net_Packet is Ada.Streams.Stream_Element_Array (1 .. 48);
--  This is what actually gets streamed

function To_Net_Packet
is new Ada.Unchecked_Conversion (SNTP_Packet, Net_Packet);
function To_SNTP_Packet
is new Ada.Unchecked_Conversion (Net_Packet, SNTP_Packet);

您可以使用pragma Default_Scalar_Storage_Order,但是我不确定需要进行Bit_Order匹配会怎样。

或者,如果您希望能够使用例如Float'Write,您可以更改GNAT流基本类型的方式。

Ada运行时使用System.Stream_Attributess-stratt.ads文件中的软件包s-stratt.adb处理基本类型的流,并在s-stratt__xdr.adb中提供替代实现(在最新的编译器中) ;较早的编译器可能使用不同的文件名,但其中会有xdr

让编译器使用此替代版本不是很简单,但这对我有用:

  1. s-stratt__xdr.adb复制到工作目录中的s-stratt.adb

  2. 使用gnatmake -a在本地编译运行时的必要部分(-gnatpg说“为运行时编译”):

    gnatmake -a -f s-stratt.adb -gnatpg

  3. 构建程序:

    gprbuild main.adb

请注意,gprbuild不支持-a。可能可以使用项目文件来创建包含修改后的运行时组件的库。

答案 2 :(得分:0)

您试图独立于热字节序以bigendian编码数据(可能用于网络传输)。 您期望UNCHECKED_CONVERSION的两个参数都是Scalar_Storage_Order = System.High_Order_First定义的here

如果指定了相反的存储顺序,则每当读取类型为S的对象的标量分量的值时,都会首先反转封装机标量的存储元素。

您的问题来自使用旧的gcc版本。

由于Scalar_Storage_Order使用以下代码,我试图通过测试FLOAT_T。System.Default_Bit_OrderSystem.High_Order_FirstUNCHECKED_CONVERSION的转换来分解问题。

inc.ads:

with SYSTEM;

package inc is

    type BITS32_T is mod (2 ** 32);
    for BITS32_T'SIZE use 32;
    
    subtype UINT32_T is BITS32_T;
    subtype INT32_UNSIGNED_T is UINT32_T;

    type SIZE_T is new UINT32_T;

    subtype INDEX_T is SIZE_T range 1 .. SIZE_T'LAST;

    type BIT_T is mod (2 ** 1);
    for BIT_T'SIZE use 1;
    
    type BITS8_T is mod (2 ** 8);
    for BITS8_T'SIZE use 8;

    -- 64-bit signed integer
    type INT64_T is range -(2 ** (64 - 1)) .. (2 ** (64 - 1) - 1);
    for INT64_T'SIZE use 64;
    subtype INT64_SIGNED_T is INT64_T;

    type BIT_FIELD_ARR_NC_T is array (INDEX_T range <>) of BIT_T;
    for BIT_FIELD_ARR_NC_T'COMPONENT_SIZE use 1;
    for BIT_FIELD_ARR_NC_T'Scalar_Storage_Order use System.High_Order_First;

--Low_Order_First
    type BYTE_FIELD_ARR_HOST_ENDIANNESS_NC_T is array (INDEX_T range <>) of BITS8_T;
    for BYTE_FIELD_ARR_HOST_ENDIANNESS_NC_T'COMPONENT_SIZE use 8;
    
    type BIT_FIELD_ARR_HOST_ENDIANNESS_NC_T is array (INDEX_T range <>) of BIT_T;
    for BIT_FIELD_ARR_HOST_ENDIANNESS_NC_T'COMPONENT_SIZE use 1;

end inc;

test_types.adb:

with inc;
with INTERFACES;
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with UNCHECKED_CONVERSION;

procedure TEST_TYPES  is
    
    longfloat : INTERFACES.IEEE_FLOAT_64 := INTERFACES.IEEE_FLOAT_64(1e11);
    
    --float64 : inc.INT64_T := 16#1122334455667788#;
    int64 : inc.INT64_T := 16#1122334455667788#;
    
    
    ---------------- TYPE used to print represnentation in memory ------------------------------
    
    subtype BYTES_ARRAY_T is inc.BYTE_FIELD_ARR_HOST_ENDIANNESS_NC_T (1 .. 8);

    -------- tableau de bits -------
    subtype BITS_FIELD_T is inc.BIT_FIELD_ARR_NC_T (1 .. 64);
    subtype BITS_FIELD_HOST_ENDIANNESS_T is inc.BIT_FIELD_ARR_HOST_ENDIANNESS_NC_T (1 .. 64);


    
    ---------------- FLOAT with BIG ENDIAN encoding ------------------------------
    type TMP_TYPE_T is new STANDARD.LONG_FLOAT;
        for TMP_TYPE_T'VALUE_SIZE use 64;
        TMP_TYPE : TMP_TYPE_T;
    function TO_BYTES_ARRAY is new UNCHECKED_CONVERSION (TMP_TYPE_T, BITS_FIELD_T);
    bytes: BITS_FIELD_T;
    ---------------- FLOAT with host ENDIANNESS ------------------------------
    function TO_BYTES_HOST_ENDIANNESS_ARRAY is new UNCHECKED_CONVERSION (TMP_TYPE_T, BITS_FIELD_HOST_ENDIANNESS_T);
    bytesNoEndian: BITS_FIELD_HOST_ENDIANNESS_T;



    ---------------- INTEGER with ENDIAN CONVERSION ------------------------------
    type TMP_Integer_T is new STANDARD.LONG_LONG_INTEGER;
        for TMP_Integer_T'VALUE_SIZE use 64;
        TMP_Integer : TMP_Integer_T; 
    function TO_BYTES_ARRAY_Integer is new UNCHECKED_CONVERSION (TMP_Integer_T, BITS_FIELD_T);
    bytes_integer: BITS_FIELD_T;    
    ---------------- INTEGER without ENDIAN CONVERSION ------------------------------
    function TO_BYTES_ARRAY_HOST_ENDIANNESS_Integer is new UNCHECKED_CONVERSION (TMP_Integer_T, BITS_FIELD_HOST_ENDIANNESS_T);
    bytes_no_endian_integer: BITS_FIELD_HOST_ENDIANNESS_T;      

    -- representation in memory
    float_rep: BYTES_ARRAY_T;
    float_bits_field_rep: BYTES_ARRAY_T;
    int_rep: BYTES_ARRAY_T;
    int_bits_field_rep: BYTES_ARRAY_T;

    for float_rep'ADDRESS use bytesNoEndian'ADDRESS;
    for float_bits_field_rep'ADDRESS use bytes'ADDRESS;
    for int_rep'ADDRESS use bytes_no_endian_integer'ADDRESS;
    for int_bits_field_rep'ADDRESS use bytes_integer'ADDRESS;
------------------ FUNCTION FROM STACKOVERFLOW-----------------------
    function byte2hexa(byte : Integer) return String is
        Hexa : String(1..8);
    begin
        Ada.Integer_Text_IO.Put(Hexa, byte, 16);
        return Hexa;
    end byte2hexa;  
    procedure array2hexa(bytes : BYTES_ARRAY_T)  is
    begin
        Ada.Integer_Text_IO.Put(Integer(bytes(1)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(2)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(3)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(4)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(5)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(6)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(7)), Base => 16);
        Ada.Integer_Text_IO.Put(Integer(bytes(8)), Base => 16);
        Ada.Text_IO.New_line;
    end array2hexa; 
begin
    -- test serialisation on float 
    TMP_TYPE := TMP_TYPE_T(longfloat);
    bytesNoEndian := TO_BYTES_HOST_ENDIANNESS_ARRAY(TMP_TYPE);
    Ada.Text_IO.Put_line("float in native endianess ");
    array2hexa(float_rep);
    Ada.Text_IO.New_line;
    
    
    Ada.Text_IO.Put_line("float into BigEndian Bit array");
    TMP_TYPE := TMP_TYPE_T(longfloat);
    bytes := TO_BYTES_ARRAY(TMP_TYPE);
    array2hexa(float_bits_field_rep);
    Ada.Text_IO.New_line;
    
    -- test serialisation on integer 
    TMP_Integer := TMP_Integer_T(int64); 
    bytes_no_endian_integer := TO_BYTES_ARRAY_HOST_ENDIANNESS_Integer(TMP_Integer);
    Ada.Text_IO.Put_line("Integer in native endianess ");
    array2hexa(int_rep);

    Ada.Text_IO.New_line;
    Ada.Text_IO.Put_line("Integer into BigEndian Bit array");
    TMP_Integer := TMP_Integer_T(int64); 
    bytes_integer := TO_BYTES_ARRAY_Integer(TMP_Integer);
    array2hexa(int_bits_field_rep);
    
end TEST_TYPES;

在我建议的代码中,问题来自于明确定义了BITS_FIELD_T'element的字节序,但未定义UNCHECKED_CONVERSION的行为(关于从Float字节序向BITS_FIELD_T字节序的转换)

令人惊讶的是,使用gcc(GCC)6.2.1 20161010(对于GNAT Pro 17.2 20170606) UNCHECKED_CONVERSION转换整数的尾数而不是浮点数:

float in native endianess
      16#0#      16#0#      16#0#     16#E8#     16#76#     16#48#     16#37#     16#42#

float into BigEndian Bit array
      16#0#      16#0#      16#0#     16#E8#     16#76#     16#48#     16#37#     16#42#

Integer in native endianess
     16#88#     16#77#     16#66#     16#55#     16#44#     16#33#     16#22#     16#11#

Integer into BigEndian Bit array
     16#11#     16#22#     16#33#     16#44#     16#55#     16#66#     16#77#     16#88#

但带有gcc(GCC)7.3.1 20181018(适用于GNAT Pro 20.0w 20181017) 浮点值被核心交换:

float in native endianess
      16#0#      16#0#      16#0#     16#E8#     16#76#     16#48#     16#37#     16#42#

float into BigEndian Bit array
     16#42#     16#37#     16#48#     16#76#     16#E8#      16#0#      16#0#      16#0#

一种解决方案(适用于旧编译器)是在UNCHECKED_CONVERSION之前通过中间的BigEndian结构:


procedure WRITE_LONG_FLOAT_T
     (MY_STREAM  : in out STREAMS.STREAM_T;
      ITEM       : in BASIC_TYPES.LONG_FLOAT_T;
      ALIGN_MODE : in STREAMS.ALIGN_MODE_T)
   is
   
      pragma UNREFERENCED (ALIGN_MODE);

      -- Temporary types for non pack case
      type TMP_TYPE_T is new STANDARD.LONG_FLOAT;
      for TMP_TYPE_T'VALUE_SIZE use LONG_FLOAT_T_SIZE_C;
      TMP_TYPE : TMP_TYPE_T;
      subtype BITS_FIELD_T is STREAMS.BIT_FIELD_ARR_NC_T (1 .. STREAMS.SIZE_T (LONG_FLOAT_T_SIZE_C));

      function TO_BITS_ARRAY is new UNCHECKED_CONVERSION (TMP_TYPE_T,
                                                          BITS_FIELD_T);

      type ITEM_ENDIAN_T is
         record
            TMP_TYPE_ENDIAN : TMP_TYPE_T;
         end record;
      for ITEM_ENDIAN_T'Bit_Order use System.High_Order_First;
      for ITEM_ENDIAN_T'Scalar_Storage_Order use System.High_Order_First;
      ITEM_ENDIAN : ITEM_ENDIAN_T;

      --subtype LONG_FLOAT_TO_ARRAY_T is PUS.TYPES.BYTE_FIELD_NC_T (1 .. 8);
      function TO_BITS_ARRAY_ENDIAN is new UNCHECKED_CONVERSION (ITEM_ENDIAN_T, BITS_FIELD_T);

   begin
   
      
      -- Convert item to a temporary type
      TMP_TYPE := TMP_TYPE_T(ITEM);
      ITEM_ENDIAN.TMP_TYPE_ENDIAN := TMP_TYPE;


      STREAMS.WRITE (MY_STREAM  => MY_STREAM,
                     --DATA       => TO_BITS_ARRAY(TMP_TYPE));
                     DATA       => TO_BITS_ARRAY_`enter code here`ENDIAN(ITEM_ENDIAN));
   
   end WRITE_LONG_FLOAT_T;

答案 3 :(得分:0)

一种方法(或另一种思路...)是使用IEEE 754表示法包:http://www.dmitry-kazakov.de/ada/components.htm#IEEE_754

在这里完成了这些软件包的字节序中立使用:http://excel-writer.sf.net/