Ada中的任意长度整数

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:我选择不使用递归,因为我想在这个练习中探索循环。但请在代码的所有方面(风格、最佳实践、错误等)发表评论。

3个回答

9

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

您可以使用AdaCore Libre网站上的当前GNAT编译器编译该库。

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

最后,我将为您提供一个小例子,演示如何从LibAdaCrypt中相乘两个512位的Big_Numbers。

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;

最好的问候, 克里斯蒂安

非常感谢!这比我期望的回答要详细得多...我会去查看一下。 - Arne
很好的回答,Christian。我已经验证了你的额外网页并将它们转换为链接。希望我的点赞可以为你走出不受信任的新手区提供帮助。 - T.E.D.

2
据我所知,每个Ada编译器都内置了任意长度算术运算。这是为了支持命名数字(无类型数值常量)的定义方式。
鉴于此,遗憾的是标准没有为我们用户提供对该功能的标准访问。然而,适用于编译器需要的用途和适用于一般用途的用途可能经常是两回事。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接