对于最后的程序,我从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在物理上是兼容的,您可以将它们作为公共类型的子类型,因为它们具有相同的delta。
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;
顺便说一句,为了消除舍入错误,我已经删除了常量中的类型。