【问题标题】:Ada fixed-point rounding of multiplication乘法的 Ada 定点舍入
【发布时间】:2018-02-06 08:57:11
【问题描述】:

以下代码打印出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;

【问题讨论】:

  • 您是否尝试过查看 Ada 参考手册?我很确定它包含一个解释。

标签: ada fixed-point


【解决方案1】:

我不认为“四舍五入”是个大问题。

你说

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) 只要求它小于或等于增量。

所以,0.0191 表示为二进制的 312,乘以 'Small 得到 1.904296875E-02,平方为 3.62634658813477E-04,再除以 'Small 得到二进制表示为 5.94140625E+00。 GNAT使用ARM 4.5.5(21)中的权限(“对于普通的定点类型,如果数学结果在small的两个倍数之间,则未指定两者中哪一个是结果”)将这个转换为5,对应3.0517578125 E-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;

【讨论】:

  • 或者使用十进制定点类型:类型T是delta 10.0 ** (-4) digits 6 range 0.0 .. 10.0;
  • 洞察力和细节。非常感谢。
猜你喜欢
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多