2009-08-20 91 views
6

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

回答

8

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

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

由于a bug in gcc,lib不会在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; 
 
Best regards 
    Christian 
+0

非常感谢!这是比我希望得到的更多的答案..我会检查出来。 – Arne 2009-08-22 21:59:36

+0

好的答案,基督徒。我继续并验证了您的额外网页,并将它们转换为适合您的链接。希望从我的upvote中得到额外的10分会帮助你更快地从不受信任的noob地区驱逐出去。 – 2009-08-24 17:39:03

1

从我所收集,每一个Ada编译带有任意长度的算术内置。它需要以语言定义的方式支持命名数字(无类型数字常量)。

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