这篇文章链接到这个 Ada 2005 访问类型,因为使用了或多或少相似的代码。正在使用 Euler 方法求解微分方程并使用访问类型。现在我想修改代码,以便它们使用固定的小数位数,即小数点后 6 位。
主要代码为diff.adb:
with Ada.Text_IO;
with Euler;
procedure Diff is
type Real is delta 0.000001 digits 9;
type Vector is array(Integer range <>) of Real;
type Ptr is access function (X: Real; Y: Real) return Real;
package Real_IO is new Ada.Text_IO.Decimal_IO(Num => Real);
use Real_IO;
procedure Solve is new Euler(Decimal_Type => Real, Vector_Type => Vector, Function_Ptr => Ptr);
function Maths_Func(X: Real; Y: Real) return Real is
begin
return 2.0*X*Y;
end Maths_Func;
Answer: Vector(1..6);
begin
Solve(F => Maths_Func'Access, Initial_Value => 1.0, Increment => 0.1, Result => Answer);
for N in Answer'Range loop
Put(1.0 + 0.1 * Real(N-1), Exp => 0);
Put( Answer(N), Exp => 0);
Ada.Text_IO.New_Line;
end loop;
end Diff;
然后是euler.ads:
generic
type Decimal_Type is delta <> digits <>;
type Vector_Type is array(Integer range <>) of Decimal_Type;
type Function_Ptr is access function (X: Decimal_Type; Y: Decimal_Type) return Decimal_Type;
procedure Euler(
F: in Function_Ptr; Initial_Value, Increment: in Decimal_Type; Result: out Vector_Type);
和包体euler.adb
procedure Euler
(F : in Function_Ptr; Initial_Value, Increment : in Decimal_Type; Result : out Vector_Type)
is
Step : constant Decimal_Type := Increment;
Current_X : Decimal_Type := 1.0;
begin
Result (Result'First) := Initial_Value;
for N in Result'First + 1 .. Result'Last loop
Result (N) := Result (N - 1) + Step * F(Current_X, Result (N - 1));
Current_X := Current_X + Step;
end loop;
end Euler;
编译时,我收到指向 diff.adb:
的消息类型无法根据上下文确定
需要显式转换为结果类型
对于行return 2.0倍X倍Y;
也许 2.0 在这里造成了麻烦。如何将这个浮点数转换为十进制数?
我相信在 diff.adb 中,我会遇到同样的问题:
Solve(F => Maths_Func'Access, Initial_Value => 1.0, Increment => 0.1, Result => Answer);
因为它也包含浮点数。
这对我来说似乎是一个错误。它让你做
return X * Y * 2;
和return X * 2.0;
但不是任何包含 2 个乘法运算符和一个变量的表达式。另一件奇怪的事情是通常你想做return Real (Incompatibly_Typed_Variable) * X * Y;
转换不兼容的类型,但似乎也因错误而失败。看起来表情return 2.0 * Real (X * Y);
将作为解决方法。