ada - 如何在 Ada 的数学运算中使用不同的固定点类型?

标签 ada

对于最后的程序,我从 gnat 收到以下错误消息:

test2.adb:23:61: error: invalid operand types for operator "-"
test2.adb:23:61: error: left operand has type "Gain_Type" defined at line 11
test2.adb:23:61: error: right operand has type "Offset_Type" defined at line 12

不幸的是,我没有找到一个很好的例子来解决这个问题,从而为相当小的嵌入式目标生成速度优化的代码。

我觉得总是将所有内容都转换为最大的类型没有多大意义。 最好的方法是什么/是否没有关于如何有效地使用定点解决更复杂的数学问题的现有引用资料?

procedure Test2 is
   Adc_Width   : constant Positive := 10;
   Adc_Delta   : constant Float    := 2.0**(-Adc_Width);
   Adc_Mod   : constant    := 2**Adc_Width;
   Error_Delta : constant          := 2.0**(-1);
   Gain_Min    : constant Float    := 1.0 - 2.0 * Adc_Delta;
   Gain_Max    : constant Float    := 1.0 + 2.0 * Adc_Delta;
   Offset_Min  : constant Float    := -0.5 * Adc_Delta;
   Offset_Max  : constant Float    := 2.0 * Adc_Delta;
   type Gain_Type is delta Adc_Delta * Error_Delta range Gain_Min .. Gain_Max;
   type Offset_Type is
      delta Adc_Delta * Error_Delta range Offset_Min .. Offset_Max;
   type Adc_Encoded_Type is mod Adc_Mod with
      Size => 16;
   subtype Adc_Value_Type is natural range 0 .. Adc_Encoded_Type'Modulus - 1;
   type Adc_Delta_Type is delta Adc_Delta range 0.0 .. 1.0 - Adc_Delta;
   function Compensate
    (Adc : in Adc_Encoded_Type; Gain : in Gain_Type; Offset : in Offset_Type)
     return Adc_Delta_Type
   is
   begin
      return Adc_Delta_Type (((Adc_Value_Type (Adc) * Gain) - Offset) / Adc_Mod);
   end Compensate;
begin
end Test2;

最佳答案

如果 Gain_Type 和 Offset_Type 在物理上兼容,您可以使它们成为通用类型的子类型,因为它们具有相同的增量。

procedure Test2 is
   Adc_Width   : constant := 10;
   Adc_Delta   : constant := 2.0**(-Adc_Width);
   Adc_Mod     : constant := 2**Adc_Width;
   Error_Delta : constant := 2.0**(-1);
   Gain_Min    : constant := 1.0 - 2.0 * Adc_Delta;
   Gain_Max    : constant := 1.0 + 2.0 * Adc_Delta;
   Offset_Min  : constant := -0.5 * Adc_Delta;
   Offset_Max  : constant := 2.0 * Adc_Delta;
   --
   type Super_Type is delta Adc_Delta * Error_Delta range -1.0 .. 2.0;
   subtype Gain_Type   is Super_Type range Gain_Min .. Gain_Max;
   subtype Offset_Type is Super_Type range Offset_Min .. Offset_Max;
   --
   type Adc_Encoded_Type is mod Adc_Mod with
      Size => 16;
   subtype Adc_Value_Type is natural range 0 .. Adc_Encoded_Type'Modulus - 1;
   type Adc_Delta_Type is delta Adc_Delta range 0.0 .. 1.0 - Adc_Delta;
   function Compensate
    (Adc : in Adc_Encoded_Type; Gain : in Gain_Type; Offset : in Offset_Type)
     return Adc_Delta_Type
   is
   begin
      return Adc_Delta_Type (((Adc_Value_Type (Adc) * Gain) - Offset) / Adc_Mod);
   end Compensate;
begin
  null;
end Test2;

顺便说一句,为了消除舍入误差,我已经删除了常量中的类型。

关于ada - 如何在 Ada 的数学运算中使用不同的固定点类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72904568/

相关文章:

arrays - 在 SPARK 中设置前提条件检查数组元素报告 'array index check might fail'

ada - (Ada 2012) 编译时错误 "expected private type... found composite type"

string - End_Error 帮助,在 Ada 中使用无界字符串

sockets - Ada 和 Python 之间的 TCP 套接字

ada - 在Ada中使用 `limited with`来避免循环依赖

ada - 将字符串作为 Ada 中的任务创建判别式传递

c - C中的空结构

random - 在 Ada 中设置随机浮点生成的范围

ada - Ada 中的迭代器

Ada 手册 : difference between annotated and consolidated