------------------------------------------------------------------------------ -- -- -- G N U _ M U L T I P L E _ P R E C I S I O N . C O N T R O L L E D _ Z -- -- -- -- S p e c -- -- -- -- $Revision: 1.1 $ -- -- -- -- Copyright (C) 1999 Michael Roe -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 2, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- -- for more details. You should have received a copy of the GNU General -- -- Public License distributed with GNAT; see file COPYING. If not, write -- -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- -- MA 02111-1307, USA. -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- -- -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- Ada language binding to the GNU Multiple Precision library (GMP) -- -- -- -- This package provides facilities for doing arithmetic on integers which -- -- are too large to fit into any if the language-defined integer types. -- -- -- -- A multiple precision integer is represented by the type Big_Integer. -- -- Finalization is used to automatically allocate a free memory. -- -- -- ------------------------------------------------------------------------------ with Ada.Streams; with Ada.Finalization; with Interfaces.C; with System; with GNU_Multiple_Precision.Z; package GNU_Multiple_Precision.Controlled_Z is type Big_Integer is new Ada.Finalization.Limited_Controlled with record Value : GNU_Multiple_Precision.Z.Big_Integer; end record; procedure Initialize(Object : in out Big_Integer); procedure Finalize (Object : in out Big_Integer); ------------------------------------------------------------------------------ -- Assignment -- ------------------------------------------------------------------------------ --------- -- Set -- --------- procedure Set (Rop : in out Big_Integer; Op : in Big_Integer); -- Assign the value of Op to Rop procedure Set_Integer (Rop : in out Big_Integer; Op : in Interfaces.C.int); procedure Set_Unsigned (Rop : in out Big_Integer; Op : in Interfaces.C.unsigned); procedure Set_Double (Rop : in out Big_Integer; Op : in Interfaces.C.double); procedure Set_C_String (Rop : in out Big_Integer; Str : in Interfaces.C.char_array; Base : in Interfaces.C.int); ------------------------------------------------------------------------------ -- Type Conversion -- ------------------------------------------------------------------------------ --------- -- Get -- --------- function Get_Unsigned (Op : Big_Integer) return Interfaces.C.unsigned; function Get_Integer (Op : Big_Integer) return Interfaces.C.int; function Get_String (Buffer : System.Address; Base : Integer; Op : Big_Integer) return System.Address; ------------------------------------------------------------------------------ -- Arithmetic -- ------------------------------------------------------------------------------ -------------- -- Absolute -- -------------- -- NB: Abs is a reserved word in Ada, so cannot be a procedure name procedure Absolute (Rop : in out Big_Integer; Op : in Big_Integer); --------- -- Add -- --------- procedure Add (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure Add_Unsigned (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned_long); procedure Add (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned_long) renames Add_Unsigned; --------- -- Div -- --------- procedure Cdiv_Q (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure Cdiv_Q_Unsigned (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); procedure Cdiv_QR (Quotient, Remainder : out Big_Integer; Op1, Op2 : in Big_Integer); procedure Cdiv_QR_Unsigned (Quotient, Remainder : out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); procedure Cdiv_R (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure Cdiv_R_Unsigned (Remainder : out Interfaces.C.unsigned; Quotient : out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); function Cdiv_Unsigned (Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned) return Interfaces.C.unsigned; --------------- -- Div_Exact -- --------------- procedure Div_Exact (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); --------------- -- Factorial -- --------------- procedure Factorial (Rop : in out Big_Integer; Op : Interfaces.C.unsigned); --------- -- GCD -- --------- procedure GCD (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure GCD_Unsigned (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); procedure GCD_Extended (G, S, T : in out Big_Integer; A, B : in Big_Integer); -- In Ada, we can't pass a NULL pointer so have to resort to this trick: procedure GCD_Extended_No_T (G, S : in out Big_Integer; Dummy : System.Address; A, B : in Big_Integer); ------------ -- Invert -- ------------ procedure Invert (Return_Code : out Interfaces.C.int; Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); --------- -- Neg -- --------- procedure Negate (Rop : in out Big_Integer; Op : in Big_Integer); --------- -- Mod -- --------- -- Mod is a reserved word in Ada procedure Remainder (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); -- function Mod_Unsigned (Rop : in out Big_Integer; -- Op1, Op2 : in Big_Integer) -- return Interfaces.C.unsigned; -- pragma Import (C, Mod_Unsigned, "mpz_mod_ui"); -------------- -- Multiply -- -------------- procedure Multiply (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure Multiply_2_Exponent (Rop : in out Big_Integer; X : in Big_Integer; Exponent : in Interfaces.C.unsigned); procedure Multiply_Unsigned (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); ---------------------- -- Perfect_Square_P -- ---------------------- function Perfect_Square_P (Op : Big_Integer) return Interfaces.C.int; ----------- -- Power -- ----------- procedure Power (Rop : in out Big_Integer; Base : in Big_Integer; Exponent : in Interfaces.C.unsigned); procedure Power_Unsigned (Rop : in out Big_Integer; Base, Exponent : Interfaces.C.unsigned); procedure Power_Modulus (Rop : in out Big_Integer; Base, Exponent, Modulus : in Big_Integer); procedure Power_Modulus_Unsigned (Rop : in out Big_Integer; Base : in Big_Integer; Exponent : in Interfaces.C.unsigned; Modulus : in Big_Integer); ---------------------- -- Probable_Prime_P -- ---------------------- function Probable_Prime_P (Op : Big_Integer; Reps : Interfaces.C.int) return Interfaces.C.int; ---------- -- Sqrt -- ---------- procedure Sqrt (Rop : in out Big_Integer; Op : in Big_Integer); procedure Sqrt_Remainder (Rop1, Rop2 : in out Big_Integer; Op : in Big_Integer); --------- -- Sub -- --------- procedure Sub (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); procedure Sub_Unsigned (Rop : in out Big_Integer; Op1 : in Big_Integer; Op2 : in Interfaces.C.unsigned); ------------------------------------------------------------------------------ -- Comparison -- ------------------------------------------------------------------------------ ------------- -- Compare -- ------------- function Compare (Op1, Op2 : Big_Integer) return Integer; -- Returns a positive value if Op1 > Op2, zero if Op1 = Op2, -- and a negative value if Op1 < Op2. function Compare_Integer (X : Big_Integer; Y : Integer) return Integer; function Compare (X : Big_Integer; Y : Integer) return Integer renames Compare_Integer; function Compare_Unsigned (X : Big_Integer; Y : Interfaces.C.unsigned) return Integer; -- Don't overload both the signed and unsigned versions as 'compare', -- as this will lead to ambiguity in resolving the name ------------------------------------------------------------------------------ -- Bit Manipulation -- ------------------------------------------------------------------------------ ----------------- -- Bitwise_And -- ----------------- -- and is a reserved word in Ada, so cannot be a procedure name procedure Bitwise_And (Rop : in out Big_Integer; X, Y : in Big_Integer); ---------------- -- Bitwise_Or -- ---------------- -- or is a reserved word in Ada, so cannot be a procedure name procedure Bitwise_Or (Rop : in out Big_Integer; Op1, Op2 : in Big_Integer); ---------------- -- Complement -- ---------------- procedure Complement (Rop : in out Big_Integer; Op : in Big_Integer); -- Set Rop to the one's complement of Op ---------------------- -- Population_Count -- ---------------------- function Population_Count (Op : Big_Integer) return Interfaces.C.unsigned; -- For non-negative numbers, return the numbers of 1's bits in the twos -- complement representation of Op. For negative numbers, return MAX_ULONG ---------------------- -- Hamming_Distance -- ---------------------- function Hamming_Distance (Op1, Op2 : Big_Integer) return Interfaces.C.unsigned; -- If Op1 and Op2 are both non-negative, return the hamming distance -- between them. The behaviour in other cases depends on the version of -- the GMP library; MAX_ULONG may be returned. ----------- -- Scan0 -- ----------- function Scan0 (Op1 : Big_Integer; Starting_Bit : Interfaces.C.unsigned) return Interfaces.C.unsigned; -- Starting with Starting_Bit, search towards more significant bits -- until a zero bit is found. Return the index of the found bit. ----------- -- Scan1 -- ----------- function Scan1 (Op1 : Big_Integer; Starting_Bit : Interfaces.C.unsigned) return Interfaces.C.unsigned; -- Starting with Starting_Bit, search towards more significant bits -- until a ones bit is found. Return the index of the found bit. ------------- -- Set_Bit -- ------------- procedure Set_Bit (Rop : in out Big_Integer; Bit_Index : in Interfaces.C.unsigned); -- Set bit number Bit_Index in Rop --------------- -- Clear_Bit -- --------------- procedure Clear_Bit (Rop : in out Big_Integer; Bit : Interfaces.C.unsigned); ------------------------------------------------------------------------------ -- Miscellaneous -- ------------------------------------------------------------------------------ ------------------ -- Size_In_Base -- ------------------- function Size_In_Base (Op : Big_Integer; Base : Interfaces.C.int) return Interfaces.C.size_t; ------------ -- Random -- ------------ procedure Random (Rop : Big_Integer; Max_Size : Interfaces.C.size_t); -- Generate a random integer of size at most Max_Size. The size is -- specified in 'limbs', ie. machine words in the internal representation -- No guarantees are made about the quality of the random-number generator -- Random numbers are generated when Max_Size is negative procedure Random2 (Rop : Big_Integer; Max_Size : Interfaces.C.size_t); end GNU_Multiple_Precision.Controlled_Z;