Ada定点舍入乘法

时间:2018-02-06 08:57:11

标签: ada fixed-point

以下代码打印TRUE,表示0.0191*0.0191正在评估0.00030.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;

1 个答案:

答案 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;