home *** CD-ROM | disk | FTP | other *** search
- {
- Definitions for GNU multiple precision functions: arithmetic with
- integer, rational and real numbers of arbitrary size and precision.
-
- Translation of the C header (gmp.h) of the GMP library. Tested with
- GMP 2.0.2 and 3.0.1.
-
- To use the GMP unit, you will need the GMP library which can be
- found in ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/ .
-
- Copyright (C) 1998-2001 Free Software Foundation, Inc.
-
- Author: Frank Heckenbach <frank@pascal.gnu.de>
-
- This file is part of GNU Pascal.
-
- GNU Pascal is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU Pascal is distributed in the hope that it will be useful,
- but WITHOUT 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
- along with GNU Pascal; see the 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 you link this file with files compiled
- with a GNU compiler to produce an executable, this does not 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 General
- Public License.
-
- Please also note the license of the GMP library.
- }
-
- {$gnu-pascal,B-,I-}
- {$if __GPC_RELEASE__ < 20000412}
- {$error This unit requires GPC release 20000412 or newer.}
- {$endif}
- {$nested-comments}
-
- { If this define is set, routines new in GMP 3.x will be made
- available. The define will have no effect on the other interface
- changes between GMP 2.x and 3.x, i.e. the other routines will work
- correctly even if this define is set incorrectly, except on 64 bit
- machines, Crays and other systems where the types are different
- between the GMP versions. Otherwise, the only possible problem if
- setting the define while using GMP 2.x are linking errors if you
- actually use any of the new routines. }
- {$ifndef HAVE_GMP2}
- {$define HAVE_GMP3}
- {$endif}
-
- unit gmp;
-
- interface
-
- uses GPC;
-
- {$if defined (__mips) && defined (_ABIN32) && defined (HAVE_GMP3)}
- { Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI permits. }
- {$define _LONG_LONG_LIMB}
- {$endif}
-
- type
- {$ifdef _SHORT_LIMB}
- mp_limb_t = Cardinal;
- mp_limb_signed_t = Integer;
- {$elif defined (_LONG_LONG_LIMB)}
- mp_limb_t = LongCard;
- mp_limb_signed_t = LongInt;
- {$else}
- mp_limb_t = MedCard;
- mp_limb_signed_t = MedInt;
- {$endif}
-
- mp_ptr = ^mp_limb_t;
-
- {$if defined (_CRAY) && !defined (_CRAYMPP) && defined (HAVE_GMP3)}
- mp_size_t = Integer;
- mp_exp_t = Integer;
- {$else}
- mp_size_t = MedInt;
- mp_exp_t = MedInt;
- {$endif}
-
- mpz_t = record
- mp_alloc,
- mp_size : {$if defined (__MP_SMALL__) && defined (HAVE_GMP3)}
- ShortInt
- {$else}
- Integer
- {$endif};
- mp_d : mp_ptr
- end;
-
- mpz_array_ptr = ^mpz_array;
- mpz_array = array [0 .. MaxVarSize div SizeOf (mpz_t)] of mpz_t;
-
- mpq_t = record
- mp_num,
- mp_den : mpz_t
- end;
-
- mpf_t = record
- mp_prec,
- mp_size : Integer;
- mp_exp : mp_exp_t;
- mp_d : mp_ptr
- end;
-
- TAllocFunction = function (Size : SizeType) : Pointer;
- TReAllocFunction = function (var Dest : Pointer; OldSize, NewSize : SizeType) : Pointer;
- TDeAllocProcedure = procedure (Src : Pointer; Size : SizeType);
-
- procedure mp_set_memory_functions (AllocFunction : TAllocFunction;
- ReAllocFunction : TReAllocFunction;
- DeAllocProcedure : TDeAllocProcedure); asmname '__gmp_set_memory_functions';
-
- function mp_bits_per_limb : Integer; asmname '_p_mp_bits_per_limb';
-
- {**************** Integer (i.e. Z) routines. ****************}
-
- procedure mpz_init (var Dest : mpz_t); asmname '__gmpz_init';
- procedure mpz_clear (var Dest : mpz_t); asmname '__gmpz_clear';
- function mpz_realloc (var Dest : mpz_t; NewAlloc : mp_size_t) : Pointer; asmname '__gmpz_realloc';
- procedure mpz_array_init (Dest : mpz_array_ptr; ArraySize, FixedNumBits : mp_size_t); asmname '__gmpz_array_init';
-
- procedure mpz_set (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_set';
- procedure mpz_set_ui (var Dest : mpz_t; Src : MedCard); asmname '__gmpz_set_ui';
- procedure mpz_set_si (var Dest : mpz_t; Src : MedInt); asmname '__gmpz_set_si';
- procedure mpz_set_d (var Dest : mpz_t; Src : Double); asmname '__gmpz_set_d';
- procedure mpz_set_q (var Dest : mpz_t; Src : mpq_t); asmname '__gmpz_set_q';
- procedure mpz_set_f (var Dest : mpz_t; Src : mpf_t); asmname '__gmpz_set_f';
- function mpz_set_str (var Dest : mpz_t; Src : CString; Base : Integer) : Integer; asmname '__gmpz_set_str';
-
- procedure mpz_init_set (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_init_set';
- procedure mpz_init_set_ui (var Dest : mpz_t; Src : MedCard); asmname '__gmpz_init_set_ui';
- procedure mpz_init_set_si (var Dest : mpz_t; Src : MedInt); asmname '__gmpz_init_set_si';
- procedure mpz_init_set_d (var Dest : mpz_t; Src : Double); asmname '__gmpz_init_set_d';
- function mpz_init_set_str (var Dest : mpz_t; Src : CString; Base : Integer) : Integer; asmname '__gmpz_init_set_str';
-
- function mpz_get_ui (protected var Src : mpz_t) : MedCard; asmname '__gmpz_get_ui';
- function mpz_get_si (protected var Src : mpz_t) : MedInt; asmname '__gmpz_get_si';
- function mpz_get_d (protected var Src : mpz_t) : Double; asmname '__gmpz_get_d';
- { Pass nil for Dest to let the function allocate memory for it }
- function mpz_get_str (Dest : CString; Base : Integer; protected var Src : mpz_t) : CString; asmname '__gmpz_get_str';
-
- procedure mpz_add (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_add';
- procedure mpz_add_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_add_ui';
- procedure mpz_sub (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_sub';
- procedure mpz_sub_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_sub_ui';
- procedure mpz_mul (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_mul';
- procedure mpz_mul_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_mul_ui';
- procedure mpz_mul_2exp (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_mul_2exp';
- procedure mpz_neg (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_neg';
- procedure mpz_abs (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_abs';
- procedure mpz_fac_ui (var Dest : mpz_t; Src : MedCard); asmname '__gmpz_fac_ui';
-
- procedure mpz_tdiv_q (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_q';
- procedure mpz_tdiv_q_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_q_ui';
- procedure mpz_tdiv_r (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_r';
- procedure mpz_tdiv_r_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_r_ui';
- procedure mpz_tdiv_qr (var DestQ, DestR : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_qr';
- procedure mpz_tdiv_qr_ui (var DestQ, DestR : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_qr_ui';
-
- procedure mpz_fdiv_q (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_q';
- function mpz_fdiv_q_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_fdiv_q_ui';
- procedure mpz_fdiv_r (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_r';
- function mpz_fdiv_r_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_fdiv_r_ui';
- procedure mpz_fdiv_qr (var DestQ, DestR : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_qr';
- function mpz_fdiv_qr_ui (var DestQ, DestR : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_fdiv_qr_ui';
- function mpz_fdiv_ui (protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_fdiv_ui';
-
- procedure mpz_cdiv_q (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_cdiv_q';
- function mpz_cdiv_q_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_cdiv_q_ui';
- procedure mpz_cdiv_r (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_cdiv_r';
- function mpz_cdiv_r_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_cdiv_r_ui';
- procedure mpz_cdiv_qr (var DestQ, DestR : mpz_t; protected var Src1,Src2 : mpz_t); asmname '__gmpz_cdiv_qr';
- function mpz_cdiv_qr_ui (var DestQ, DestR : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_cdiv_qr_ui';
- function mpz_cdiv_ui (protected var Src1 : mpz_t; Src2:MedCard) : MedCard; asmname '__gmpz_cdiv_ui';
-
- procedure mpz_mod (var Dest : mpz_t; protected var Src1,Src2 : mpz_t); asmname '__gmpz_mod';
- procedure mpz_divexact (var Dest : mpz_t; protected var Src1,Src2 : mpz_t); asmname '__gmpz_divexact';
-
- procedure mpz_tdiv_q_2exp (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_q_2exp';
- procedure mpz_tdiv_r_2exp (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_r_2exp';
- procedure mpz_fdiv_q_2exp (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_fdiv_q_2exp';
- procedure mpz_fdiv_r_2exp (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_fdiv_r_2exp';
-
- procedure mpz_powm (var Dest : mpz_t; protected var Base, Exponent, Modulus : mpz_t); asmname '__gmpz_powm';
- procedure mpz_powm_ui (var Dest : mpz_t; protected var Base : mpz_t; Exponent : MedCard; protected var Modulus : mpz_t); asmname '__gmpz_powm_ui';
- procedure mpz_pow_ui (var Dest : mpz_t; protected var Base : mpz_t; Exponent : MedCard); asmname '__gmpz_pow_ui';
- procedure mpz_ui_pow_ui (var Dest : mpz_t; Base, Exponent : MedCard); asmname '__gmpz_ui_pow_ui';
-
- procedure mpz_sqrt (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_sqrt';
- procedure mpz_sqrtrem (var Dest, DestR : mpz_t; protected var Src : mpz_t); asmname '__gmpz_sqrtrem';
- function mpz_perfect_square_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_perfect_square_p';
-
- function mpz_probab_prime_p (protected var Src : mpz_t; Repetitions : Integer) : Integer; asmname '__gmpz_probab_prime_p';
- procedure mpz_gcd (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_gcd';
- function mpz_gcd_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_gcd_ui';
- procedure mpz_gcdext (var Dest, DestA, DestB : mpz_t; protected var SrcA, SrcB : mpz_t); asmname '__gmpz_gcdext';
- function mpz_invert (var Dest : mpz_t; protected var Src, Modulus : mpz_t) : Integer; asmname '__gmpz_invert';
- function mpz_jacobi (protected var Src1, Src2 : mpz_t) : Integer; asmname '__gmpz_jacobi';
- function mpz_legendre (protected var Src1, Src2 : mpz_t) : Integer; asmname '__gmpz_legendre';
-
- function mpz_cmp (protected var Src1, Src2 : mpz_t) : Integer; asmname '__gmpz_cmp';
- function mpz_cmp_ui (protected var Src1 : mpz_t; Src2 : MedCard) : Integer; asmname '__gmpz_cmp_ui';
- function mpz_cmp_si (protected var Src1 : mpz_t; Src2 : MedInt) : Integer; asmname '__gmpz_cmp_si';
- function mpz_sgn (protected var Src : mpz_t) : Integer;
-
- procedure mpz_and (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_and';
- procedure mpz_ior (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_ior';
- procedure mpz_com (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_com';
- function mpz_popcount (protected var Src : mpz_t) : MedCard; asmname '__gmpz_popcount';
- function mpz_hamdist (protected var Src1, Src2 : mpz_t) : MedCard; asmname '__gmpz_hamdist';
- function mpz_scan0 (protected var Src : mpz_t; StartingBit : MedCard) : MedCard; asmname '__gmpz_scan0';
- function mpz_scan1 (protected var Src : mpz_t; StartingBit : MedCard) : MedCard; asmname '__gmpz_scan1';
- procedure mpz_setbit (var Dest : mpz_t; BitIndex : MedCard); asmname '__gmpz_setbit';
- procedure mpz_clrbit (var Dest : mpz_t; BitIndex : MedCard); asmname '__gmpz_clrbit';
-
- procedure mpz_random (var Dest : mpz_t; MaxSize : mp_size_t); asmname '__gmpz_random';
- procedure mpz_random2 (var Dest : mpz_t; MaxSize : mp_size_t); asmname '__gmpz_random2';
- function mpz_sizeinbase (protected var Src : mpz_t; Base : Integer) : SizeType; asmname '__gmpz_sizeinbase';
-
- {**************** Rational (i.e. Q) routines. ****************}
-
- procedure mpq_canonicalize (var Dest : mpq_t); asmname '__gmpq_canonicalize';
-
- procedure mpq_init (var Dest : mpq_t); asmname '__gmpq_init';
- procedure mpq_clear (var Dest : mpq_t); asmname '__gmpq_clear';
- procedure mpq_set (var Dest : mpq_t; protected var Src : mpq_t); asmname '__gmpq_set';
- procedure mpq_set_z (var Dest : mpq_t; protected var Src : mpz_t); asmname '__gmpq_set_z';
- procedure mpq_set_ui (var Dest : mpq_t; Nom, Den : MedCard); asmname '__gmpq_set_ui';
- procedure mpq_set_si (var Dest : mpq_t; Nom : MedInt; Den : MedCard); asmname '__gmpq_set_si';
-
- procedure mpq_add (var Dest : mpq_t; protected var Src1, Src2 : mpq_t); asmname '__gmpq_add';
- procedure mpq_sub (var Dest : mpq_t; protected var Src1, Src2 : mpq_t); asmname '__gmpq_sub';
- procedure mpq_mul (var Dest : mpq_t; protected var Src1, Src2 : mpq_t); asmname '__gmpq_mul';
- procedure mpq_div (var Dest : mpq_t; protected var Src1, Src2 : mpq_t); asmname '__gmpq_div';
- procedure mpq_neg (var Dest : mpq_t; protected var Src : mpq_t); asmname '__gmpq_neg';
- procedure mpq_inv (var Dest : mpq_t; protected var Src : mpq_t); asmname '__gmpq_inv';
-
- function mpq_cmp (protected var Src1, Src2 : mpq_t) : Integer; asmname '__gmpq_cmp';
- function mpq_cmp_ui (protected var Src1 : mpq_t; Nom2, Den2 : MedCard) : Integer; asmname '__gmpq_cmp_ui';
- function mpq_sgn (protected var Src : mpq_t) : Integer;
- function mpq_equal (protected var Src1, Src2 : mpq_t) : Integer; asmname '__gmpq_equal';
-
- function mpq_get_d (protected var Src : mpq_t) : Double; asmname '__gmpq_get_d';
- procedure mpq_set_num (var Dest : mpq_t; protected var Src : mpz_t); asmname '__gmpq_set_num';
- procedure mpq_set_den (var Dest : mpq_t; protected var Src : mpz_t); asmname '__gmpq_set_den';
- procedure mpq_get_num (var Dest : mpz_t; protected var Src : mpq_t); asmname '__gmpq_get_num';
- procedure mpq_get_den (var Dest : mpz_t; protected var Src : mpq_t); asmname '__gmpq_get_den';
-
- {**************** Float (i.e. R) routines. ****************}
-
- procedure mpf_set_default_prec (Precision : MedCard); asmname '__gmpf_set_default_prec';
- procedure mpf_init (var Dest : mpf_t); asmname '__gmpf_init';
- procedure mpf_init2 (var Dest : mpf_t; Precision : MedCard); asmname '__gmpf_init2';
- procedure mpf_clear (var Dest : mpf_t); asmname '__gmpf_clear';
- procedure mpf_set_prec (var Dest : mpf_t; Precision : MedCard); asmname '__gmpf_set_prec';
- function mpf_get_prec (protected var Src : mpf_t) : MedCard; asmname '__gmpf_get_prec';
- procedure mpf_set_prec_raw (var Dest : mpf_t; Precision : MedCard); asmname '__gmpf_set_prec_raw';
-
- procedure mpf_set (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_set';
- procedure mpf_set_ui (var Dest : mpf_t; Src : MedCard); asmname '__gmpf_set_ui';
- procedure mpf_set_si (var Dest : mpf_t; Src : MedInt); asmname '__gmpf_set_si';
- procedure mpf_set_d (var Dest : mpf_t; Src : Double); asmname '__gmpf_set_d';
- procedure mpf_set_z (var Dest : mpf_t; protected var Src : mpz_t); asmname '__gmpf_set_z';
- procedure mpf_set_q (var Dest : mpf_t; protected var Src : mpq_t); asmname '__gmpf_set_q';
- function mpf_set_str (var Dest : mpf_t; Src : CString; Base : Integer) : Integer; asmname '__gmpf_set_str';
-
- procedure mpf_init_set (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_init_set';
- procedure mpf_init_set_ui (var Dest : mpf_t; Src : MedCard); asmname '__gmpf_init_set_ui';
- procedure mpf_init_set_si (var Dest : mpf_t; Src : MedInt); asmname '__gmpf_init_set_si';
- procedure mpf_init_set_d (var Dest : mpf_t; Src : Double); asmname '__gmpf_init_set_d';
- function mpf_init_set_str (var Dest : mpf_t; Src : CString; Base : Integer) : Integer; asmname '__gmpf_init_set_str';
-
- function mpf_get_d (protected var Src : mpf_t) : Double; asmname '__gmpf_get_d';
- { Pass nil for Dest to let the function allocate memory for it }
- function mpf_get_str (Dest : CString; var Exponent : mp_exp_t; Base : Integer;
- NumberOfDigits : SizeType; protected var Src : mpf_t) : CString; asmname '__gmpf_get_str';
-
- procedure mpf_add (var Dest : mpf_t; protected var Src1, Src2 : mpf_t); asmname '__gmpf_add';
- procedure mpf_add_ui (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_add_ui';
- procedure mpf_sub (var Dest : mpf_t; protected var Src1, Src2 : mpf_t); asmname '__gmpf_sub';
- procedure mpf_ui_sub (var Dest : mpf_t; Src1 : MedCard; protected var Src2 : mpf_t); asmname '__gmpf_ui_sub';
- procedure mpf_sub_ui (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_sub_ui';
- procedure mpf_mul (var Dest : mpf_t; protected var Src1, Src2 : mpf_t); asmname '__gmpf_mul';
- procedure mpf_mul_ui (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_mul_ui';
- procedure mpf_div (var Dest : mpf_t; protected var Src1, Src2 : mpf_t); asmname '__gmpf_div';
- procedure mpf_ui_div (var Dest : mpf_t; Src1 : MedCard; protected var Src2 : mpf_t); asmname '__gmpf_ui_div';
- procedure mpf_div_ui (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_div_ui';
- procedure mpf_sqrt (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_sqrt';
- procedure mpf_sqrt_ui (var Dest : mpf_t; Src : MedCard); asmname '__gmpf_sqrt_ui';
- procedure mpf_neg (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_neg';
- procedure mpf_abs (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_abs';
- procedure mpf_mul_2exp (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_mul_2exp';
- procedure mpf_div_2exp (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_div_2exp';
-
- function mpf_cmp (protected var Src1, Src2 : mpf_t) : Integer; asmname '__gmpf_cmp';
- function mpf_cmp_si (protected var Src1 : mpf_t; Src2 : MedInt) : Integer;
- function mpf_cmp_ui (protected var Src1 : mpf_t; Src2 : MedCard) : Integer;
- function mpf_eq (protected var Src1, Src2 : mpf_t; NumberOfBits : MedCard) : Integer; asmname '__gmpf_eq';
- procedure mpf_reldiff (var Dest : mpf_t; protected var Src1, Src2 : mpf_t); asmname '__gmpf_reldiff';
- function mpf_sgn (protected var Src : mpf_t) : Integer;
-
- procedure mpf_random2 (var Dest : mpf_t; MaxSize : mp_size_t; MaxExp : mp_exp_t); asmname '__gmpf_random2';
-
- {$if 0} (*@@ commented out because they use C file pointers *)
- function mpz_inp_str (var Dest : mpz_t; Src : CFilePtr; Base : Integer) : SizeType; asmname '__gmpz_inp_str';
- function mpz_inp_raw (var Dest : mpz_t; Src : CFilePtr) : SizeType ; asmname '__gmpz_inp_raw';
- function mpz_out_str (Dest : CFilePtr; Base : Integer; protected var Src : mpz_t) : SizeType; asmname '__gmpz_out_str';
- function mpz_out_raw (Dest : CFilePtr; protected var Src : mpz_t) : SizeType ; asmname '__gmpz_out_raw';
- (*@@ mpf_out_str has a bug in GMP 2.0.2: it writes a spurious #0 before the exponent for negative numbers*)
- function mpf_out_str (Dest : CFilePtr; Base : Integer; NumberOfDigits : SizeType; protected var Src : mpf_t) : SizeType; asmname '__gmpf_out_str';
- function mpf_inp_str (var Dest : mpf_t; Src : CFilePtr; Base : Integer) : SizeType; asmname '__gmpf_inp_str';
- {$endif}
-
- { New declarations in GMP 3.x. @@ Mostly untested! }
- {$ifdef HAVE_GMP3}
-
- { Available random number generation algorithms. }
- type
- gmp_randalg_t = (GMPRandAlgLC { Linear congruential. });
-
- const
- GMPRandAlgDefault = GMPRandAlgLC;
-
- { Linear congruential data struct. }
- type
- gmp_randata_lc = record
- a : mpz_t; { Multiplier. }
- c : MedCard; { Adder. }
- m : mpz_t; { Modulus (valid only if m2exp = 0). }
- m2exp : MedCard; { If <> 0, modulus is 2 ^ m2exp. }
- end;
-
- type
- gmp_randstate_t = record
- Seed : mpz_t; { Current seed. }
- Alg : gmp_randalg_t; { Algorithm used. }
- AlgData : record { Algorithm specific data. }
- case gmp_randalg_t of
- GMPRandAlgLC : (lc : ^gmp_randata_lc); { Linear congruential. }
- end
- end;
-
- procedure gmp_randinit (var State : gmp_randstate_t; Alg : gmp_randalg_t; ...); asmname '__gmp_randinit';
- procedure gmp_randinit_lc (var State : gmp_randstate_t; A : mpz_t; C : MedCard; M : mpz_t); asmname '__gmp_randinit_lc';
- procedure gmp_randinit_lc_2exp (var State : gmp_randstate_t; A : mpz_t; C : MedCard; M2Exp : MedCard); asmname '__gmp_randinit_lc_2exp';
- procedure gmp_randseed (var State : gmp_randstate_t; Seed : mpz_t); asmname '__gmp_randseed';
- procedure gmp_randseed_ui (var State : gmp_randstate_t; Seed : MedCard); asmname '__gmp_randseed_ui';
- procedure gmp_randclear (var State : gmp_randstate_t); asmname '__gmp_randclear';
-
- procedure mpz_addmul_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_addmul_ui';
- procedure mpz_bin_ui (var Dest : mpz_t; protected var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_bin_ui';
- procedure mpz_bin_uiui (var Dest : mpz_t; Src1, Src2 : MedCard); asmname '__gmpz_bin_uiui';
- function mpz_cmpabs (protected var Src1, Src2 : mpz_t) : Integer; asmname '__gmpz_cmpabs';
- function mpz_cmpabs_ui (protected var Src1 : mpz_t; Src2 : MedCard) : Integer; asmname '__gmpz_cmpabs_ui';
- procedure mpz_dump (protected var Src : mpz_t); asmname '__gmpz_dump';
- procedure mpz_fib_ui (var Dest : mpz_t; Src : MedCard); asmname '__gmpz_fib_ui';
- function mpz_fits_sint_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_sint_p';
- function mpz_fits_slong_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_slong_p';
- function mpz_fits_sshort_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_sshort_p';
- function mpz_fits_uint_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_uint_p';
- function mpz_fits_ulong_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_ulong_p';
- function mpz_fits_ushort_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_fits_ushort_p';
- procedure mpz_lcm (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_lcm';
- procedure mpz_nextprime (var Dest : mpz_t; protected var Src : mpz_t); asmname '__gmpz_nextprime';
- function mpz_perfect_power_p (protected var Src : mpz_t) : Integer; asmname '__gmpz_perfect_power_p';
- function mpz_remove (var Dest : mpz_t; protected var Src1, Src2 : mpz_t) : MedCard; asmname '__gmpz_remove';
- function mpz_root (var Dest : mpz_t; protected var Src : mpz_t; N : MedCard) : Integer; asmname '__gmpz_root';
- procedure mpz_rrandomb (var ROP : mpz_t; var State : gmp_randstate_t; N : MedCard); asmname '__gmpz_rrandomb';
- procedure mpz_swap (var v1, v2 : mpz_t); asmname '__gmpz_swap';
- function mpz_tdiv_ui (protected var Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_tdiv_ui';
- function mpz_tstbit (protected var Src1 : mpz_t; Src2 : MedCard) : Integer; asmname '__gmpz_tstbit';
- procedure mpz_urandomb (ROP : mpz_t; var State : gmp_randstate_t; N : MedCard); asmname '__gmpz_urandomb';
- procedure mpz_urandomm (ROP : mpz_t; var State : gmp_randstate_t; N : mpz_t); asmname '__gmpz_urandomm';
- procedure mpz_xor (var Dest : mpz_t; protected var Src1, Src2 : mpz_t); asmname '__gmpz_xor';
-
- procedure mpq_set_d (var Dest : mpq_t; Src : Double); asmname '__gmpq_set_d';
-
- procedure mpf_ceil (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_ceil';
- procedure mpf_floor (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_floor';
- procedure mpf_pow_ui (var Dest : mpf_t; protected var Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_pow_ui';
- procedure mpf_trunc (var Dest : mpf_t; protected var Src : mpf_t); asmname '__gmpf_trunc';
- procedure mpf_urandomb (ROP : mpf_t; var State : gmp_randstate_t; N : MedCard); asmname '__gmpf_urandomb';
-
- const
- GMPErrorNone = 0;
- GMPErrorUnsupportedArgument = 1;
- GMPErrorDivisionByZero = 2;
- GMPErrorSqrtOfNegative = 4;
- GMPErrorInvalidArgument = 8;
- GMPErrorAllocate = 16;
-
- var
- gmp_errno : Integer; asmname '__gmp_errno'; external;
-
- {$endif}
-
- { Extensions to the GMP library, implemented in this unit }
-
- procedure mpf_exp (var Dest : mpf_t; protected var Src : mpf_t);
- procedure mpf_ln (var Dest : mpf_t; protected var Src : mpf_t);
- procedure mpf_pow (var Dest : mpf_t; protected var Src1, Src2 : mpf_t);
- procedure mpf_arctan (var c : mpf_t; protected var x : mpf_t);
- procedure mpf_pi (var c : mpf_t);
-
- implementation
-
- {$L gmpc.c, gmp}
-
- (*@@ Should rather be inline and in the interface*)
-
- function mpz_sgn (protected var Src : mpz_t) : Integer;
- begin
- if Src.mp_size < 0 then
- mpz_sgn := -1
- else if Src.mp_size > 0 then
- mpz_sgn := 1
- else
- mpz_sgn := 0
- end;
-
- function mpq_sgn (protected var Src : mpq_t) : Integer;
- begin
- if Src.mp_num.mp_size < 0 then
- mpq_sgn := -1
- else if Src.mp_num.mp_size > 0 then
- mpq_sgn := 1
- else
- mpq_sgn := 0
- end;
-
- function mpf_sgn (protected var Src : mpf_t) : Integer;
- begin
- if Src.mp_size < 0 then
- mpf_sgn := -1
- else if Src.mp_size > 0 then
- mpf_sgn := 1
- else
- mpf_sgn := 0
- end;
-
- (*@@ GMP 2.0.2 has a bug in mpf_cmp_si and mpf_cmp_ui, so work around :-( *)
-
- function mpf_cmp_si (protected var Src1 : mpf_t; Src2 : MedInt) : Integer;
- var Temp : mpf_t;
- begin
- mpf_init_set_si (Temp, Src2);
- mpf_cmp_si := mpf_cmp (Src1, Temp);
- mpf_clear (Temp)
- end;
-
- function mpf_cmp_ui (protected var Src1 : mpf_t; Src2 : MedCard) : Integer;
- var Temp : mpf_t;
- begin
- mpf_init_set_ui (Temp, Src2);
- mpf_cmp_ui := mpf_cmp (Src1, Temp);
- mpf_clear (Temp)
- end;
-
- inline function GetExp (protected var x : mpf_t) = Exp : mp_exp_t;
- (*@@ This is a kludge, but how to get the exponent (of base 2) in a better way? *)
- begin
- Dispose (mpf_get_str (nil, Exp, 2, 0, x))
- end;
-
- procedure mpf_exp (var Dest : mpf_t; protected var Src : mpf_t);
- { $$ \exp x = \sum_{n = 0}^{\infty} \frac{x^n}{n!} $$
- The series is used for $x \in [0, 1]$, other values of $x$ are scaled. }
- var
- y, s, c0 : mpf_t;
- Precision, n : MedCard;
- Exp, i : mp_exp_t;
- Negative : Boolean;
- begin
- Precision := mpf_get_prec (Dest);
- mpf_init2 (y, Precision);
- mpf_set (y, Src);
- mpf_set_ui (Dest, 1);
- Negative := mpf_sgn (y) < 0;
- if Negative then mpf_neg (y, y);
- Exp := GetExp (y);
- if Exp > 0 then mpf_div_2exp (y, y, Exp);
- mpf_init2 (c0, Precision);
- mpf_init2 (s, Precision);
- mpf_set_ui (s, 1);
- n := 1;
- repeat
- mpf_mul (s, s, y);
- mpf_div_ui (s, s, n);
- mpf_set (c0, Dest);
- mpf_add (Dest, Dest, s);
- Inc (n)
- until mpf_eq (c0, Dest, Precision) <> 0;
- for i := 1 to Exp do mpf_mul (Dest, Dest, Dest);
- if Negative then mpf_ui_div (Dest, 1, Dest);
- mpf_clear (s);
- mpf_clear (c0);
- mpf_clear (y)
- end;
-
- procedure mpf_ln (var Dest : mpf_t; protected var Src : mpf_t);
- { $$ \ln x = \sum_{n = 1}^{\infty} - \frac{(1-x)^n}{n}, \quad x \in ]0, 2] \Rightarrow $$
- $$ \ln 2^i y = -i \ln \frac{1}{2} + \sum_{n = 1}^{\infty} - \frac{(1-y)^n}{n},
- \quad y \in \left[ \frac{1}{2}, 1 \right], i \in \mathbf{Z} $$ }
- var
- y, s, p, c0, Half : mpf_t;
- LnHalf : static mpf_t;
- LnHalfInited : static Boolean = False;
- n, Precision : MedCard;
- Exp : mp_exp_t;
- Dummy : Double;
- begin
- if mpf_sgn (Src) <= 0 then
- begin
- Dummy := Ln (0); { Generate an error }
- Exit
- end;
- Precision := mpf_get_prec (Dest);
- mpf_init2 (y, Precision);
- mpf_set (y, Src);
- mpf_set_ui (Dest, 0);
- Exp := GetExp (y);
- if Exp <> 0 then
- begin
- if not LnHalfInited or (mpf_get_prec (LnHalf) < Precision) then
- begin
- if LnHalfInited then mpf_clear (LnHalf);
- mpf_init2 (LnHalf, Precision);
- mpf_init2 (Half, Precision);
- mpf_set_d (Half, 0.5);
- mpf_ln (LnHalf, Half);
- mpf_clear (Half)
- end;
- mpf_set (Dest, LnHalf);
- mpf_mul_ui (Dest, Dest, abs (Exp));
- if Exp > 0
- then
- begin
- mpf_neg (Dest, Dest);
- mpf_div_2exp (y, y, Exp)
- end
- else mpf_mul_2exp (y, y, - Exp)
- end;
- mpf_ui_sub (y, 1, y);
- mpf_init2 (c0, Precision);
- mpf_init2 (s, Precision);
- mpf_init2 (p, Precision);
- mpf_set_si (p, -1);
- n := 1;
- repeat
- mpf_mul (p, p, y);
- mpf_div_ui (s, p, n);
- mpf_set (c0, Dest);
- mpf_add (Dest, Dest, s);
- Inc (n)
- until mpf_eq (c0, Dest, Precision) <> 0;
- mpf_clear (p);
- mpf_clear (s);
- mpf_clear (c0);
- mpf_clear (y)
- end;
-
- procedure mpf_pow (var Dest : mpf_t; protected var Src1, Src2 : mpf_t);
- var Temp : mpf_t;
- begin
- mpf_init2 (Temp, mpf_get_prec (Src1));
- mpf_ln (Temp, Src1);
- mpf_mul (Temp, Temp, Src2);
- mpf_exp (Dest, Temp);
- mpf_clear (Temp)
- end;
-
- procedure mpf_arctan (var c : mpf_t; protected var x : mpf_t);
- { $$\arctan x = \sum_{n=0}^{\infty} (-1)^n \frac{x^{2n+1}}{2n+1}$$ }
- var
- p, mx2, c0, s : mpf_t;
- Precision, n : MedCard;
- begin
- Precision := mpf_get_prec (c);
- mpf_init2 (p, Precision);
- mpf_set (p, x);
- mpf_init2 (mx2, Precision);
- mpf_mul (mx2, x, x);
- mpf_neg (mx2, mx2);
- mpf_init2 (c0, Precision);
- mpf_init2 (s, Precision);
- mpf_set (c, x);
- n := 1;
- repeat
- mpf_mul (p, p, mx2);
- mpf_div_ui (s, p, 2 * n + 1);
- mpf_set (c0, c);
- mpf_add (c, c, s);
- Inc (n)
- until mpf_eq (c0, c, Precision) <> 0;
- mpf_clear (s);
- mpf_clear (c0);
- mpf_clear (mx2);
- mpf_clear (p)
- end;
-
- procedure mpf_pi (var c : mpf_t);
- { 4 arctan 1/5 - arctan 1/239 = pi/4 }
- var b : mpf_t;
- begin
- mpf_set_ui (c, 1);
- mpf_div_ui (c, c, 5);
- mpf_arctan (c, c);
- mpf_mul_ui (c, c, 4);
- mpf_init2 (b, mpf_get_prec (c));
- mpf_set_ui (b, 1);
- mpf_div_ui (b, b, 239);
- mpf_arctan (b, b);
- mpf_sub (c, c, b);
- mpf_mul_ui (c, c, 4);
- mpf_clear (b)
- end;
-
- end.
-