我目前正在教自己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:我确实选择了反对递归,因为我想在本练习中探索循环。但否则请评论代码的所有方面(样式,最佳实践,错误..)
答案 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编译器都内置了任意长度算术。需要以语言定义的方式支持命名数字(无类型数字常量)。
鉴于此,遗憾的是标准并没有为我们提供用户对该设施的标准访问权限。然后,再次,可用于编译器需要的,并且可用于一般用途可能通常是两个不同的事情。