Ada定点乘法舍入
Ada fixed-point rounding of multiplication
以下代码打印 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
。
如果我把delta改成10.0**(-5)
,就不是这样了。
所以我的问题是 "How rounding of fixed-point calculation works in this situation?"
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;
我不认为 'rounding' 是这里的问题。
你说
type T is delta 10.0**(-4) range 0.0 .. 10.0;
这意味着 (Put_Line (T'Small'Image);
) T
的最低有效位是 6.103515625E-05.
这是2的第一个二进制次幂小于delta; 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) ("for ordinary fixed point types, if the mathematical result is between two multiples of the small, it is unspecified which of the two is the result") 中的权限将其转换为 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;
以下代码打印 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
。
如果我把delta改成10.0**(-5)
,就不是这样了。
所以我的问题是 "How rounding of fixed-point calculation works in this situation?"
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;
我不认为 'rounding' 是这里的问题。
你说
type T is delta 10.0**(-4) range 0.0 .. 10.0;
这意味着 (Put_Line (T'Small'Image);
) T
的最低有效位是 6.103515625E-05.
这是2的第一个二进制次幂小于delta; 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) ("for ordinary fixed point types, if the mathematical result is between two multiples of the small, it is unspecified which of the two is the result") 中的权限将其转换为 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;