2009-08-20 66 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編譯帶有任意長度的算術內置。它需要以語言定義的方式支持命名數字(無類型數字常量)。

鑑於此,該標準沒有爲我們提供用戶對該設施的標準訪問權限。再次,可用於編譯器需要的東西,並且可用於一般用途通常可能是兩個不同的東西。