Ada中的任意长度整数

时间:2009-08-20 22:34:10

标签: ada

我目前正在教自己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:我确实选择了反对递归,因为我想在本练习中探索循环。但否则请评论代码的所有方面(样式,最佳实践,错误..)

2 个答案:

答案 0 :(得分:8)

Ada Crypto Library支持大型无符号数字(Big_Numbers)。你可以下载 来自http://sourceforge.net/projects/libadacrypt-dev/的lib。 我建议查看svn。 Big_Numbers乘法函数 当前版本有一个小错误。

您可以使用the AdaCore Libre site中的当前GNAT编译器编译lib。

由于a bug in gcc,lib不会在gcc-4.3或gcc-4.4下编译。

最后,我将给你一个小例子如何乘以两个512位Big_Numbers 来自LibAdaCrypt。

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;
 
Best regards
   Christian

答案 1 :(得分:1)

从我收集的内容来看,每个Ada编译器都内置了任意长度算术。需要以语言定义的方式支持命名数字(无类型数字常量)。

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