以下代码打印TRUE表示0.0191*0.0191正在评估0.0003并0.0192*0.0192正在评估0.0004.然而:
0.0191*0.0191 = 0.00036481
0.0192*0.0192 = 0.00036864
Run Code Online (Sandbox Code Playgroud)
如果舍入发生在阈值处0.00035,那么平方根的相应阈值应该是0.0187.
如果我将delta更改为10.0**(-5),则情况并非如此.
所以我的问题是"在这种情况下如何对定点计算进行舍入?"
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type T is delta 10.0**(-4) range 0.0 .. 10.0;
X1 : T := 0.0191;
X2 : T := 0.0192;
Y : T := 0.0004;
B : Boolean;
begin
B := (X1 * X1 = Y - T'Delta) and (X2 * X2 =Y);
Put_Line(B'Image);
end Main;
Run Code Online (Sandbox Code Playgroud)
我不认为'四舍五入'在这里是个问题.
你说
type T is delta 10.0**(-4) range 0.0 .. 10.0;
Run Code Online (Sandbox Code Playgroud)
这意味着(Put_Line (T'Small'Image);)a的最低有效位T是6.103515625E-05.
这是第一个比delta小2的二进制幂; ARM 3.5.9(8)仅要求它小于或等于delta.
因此,0.0191表示为二进制312,其乘以'Small1.904296875E-02,其平方为3.62634658813477E-04,除以'Small得到二进制表示为5.94140625E + 00.GNAT使用ARM 4.5.5(21)中的权限("对于普通的固定点类型,如果数学结果在两个小的倍数之间,则未指定两者中的哪一个是结果")将其转换为5,对应于3.0517578125E-04,在打印四舍五入时给出0.0003的结果.
0.0192以二进制表示为314,其导致6.017822265625E + 00的结果,转换为6,其对应于3.662109375E-04,四舍五入以打印至0.0004.
你会收集到我用你的代码搞砸了这些数字!
你可能想考虑一下
Delta_T : constant := 10.0 ** (-4);
type T is delta Delta_T range 0.0 .. 10.0 with Small => Delta_T;
Run Code Online (Sandbox Code Playgroud)