Ada 不同环境下的不同标量范围

Ada 不同环境下的不同标量范围,ada,Ada,如何在第一个状态下表示具有完整标量范围的数据,然后在使用相同内存空间的情况下在下一个状态中将其表示为0到1 任何解决问题的方法都是值得赞赏的,如果解决方案需要更改示例程序,则示例程序不必如此 例子 从文件中读取值,然后对其进行规范化Float_数组用于直接来自文件的任意范围的原始值。 功能\u数组用于标准化值 type Float\u数组是Float的数组(整数范围); 类型特征是新的浮动范围0.0。。1.0; 类型特征_数组是特征的数组(整数范围); 第一步是将浮点读入Float\u数组,并

如何在第一个状态下表示具有完整标量范围的数据,然后在使用相同内存空间的情况下在下一个状态中将其表示为0到1

任何解决问题的方法都是值得赞赏的,如果解决方案需要更改示例程序,则示例程序不必如此

例子 从文件中读取值,然后对其进行规范化
Float_数组
用于直接来自文件的任意范围的原始值。
功能\u数组
用于标准化值

type Float\u数组是Float的数组(整数范围);
类型特征是新的浮动范围0.0。。1.0;
类型特征_数组是特征的数组(整数范围);
第一步是将浮点读入
Float\u数组
,并找到最大值和最小值

过程读取(名称:字符串;结果:out Float_数组;Last:out Integer;Min:out Float;Max:out Float)为
使用Ada.Text\u IO;
使用Ada.Float\u Text\u IO;
F:文件类型;
开始
打开(F,In_文件,名称);
对于结果范围循环中的I
当_文件(F)的_结束时退出;
得到(F,结果(I));
最小值:=Float'Min(最小值,结果(I));
Max:=Float'Max(Max,结果(I));
最后:=I;
端环;
关闭(F);
结束;
Float_数组
只是暂时用于读取和查找最小最大值。下一步是规范化所有值

函数规格化(值:浮点;最小、最大:浮点)返回浮点为
开始
返回值(最小值)/(最大值-最小值);
结束;
过程规格化(最小:浮点;最大:浮点;缩放:浮点;结果:输入输出浮点_数组)为
开始
对于结果循环的E
E:=标准化(E,最小值,最大值)*刻度;
端环;
结束;
标准化后,我希望将值表示为
功能\u数组

不进行范围检查的错误解决方案。 没有范围检查,因此这不是一个合适的解决方案。将值从1缩放到3不会产生范围检查错误。因此,在这一点上,如果没有范围检查,就没有点具有
功能\u数组

Last:整数;
数据:浮点数组(1..100);
Min:Float:=Float'First;
最大:浮动:=浮动的最后一次;
开始
读取(“浮点数的频率线”,数据,最后,最小值,最大值);
标准化(最小值、最大值、1.0、数据);
--标准化(最小值、最大值、3.0、数据);
声明
_特性:带有Address=>Data'Address的特性_数组(Data'Range);
开始
Put(功能);
结束;

我在数组上尝试了属性,即
的_Features'Valid,但它只对标量类型有效。用于范围检查需要额外的代码。

我想我终于明白这里需要什么了。您希望变量为规范化类型,而不是浮点数类型。(在浮动的情况下,必须不断进行数组覆盖,或者有两个变量指向同一地址)


这应该是可行的,但请记住,您必须确保Normalize的结果是有效的。

手动范围检查似乎是可行的方法。我找不到自动使用Ada范围检查的方法

手动检查浮点数组是否在范围内 这使用了。 当变量依赖于地址时,有时需要这样做。

代码
带有Ada.Text\u IO;
使用Ada.Float_Text_IO;
主要程序是
类型Float_Array是Float的数组(整数范围);
类型特征是新的浮动范围0.0。。1.0;
类型特征_数组是特征的数组(整数范围);
读取的过程(名称:字符串;结果:out Float_数组;Last:in-out整数;Min:in-out Float;Max:in-out Float)为
使用Ada.Text\u IO;
使用Ada.Float\u Text\u IO;
F:文件类型;
开始
打开(F,In_文件,名称);
环
当_文件(F)的_结束时退出;
Last:=Last+1;
Get(F,Result(Last));
跳过线(F);
最小值:=浮点最小值(最小值,结果(最后));
Max:=Float'Max(Max,Result(Last));
当Last=Result'Last时退出;
端环;
关闭(F);
结束;
函数规格化(Value:Float;Min,Max:Float)返回浮点为((Value-Min)/(Max-Min));
过程规格化(最小:浮点;最大:浮点;缩放:浮点;结果:输入输出浮点_数组)为
开始
对于结果循环的E
E:=标准化(E,最小值,最大值)*刻度;
端环;
结束;
程序Put(项目:功能_数组)为
使用Ada.Float\u Text\u IO;
使用Ada.Text\u IO;
开始
对于项目循环的E
Put(浮动(E),3,3,0);
新线;
端环;
结束;
程序Put(项目:浮点数组)为
使用Ada.Float\u Text\u IO;
使用Ada.Text\u IO;
开始
对于项目循环的E
Put(E,3,3,0);
新线;
端环;
结束;
程序读取(项目:输出特征\u数组;最后:输入输出整数)
Pre=>功能\u数组'组件\u大小=浮点\u数组'组件\u大小,

Post=>(对于项目的所有E(项目“第一个..最后一个”)=>E>=0.0和E为什么必须使用相同的内存空间?@Jacobsparrenadersen,因为我不使用未规范化的数据。使用函数而不是过程。作为一个附带问题,考虑到您对
功能的定义,您最好确保
Scale@SimonWright在示例中,我可以将Scale更改为大于1.0以尝试de自由地诱发错误或测试假阳性错误。比例可能总是会是1.0,但我把它放在那里是为了有一个更广义的规范化。解决方案不好的问题是什么?我看到的唯一问题是功能数组的无用声明和不必要的声明块(你可以简单地做put(数据)考虑到数据已经标准化……)这段代码比我的代码更有意义,但是我已经测试了它,它的结果与我的代码相同,没有范围检查。你的代码更好,
Float\u Array
应该是本地的,只在读取和规范化时暂时可见。因为我们使用Ada 2012,我们可以随时添加后条件来规范化,这将
  Last : Integer;
  The_Features : Feature_Array (1 .. 100);
  Min : Float := Float'First;
  Max : Float := Float'Last;
begin
  declare
    Data : Float_Array (The_Features'Range) with Address => The_Features'Address;
  begin
    Read ("frequency.lines_of_float", Data, Last, Min, Max);
    Normalize (Min, Max, 1.0, Data);
    -- Normalize (Min, Max, 3.0, Data);
  end;
  Put (The_Features);
A := (for all E of Item (Item'First .. Last) => E'Valid);
Assert (A, "Elements of Item is not within range.");
0.1
11.0
-3.0
Before normalization.
  0.100
 11.000
 -3.000
After normalization.
  0.221
  1.000
  0.000