2009-08-20 18 views
6

Attualmente mi sto insegnando Ada e anche se potrei iniziare affrontando alcuni dei problemi più convenzionali per iniziare.Numero intero di lunghezza arbitraria in Ada

In particolare, provo a calcolare il fattoriale n !, mentre n> 100. La mia applicazione finora è:

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; 

Il problema è, ovviamente, che anche Long_Long_Integer è troppo piccolo può per questo e genera un'eccezione CONTRAINT_ERROR per n> 20.

Esiste un pacchetto che implementa numeri interi di dimensioni arbitrarie?

Grazie!

PS: Ho optato contro la ricorsione perché volevo esplorare i loop in questo esercizio. In caso contrario, si prega di commentare tutti gli aspetti del codice (stile, best-practice, errore ..)

risposta

8

La libreria Ada Crypto supporta grandi numeri senza segno (Big_Numbers). È possibile scaricare lib da http://sourceforge.net/projects/libadacrypt-dev/. Ti consiglio di controllare lo svn. La funzione di moltiplicazione Big_Numbers della versione corrente presenta un bug secondario.

È possibile compilare la lib con il compilatore GNAT corrente da the AdaCore Libre site.

La libreria lib non verrà compilata con gcc-4.3 o gcc-4.4 a causa di a bug in gcc.

Infine, vi darò un piccolo esempio di come moltiplicare due Big_Numbers 512 bit da 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 
+0

grazie mille! Questa è molto più di una risposta di quanto speravo di ottenere .. Vado a dare un'occhiata. – Arne

+0

Buona risposta, Christian. Sono andato avanti e ho verificato le tue pagine web extra e le ho trasformate in link per te. Speriamo che i 10 punti extra della mia upvote ti aiuteranno a spingerti fuori dalla terra di noob inaffidabile prima. –

1

Da quanto ho capito, ogni compilatore Ada è dotato di arbitraria lunghezza aritmetica built-in. È necessario supportare i numeri nominati (costanti numeriche senza tipo) nel modo in cui la lingua li ha definiti.

Considerato ciò, è un vero peccato che lo standard non abbia fornito agli utenti l'accesso standard a tale struttura. Quindi, di nuovo, utilizzabile per ciò che serve al compilatore e utilizzabile per l'uso generale potrebbe spesso essere due cose diverse.

Problemi correlati