7

我目前正在自学 Ada,虽然我可以从解决一些更传统的问题开始。

更具体地说,我尝试计算阶乘 n!,而 n>100。到目前为止,我的实现是:

with Ada.Text_IO;
with Ada.Integer_Text_IO;

use Ada.Text_IO;

procedure Factorial is 
    -- define a type covering the range beginning at 1 up to which faculty is to
    -- be computed.
    subtype Argument is Long_Long_Integer range 1..100;

    -- define a type that is large enough to hold the result
    subtype Result is Long_Long_Integer range 1..Long_Long_Integer'Last;
    package Result_IO is new Ada.Text_IO.Integer_IO(Result); use Result_IO;

    -- variable holding the faculty calculated.
    fac : Result := 1;

begin
    -- loop over whole range of ARGUMENT and calculate n!
    for n in ARGUMENT loop
        fac := (fac * n);
    end loop;
end;

问题显然是即使 Long_Long_Integer 也可能太小,并且对于 n>20 会引发 CONTRAINT_ERROR 异常。

是否有实现任意大小整数的包?

谢谢!

PS:我确实选择了反对递归,因为我想在这个练习中探索循环。但除此之外,请评论代码的所有方面(样式、最佳实践、错误..)

4

3 回答 3

9

Ada Crypto 库支持大的无符号数 ( Big_Numbers)。您可以从http://sourceforge.net/projects/libadacrypt-dev/下载该库。我建议检查 svn。当前版本的 Big_Numbers 乘法函数有一个小错误。

您可以使用来自AdaCore Libre 站点的当前 GNAT 编译器编译该库。

由于 gcc 中的错误,该库将无法在 gcc-4.3 或 gcc-4.4 下编译。

最后,我会给你一个小例子,如何将 LibAdaCrypt 中的两个 512 位 Big_Number 相乘。

package Test.Big_Numbers is

with Crypto.Types.Big_Numbers;

pragma Elaborate_All(Crypto.Types.Big_Numbers);

package Big is new Crypto.Types.Big_Numbers(512);
    use Big;
    use Big.Utils;
end Test.Big_Numbers;



package body Test.Big_Numbers is

x : Big_Unsigned := To_Big_Unsigned("16#57C19F8F7866F8633AC1D25B92FC83B4#");
Y : Big_Unsigned := To_Big_Unsigned("16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60#");

x := X * Y;
Put_Line(X);

end Test.Big_Numbers;
 
此致
   基督教
于 2009-08-21T14:58:28.320 回答
2

据我所知,每个 Ada 编译器都内置了任意长度的算法。需要以语言定义它们的方式支持命名数字(无类型数字常量)。

鉴于此,遗憾的是该标准没有为我们用户提供对该设施的标准访问权限。再说一次,可用于编译器需要的东西和可用于一般用途的东西通常可能是两个不同的东西。

于 2009-08-24T18:31:12.223 回答
0

在即将发布的 Ada 202X 版本中,库包 Numerics.Big_Numbers.Big_Integers 支持使用 GNAT 处理任意整数。

ARM 中的更多信息:http:
//www.ada-auth.org/standards/2xrm/html/RM-A-5-6.html

于 2022-02-10T22:08:50.410 回答