以下代码打印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
如果舍入发生在0.00035
的阈值,则平方根的相应阈值应为0.0187
。
如果我将增量更改为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;
答案 0 :(得分:8)
我认为'四舍五入'在这里不是问题。
你说
type T is delta 10.0**(-4) range 0.0 .. 10.0;
表示(Put_Line (T'Small'Image);
)T
的最低有效位为6.103515625E-05。
这是第一个比delta小2的二进制幂; ARM 3.5.9(8)仅要求它小于或等于delta。
因此,0.0191以二进制表示为312,乘以'Small
得到1.904296875E-02,其平方为3.62634658813477E-04,除以'Small
得到二进制表示为5.94140625 E + 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;