ADA:如何指示泛型参数可以转换为Float

ADA:如何指示泛型参数可以转换为Float,ada,Ada,在本例中,我试图定义一个泛型,它接受所有数字类型,并通过两个操作创建一个pair类型:加法和浮点型标量的右乘法 Compiling: pair.ads Source file time stamp: 2021-03-10 02:36:51 Compiled at: 2021-03-09 21:36:52 1. generic 2. type T is private; 3. with function "+" (a, b : T)

在本例中,我试图定义一个泛型,它接受所有数字类型,并通过两个操作创建一个pair类型:加法和浮点型标量的右乘法

Compiling: pair.ads
Source file time stamp: 2021-03-10 02:36:51
Compiled at: 2021-03-09 21:36:52

     1. generic
     2.    type T is private;
     3.    with function "+" (a, b : T) return T is <>;
     4.
     5. package pair is
     6.     subtype T1 is T;
     7.     type P is array (1 .. 2) of T1;
     8.   
     9.     function "*" (a : T1; f : Float) return T1 is 
    10.         (T1 (Float'rounding (Float (a) * f)));
                                            |
        >>> illegal operand for numeric conversion

    11.
    12.     function "+" (a,b : P) return P is
    13.         ((a (1) + b (1), a (2) + b (2)));
    14.
    15.     function "*" (a : P; f : Float) return P is
    16.         ((a (1) * f, a (2) * f));
    17. end pair;

 17 lines: 1 error
第3行表示私有类型T具有+运算符,但我不知道如何表示T可转换为浮点,因此第10行出现错误

第二个问题是,当使用“Float”实例化时,第9行的函数变得不明确,因为类型Float已经与Float标量相乘

我该如何解决这个问题?
谢谢大家!

您的客户端必须提供将T转换为Float和将Float转换为T的函数:

   with function To_T (Value : in Float) return T;
   with function To_Float (Value : in T) return Float;
...
      To_T (To_Float (A) * F);
或者是一个函数,用于交互T和返回T的浮点:

   with function "*" (Left : in T; Right : in Float) return T;

为什么要声明子类型T1?它不会给您带来任何好处。

您的客户机必须提供将t转换为Float和将Float转换为t的函数:

   with function To_T (Value : in Float) return T;
   with function To_Float (Value : in T) return Float;
...
      To_T (To_Float (A) * F);
或者是一个函数,用于交互T和返回T的浮点:

   with function "*" (Left : in T; Right : in Float) return T;

为什么要声明子类型T1?它不会给您带来任何好处。

我通常在这种情况下使用的解决方案是,对于类型t,需要存在一个函数转换为float,比如

   with function To_Float(X : T) return Float is <>;

我想这是表示约束T必须可转换为浮点的最佳方式。

我通常在这种情况下使用的解决方案是要求T类型存在一个函数转换为浮点,类似于

   with function To_Float(X : T) return Float is <>;

我想这是表达约束T必须可转换为Float的最佳方式。

我现在更了解您想要做什么。尝试以下方法:

generic
   Num_Bits : Positive;
   type Raw_Signal is Range <>;
package pairs is
   subtype Normal_Value is Long_Float range 0.0..1.0;
   function Normalize(Value : in Raw_Signal) return Normal_Value;
end pairs;

package body pairs is

   ---------------
   -- Normalize --
   ---------------

   function Normalize (Value : in Raw_Signal) return Normal_Value is
   begin
      return Long_Float(Value) / 2.0**Num_Bits;
   end Normalize;

end pairs;

with Pairs;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   Bits : constant := 8;
   type Byte_Signal is range 0..2**Bits - 1;
   package bytes is new pairs(Num_Bits   => Bits,
                              Raw_Signal => Byte_Signal);
   use bytes;
begin
   for I in Byte_Signal'Range loop
      Put(I'Image & " : ");
      Put_Line(Normal_Value'Image(Normalize(I)));
   end loop;
   
end Main;

我现在更明白你想做什么了。尝试以下方法:

generic
   Num_Bits : Positive;
   type Raw_Signal is Range <>;
package pairs is
   subtype Normal_Value is Long_Float range 0.0..1.0;
   function Normalize(Value : in Raw_Signal) return Normal_Value;
end pairs;

package body pairs is

   ---------------
   -- Normalize --
   ---------------

   function Normalize (Value : in Raw_Signal) return Normal_Value is
   begin
      return Long_Float(Value) / 2.0**Num_Bits;
   end Normalize;

end pairs;

with Pairs;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   Bits : constant := 8;
   type Byte_Signal is range 0..2**Bits - 1;
   package bytes is new pairs(Num_Bits   => Bits,
                              Raw_Signal => Byte_Signal);
   use bytes;
begin
   for I in Byte_Signal'Range loop
      Put(I'Image & " : ");
      Put_Line(Normal_Value'Image(Normalize(I)));
   end loop;
   
end Main;

Ada是一种强类型语言。实际上,没有安全的方法将任意类型(如记录类型、数组类型或任务类型)转换为浮点。Ada语言参考手册第12.5.2节正式标量类型描述了所有正式标量类型的通用参数描述。枚举类型没有+函数,因为它们不是算术类型。你是指美国牙科协会还是老年和残疾倡导者?Ada是一个女人的名字,不是首字母缩略词。@JimRogers域是信号处理,T确实不能是任意的-理想情况下T表示一个域R或C,然后我们可以谈论代数。实际上,我们经常处理0范围内的数字。。2**n,在减法运算中甚至不闭合,例如。。。如果我不仅能限制算术类型,而且我不知道如何限制,这将有助于解决部分问题。@PolarBear2015 0..2**n范围内的数字听起来像一个模组类型。Ada使用环绕语义为此类类型定义了加法和减法。一种是硬件对这种类型的值的限制。例如,在64位体系结构上,n的最大值为64:类型T为mod 2**64@PolarBear2015模块化类型的通用形式参数为:类型T为mod;Ada是一种强类型语言。实际上,没有安全的方法将任意类型(如记录类型、数组类型或任务类型)转换为浮点。Ada语言参考手册第12.5.2节正式标量类型描述了所有正式标量类型的通用参数描述。枚举类型没有+函数,因为它们不是算术类型。你是指美国牙科协会还是老年和残疾倡导者?Ada是一个女人的名字,不是首字母缩略词。@JimRogers域是信号处理,T确实不能是任意的-理想情况下T表示一个域R或C,然后我们可以谈论代数。实际上,我们经常处理0范围内的数字。。2**n,在减法运算中甚至不闭合,例如。。。如果我不仅能限制算术类型,而且我不知道如何限制,这将有助于解决部分问题。@PolarBear2015 0..2**n范围内的数字听起来像一个模组类型。Ada使用环绕语义为此类类型定义了加法和减法。一种是硬件对这种类型的值的限制。例如,在64位体系结构上,n的最大值为64:类型T为mod 2**64@PolarBear2015模块化类型的通用形式参数为:类型T为mod;杰弗里,谢谢你,这很有帮助!关于亚型T1,我自己也不确定是否需要它,但我不想让问题过多。关于Ada不是首字母缩略词,我不是以英语为母语的人,我错过了。不幸的是,搜索引擎没有这样的区别,每当我键入Ada时,我都会在搜索结果中找到所有的首字母缩写词……杰弗里,谢谢你,这很有帮助!关于亚型T1,我自己也不确定是否需要它,但我不想让问题过多。关于Ada不是首字母缩略词,我不是以英语为母语的人,我错过了。不幸的是,搜索引擎没有这样的区别,每当我键入Ada时,我都会在搜索结果中找到所有的首字母缩写词…谢谢!,是的,这是一个非常干净的房间
我记得大约20年前解决了这个问题。我们需要从a/D转换器实现标准化浮点值,同时在a/D转换器升级到更多位(如14位a/D到16位a/D)时,使未来的维护更容易。接收标准化值的软件应该不知道硬件更改。谢谢!,是的,这是一个比我尝试做的更干净的解决方案。我记得大约20年前解决了这个问题。我们需要从a/D转换器实现标准化浮点值,同时在a/D转换器升级到更多位(如14位a/D到16位a/D)时,使未来的维护变得容易。接收标准化值的软件应该不知道硬件更改。