@@ -1,1616 +1,1617 @@
- package Math::GMPz;
- use strict;
- use Math::GMPz::Random;
- require Exporter;
- *import = \&Exporter::import;
- require DynaLoader;
-
- use constant _UOK_T => 1;
- use constant _IOK_T => 2;
- use constant _NOK_T => 3;
- use constant _POK_T => 4;
- use constant _MATH_MPFR_T => 5;
- use constant _MATH_GMPf_T => 6;
- use constant _MATH_GMPq_T => 7;
- use constant _MATH_GMPz_T => 8;
- use constant _MATH_GMP_T => 9;
- use constant _MATH_MPC_T => 10;
-
-use subs qw( __GNU_MP_VERSION __GNU_MP_VERSION_MINOR __GNU_MP_VERSION_PATCHLEVEL
- __GNU_MP_RELEASE __GMP_CC __GMP_CFLAGS);
-
-use overload
- '+' => \&overload_add,
- '-' => \&overload_sub,
- '*' => \&overload_mul,
- '/' => \&overload_div,
- '+=' => \&overload_add_eq,
- '-=' => \&overload_sub_eq,
- '*=' => \&overload_mul_eq,
- '/=' => \&overload_div_eq,
- '%' => \&overload_mod,
- '%=' => \&overload_mod_eq,
- '<<' => \&overload_lshift,
- '<<=' => \&overload_lshift_eq,
- '>>' => \&overload_rshift,
- '>>=' => \&overload_rshift_eq,
- '&' => \&overload_and,
- '&=' => \&overload_and_eq,
- '|' => \&overload_ior,
- '|=' => \&overload_ior_eq,
- '^' => \&overload_xor,
- '^=' => \&overload_xor_eq,
- '~' => \&overload_com,
- '**' => \&overload_pow,
- '**=' => \&overload_pow_eq,
- 'sqrt' => \&overload_sqrt,
- '""' => \&overload_string,
- '++' => \&overload_inc,
- '--' => \&overload_dec,
- '>' => \&overload_gt,
- '>=' => \&overload_gte,
- '<' => \&overload_lt,
- '<=' => \&overload_lte,
- '<=>' => \&overload_spaceship,
- '==' => \&overload_equiv,
- '!=' => \&overload_not_equiv,
- '!' => \&overload_not,
- '=' => \&overload_copy,
- 'abs' => \&overload_abs;
-
- @Math::GMPz::EXPORT_OK = qw(
-__GNU_MP_VERSION __GNU_MP_VERSION_MINOR __GNU_MP_VERSION_PATCHLEVEL
-__GNU_MP_RELEASE __GMP_CC __GMP_CFLAGS
-Rmpz_abs Rmpz_add Rmpz_add_ui Rmpz_addmul Rmpz_addmul_ui Rmpz_and Rmpz_bin_ui
-Rmpz_bin_uiui Rmpz_cdiv_q Rmpz_cdiv_q_2exp Rmpz_cdiv_q_ui Rmpz_cdiv_qr
-Rmpz_cdiv_qr_ui Rmpz_cdiv_r Rmpz_cdiv_r_2exp Rmpz_cdiv_r_ui Rmpz_cdiv_ui
-Rmpz_clear Rmpz_clrbit Rmpz_cmp Rmpz_cmp_d Rmpz_cmp_si Rmpz_cmp_ui Rmpz_cmpabs
-Rmpz_cmpabs_d Rmpz_cmpabs_ui Rmpz_com Rmpz_combit Rmpz_congruent_2exp_p
-Rmpz_congruent_p Rmpz_congruent_ui_p Rmpz_div Rmpz_divmod Rmpz_div_ui
-Rmpz_divmod_ui Rmpz_div_2exp Rmpz_mod_2exp Rmpz_divexact Rmpz_divexact_ui
-Rmpz_divisible_2exp_p Rmpz_divisible_p Rmpz_divisible_ui_p Rmpz_even_p
-Rmpz_export Rmpz_fac_ui Rmpz_2fac_ui Rmpz_mfac_uiui Rmpz_primorial_ui
-Rmpz_fdiv_q Rmpz_fdiv_q_2exp Rmpz_fdiv_q_ui
-Rmpz_fdiv_qr Rmpz_fdiv_qr_ui Rmpz_fdiv_r Rmpz_fdiv_r_2exp Rmpz_fdiv_r_ui
-Rmpz_fdiv_ui Rmpz_fib2_ui Rmpz_fib_ui Rmpz_fits_sint_p Rmpz_fits_slong_p
-Rmpz_fits_sshort_p Rmpz_fits_uint_p Rmpz_fits_ulong_p Rmpz_fits_ushort_p
-Rmpz_fprintf Rmpz_sprintf Rmpz_snprintf
-Rmpz_gcd Rmpz_gcd_ui Rmpz_gcdext Rmpz_get_d_2exp Rmpz_get_si Rmpz_get_str
-Rmpz_get_ui Rmpz_getlimbn Rmpz_hamdist Rmpz_import Rmpz_init Rmpz_init2
-Rmpz_init2_nobless Rmpz_init_nobless Rmpz_init_set Rmpz_init_set_d
-Rmpz_init_set_d_nobless Rmpz_init_set_nobless Rmpz_init_set_si
-Rmpz_init_set_si_nobless Rmpz_init_set_str Rmpz_init_set_str_nobless
-Rmpz_init_set_ui Rmpz_init_set_ui_nobless Rmpz_inp_str Rmpz_inp_raw
-Rmpz_invert Rmpz_ior
-Rmpz_jacobi Rmpz_kronecker Rmpz_kronecker_si Rmpz_kronecker_ui Rmpz_lcm
-Rmpz_lcm_ui Rmpz_legendre Rmpz_lucnum2_ui Rmpz_lucnum_ui Rmpz_mod Rmpz_mod_ui
-Rmpz_mul Rmpz_mul_2exp Rmpz_mul_si Rmpz_mul_ui Rmpz_neg Rmpz_nextprime
-Rmpz_odd_p Rmpz_out_str Rmpz_out_raw
-Rmpz_perfect_power_p Rmpz_perfect_square_p
-Rmpz_popcount Rmpz_pow_ui Rmpz_powm Rmpz_powm_sec Rmpz_powm_ui Rmpz_printf
-Rmpz_probab_prime_p Rmpz_realloc2 Rmpz_remove Rmpz_root Rmpz_rootrem
-Rmpz_rrandomb Rmpz_scan0 Rmpz_scan1 Rmpz_set Rmpz_set_d Rmpz_set_f Rmpz_set_q
-Rmpz_set_si Rmpz_set_str Rmpz_set_ui Rmpz_setbit Rmpz_sgn Rmpz_si_kronecker
-Rmpz_size Rmpz_sizeinbase Rmpz_sqrt Rmpz_sqrtrem Rmpz_sub Rmpz_sub_ui
-Rmpz_submul Rmpz_submul_ui Rmpz_swap Rmpz_tdiv_q Rmpz_tdiv_q_2exp
-Rmpz_tdiv_q_ui Rmpz_tdiv_qr Rmpz_tdiv_qr_ui Rmpz_tdiv_r Rmpz_tdiv_r_2exp
-Rmpz_tdiv_r_ui Rmpz_tdiv_ui Rmpz_tstbit Rmpz_ui_kronecker Rmpz_ui_pow_ui
-Rmpz_ui_sub Rmpz_urandomb Rmpz_urandomm Rmpz_xor
-rand_init rand_clear
-TRmpz_out_str TRmpz_inp_str
-zgmp_randseed zgmp_randseed_ui zgmp_randclear
-zgmp_randinit_default zgmp_randinit_mt zgmp_randinit_lc_2exp zgmp_randinit_lc_2exp_size
-zgmp_randinit_set zgmp_randinit_default_nobless zgmp_randinit_mt_nobless
-zgmp_randinit_lc_2exp_nobless zgmp_randinit_lc_2exp_size_nobless zgmp_randinit_set_nobless
-zgmp_urandomb_ui zgmp_urandomm_ui
- );
- our $VERSION = '0.38';
- $VERSION = eval $VERSION;
-
- DynaLoader::bootstrap Math::GMPz $VERSION;
-
- $Math::GMPz::NULL = _Rmpz_NULL();
-
- %Math::GMPz::EXPORT_TAGS =(mpz => [qw(
-Rmpz_abs Rmpz_add Rmpz_add_ui Rmpz_addmul Rmpz_addmul_ui Rmpz_and Rmpz_bin_ui
-Rmpz_bin_uiui Rmpz_cdiv_q Rmpz_cdiv_q_2exp Rmpz_cdiv_q_ui Rmpz_cdiv_qr
-Rmpz_cdiv_qr_ui Rmpz_cdiv_r Rmpz_cdiv_r_2exp Rmpz_cdiv_r_ui Rmpz_cdiv_ui
-Rmpz_clear Rmpz_clrbit Rmpz_cmp Rmpz_cmp_d Rmpz_cmp_si Rmpz_cmp_ui Rmpz_cmpabs
-Rmpz_cmpabs_d Rmpz_cmpabs_ui Rmpz_com Rmpz_combit Rmpz_congruent_2exp_p
-Rmpz_congruent_p Rmpz_congruent_ui_p Rmpz_div Rmpz_divmod Rmpz_div_ui
-Rmpz_divmod_ui Rmpz_div_2exp Rmpz_mod_2exp Rmpz_divexact Rmpz_divexact_ui
-Rmpz_divisible_2exp_p Rmpz_divisible_p Rmpz_divisible_ui_p Rmpz_even_p
-Rmpz_export Rmpz_fac_ui Rmpz_2fac_ui Rmpz_mfac_uiui Rmpz_primorial_ui
-Rmpz_fdiv_q Rmpz_fdiv_q_2exp Rmpz_fdiv_q_ui
-Rmpz_fdiv_qr Rmpz_fdiv_qr_ui Rmpz_fdiv_r Rmpz_fdiv_r_2exp Rmpz_fdiv_r_ui
-Rmpz_fdiv_ui Rmpz_fib2_ui Rmpz_fib_ui Rmpz_fits_sint_p Rmpz_fits_slong_p
-Rmpz_fits_sshort_p Rmpz_fits_uint_p Rmpz_fits_ulong_p Rmpz_fits_ushort_p
-Rmpz_fprintf Rmpz_sprintf Rmpz_snprintf
-Rmpz_gcd Rmpz_gcd_ui Rmpz_gcdext Rmpz_get_d_2exp Rmpz_get_si Rmpz_get_str
-Rmpz_get_ui Rmpz_getlimbn Rmpz_hamdist Rmpz_import Rmpz_init Rmpz_init2
-Rmpz_init2_nobless Rmpz_init_nobless Rmpz_init_set Rmpz_init_set_d
-Rmpz_init_set_d_nobless Rmpz_init_set_nobless Rmpz_init_set_si
-Rmpz_init_set_si_nobless Rmpz_init_set_str Rmpz_init_set_str_nobless
-Rmpz_init_set_ui Rmpz_init_set_ui_nobless Rmpz_inp_str Rmpz_inp_raw
-Rmpz_invert Rmpz_ior
-Rmpz_jacobi Rmpz_kronecker Rmpz_kronecker_si Rmpz_kronecker_ui Rmpz_lcm
-Rmpz_lcm_ui Rmpz_legendre Rmpz_lucnum2_ui Rmpz_lucnum_ui Rmpz_mod Rmpz_mod_ui
-Rmpz_mul Rmpz_mul_2exp Rmpz_mul_si Rmpz_mul_ui Rmpz_neg Rmpz_nextprime
-Rmpz_odd_p Rmpz_out_str Rmpz_out_raw
-Rmpz_perfect_power_p Rmpz_perfect_square_p
-Rmpz_popcount Rmpz_pow_ui Rmpz_powm Rmpz_powm_sec Rmpz_powm_ui Rmpz_printf
-Rmpz_probab_prime_p Rmpz_realloc2 Rmpz_remove Rmpz_root Rmpz_rootrem
-Rmpz_rrandomb Rmpz_scan0 Rmpz_scan1 Rmpz_set Rmpz_set_d Rmpz_set_f Rmpz_set_q
-Rmpz_set_si Rmpz_set_str Rmpz_set_ui Rmpz_setbit Rmpz_sgn Rmpz_si_kronecker
-Rmpz_size Rmpz_sizeinbase Rmpz_sqrt Rmpz_sqrtrem Rmpz_sub Rmpz_sub_ui
-Rmpz_submul Rmpz_submul_ui Rmpz_swap Rmpz_tdiv_q Rmpz_tdiv_q_2exp
-Rmpz_tdiv_q_ui Rmpz_tdiv_qr Rmpz_tdiv_qr_ui Rmpz_tdiv_r Rmpz_tdiv_r_2exp
-Rmpz_tdiv_r_ui Rmpz_tdiv_ui Rmpz_tstbit Rmpz_ui_kronecker Rmpz_ui_pow_ui
-Rmpz_ui_sub Rmpz_urandomb Rmpz_urandomm Rmpz_xor
-rand_init rand_clear
-TRmpz_out_str TRmpz_inp_str
-zgmp_randseed zgmp_randseed_ui zgmp_randclear
-zgmp_randinit_default zgmp_randinit_mt zgmp_randinit_lc_2exp zgmp_randinit_lc_2exp_size
-zgmp_randinit_set zgmp_randinit_default_nobless zgmp_randinit_mt_nobless
-zgmp_randinit_lc_2exp_nobless zgmp_randinit_lc_2exp_size_nobless zgmp_randinit_set_nobless
-zgmp_urandomb_ui zgmp_urandomm_ui )]
-);
-
-sub dl_load_flags {0} # Prevent DynaLoader from complaining and croaking
-
-sub new {
-
- # This function caters for 2 possibilities:
- # 1) that 'new' has been called OOP style - in which
- # case there will be a maximum of 3 args
- # 2) that 'new' has been called as a function - in
- # which case there will be a maximum of 2 args.
- # If there are no args, then we just want to return an
- # initialized Math::GMPz
- if(!@_) {return Rmpz_init()}
-
- if(@_ > 3) {die "Too many arguments supplied to new()"}
-
- # If 'new' has been called OOP style, the first arg is the string
- # "Math::GMPz" which we don't need - so let's remove it. However,
- # if the first arg is a Math::GMPz object (which is a possibility),
- # then we'll get a fatal error when we check it for equivalence to
- # the string "Math::GMPz". So we first need to check that it's not
- # an object - which we'll do by using the ref() function:
- if(!ref($_[0]) && $_[0] eq "Math::GMPz") {
- shift;
- if(!@_) {return Rmpz_init()}
- }
-
- # @_ can now contain a maximum of 2 args - the value, and iff the value is
- # a string, (optionally) the base of the numeric string.
- if(@_ > 2) {die "Too many arguments supplied to new() - expected no more than two"}
-
- my ($arg1, $type, $base);
-
- # $_[0] is the value, $_[1] (if supplied) is the base of the number
- # in the string $[_0].
- $arg1 = shift;
- $base = 0;
-
- $type = _itsa($arg1);
- if(!$type) {die "Inappropriate argument supplied to new()"}
-
- # Create a Math::GMPz object that has $arg1 as its value.
- # Die if there are any additional args (unless $type == _POK_T)
- if($type == _UOK_T || $type == _IOK_T) {
- if(@_ ) {die "Too many arguments supplied to new() - expected only one"}
- return Rmpz_init_set_str($arg1, 10);
- }
-
- if($type == _NOK_T) {
- if(@_ ) {die "Too many arguments supplied to new() - expected only one"}
- if(Math::GMPz::_has_longdouble()) {
- return _Rmpz_init_set_ld($arg1);
- }
- return Rmpz_init_set_d($arg1);
-
- }
-
- if($type == _POK_T) { # POK
- if(@_ > 1) {die "Too many arguments supplied to new() - expected no more than two"}
- $base = shift if @_;
- if($base < 0 || $base == 1 || $base > 62) {die "Invalid value for base"}
- return Rmpz_init_set_str($arg1, $base);
- }
-
- if($type == _MATH_GMPz_T || $type == _MATH_GMP_T) { # Math::GMPz or Math::GMP object
- if(@_) {die "Too many arguments supplied to new() - expected only one"}
- return Rmpz_init_set($arg1);
- }
-}
-
-sub Rmpz_out_str {
- if(@_ == 2) {
- die "Inappropriate 1st arg supplied to Rmpz_out_str" if _itsa($_[0]) != _MATH_GMPz_T && _itsa($_[0]) != _MATH_GMP_T;
- return _Rmpz_out_str($_[0], $_[1]);
- }
- if(@_ == 3) {
- if(_itsa($_[0]) == _MATH_GMPz_T || _itsa($_[0]) == _MATH_GMP_T) {return _Rmpz_out_strS($_[0], $_[1], $_[2])}
- die "Incorrect args supplied to Rmpz_out_str" if _itsa($_[1]) != _MATH_GMPz_T && _itsa($_[1]) != _MATH_GMP_T;
- return _Rmpz_out_strP($_[0], $_[1], $_[2]);
- }
- if(@_ == 4) {
- die "Inappropriate 2nd arg supplied to Rmpz_out_str" if _itsa($_[1]) != _MATH_GMPz_T && _itsa($_[1]) != _MATH_GMP_T;
- return _Rmpz_out_strPS($_[0], $_[1], $_[2], $_[3]);
- }
- die "Wrong number of arguments supplied to Rmpz_out_str()";
-}
-
-sub TRmpz_out_str {
- if(@_ == 3) {
- die "Inappropriate 3rd arg supplied to TRmpz_out_str" if _itsa($_[2]) != _MATH_GMPz_T && _itsa($_[2]) != _MATH_GMP_T;
- return _TRmpz_out_str($_[0], $_[1], $_[2]);
- }
- if(@_ == 4) {
- if(_itsa($_[2]) == _MATH_GMPz_T || _itsa($_[2]) == _MATH_GMP_T) {return _TRmpz_out_strS($_[0], $_[1], $_[2], $_[3])}
- die "Incorrect args supplied to TRmpz_out_str" if _itsa($_[3]) != _MATH_GMPz_T && _itsa($_[3]) != _MATH_GMP_T;
- return _TRmpz_out_strP($_[0], $_[1], $_[2], $_[3]);
- }
- if(@_ == 5) {
- die "Inappropriate 4th arg supplied to TRmpz_out_str" if _itsa($_[3]) != _MATH_GMPz_T && _itsa($_[3]) != _MATH_GMP_T;
- return _TRmpz_out_strPS($_[0], $_[1], $_[2], $_[3], $_[4]);
- }
- die "Wrong number of arguments supplied to TRmpz_out_str()";
-}
-
-sub Rpi_x {
- Rmpz_set_ui($_[0], 1);
- Rmpz_mul_2exp($_[0], $_[0], $_[1]);
- Rmpz_tdiv_q_ui($_[0], $_[0], int(0.693147180559945 * $_[1]));
- }
-
-sub prime_ratio {
- return int($_[0] * 0.3465735902799726);
- }
-
-sub Rprovable_small {
- my $lim = 341550071728321;
- my $last = 0;
- if(Rmpz_cmp_ui($_[0], 2) < 0 || Rmpz_cmp_d($_[0], $lim) >= 0)
- {die "Argument to provable_small (= ", Rmpz_get_str($_[0], 10), " must be in range [2..341550071728321]"}
- if(Rmpz_cmp_ui($_[0], 18) < 0) {
- if(Rmpz_cmp_ui($_[0], 2) <= 0) {Rmpz_set_ui($_[0], 2)}
- if(!Rmpz_cmp_ui($_[0], 3)) {Rmpz_set_ui($_[0], 3)}
- if(Rmpz_cmp_ui($_[0], 5) <= 0) {Rmpz_set_ui($_[0], 5)}
- if(Rmpz_cmp_ui($_[0], 7) <= 0) {Rmpz_set_ui($_[0], 7)}
- if(Rmpz_cmp_ui($_[0], 11) <= 0) {Rmpz_set_ui($_[0], 11)}
- if(Rmpz_cmp_ui($_[0], 13) <= 0) {Rmpz_set_ui($_[0], 13)}
- Rmpz_set_ui($_[0], 17);
- }
-
- else {
- if(!Rmpz_tstbit($_[0], 0)) {Rmpz_add_ui($_[0], $_[0], 1)};
- while(Rmpz_cmp_d($_[0], $lim) < 0) {
- if(Rrm_gmp($_[0], 2) && Rrm_gmp($_[0], 3) && Rrm_gmp($_[0], 5) && Rrm_gmp($_[0], 7)
- && Rrm_gmp($_[0], 11) && Rrm_gmp($_[0], 13) && Rrm_gmp($_[0], 17))
- {$last = 1;
- last;
- }
- Rmpz_add_ui($_[0], $_[0], 2);
- }
- if(!$last) {Rmpz_set_ui($_[0], 0)}
- }
-
- }
-
-sub Rprime_test {
- my $ul = $_[1] + 1;
- for(2..$ul) {
- if(!Rrm_gmp($_[0], $_)) {return 0}
- }
- return 1;
- }
-
-sub Rnext_germaine_prime {
- my $last = 0;
- my @range = Rsieve_gmp($_[4], $_[5], $_[2]);
- Rmpz_set($_[0], $_[2]);
- my $sub = 0;
- my $mod;
- for(@range) {
- Rmpz_add_ui($_[0], $_[0], $_ - $sub);
- $sub = $_;
- $mod = Rmpz_tdiv_ui($_[0], 3);
- if($mod == 2) {
- if(Rprime_test($_[0], $_[3])) {
- Rmpz_mul_2exp($_[1], $_[0], 1);
- Rmpz_add_ui($_[1], $_[1], 1);
- if(Rprime_test($_[1], $_[3])) {
- $last = 1;
- last;
- }
- }
- }
- }
- if(!$last) {
- Rmpz_set_ui($_[0], 0);
- Rmpz_set_ui($_[1], 0);
- }
- }
-
-sub merten {
- my $gamma = 0.57721566490153286; # Euler's constant
- return 1 / exp($gamma) / log($_[0]);
- }
-
-sub Rgenerator_zp {
- my $s = Rmpz_sizeinbase($_[1], 2);
- my $order = Rmpz_init2($s);
- my $temp = Rmpz_init2($s);
- my $check = Rmpz_init2($s);
- Rmpz_set($order, $_[1]);
- Rmpz_sub_ui($order, $order, 1);
- Rmpz_set($check, $order);
-
- my $nok = (1,0);
- for(@{$_[2]}) {
- if(!Rmpz_divisible_ui_p($order, $_)) {$nok = 1}
- Rmpz_set_ui($temp, $_);
- Rmpz_remove($check, $check, $temp);
- }
-
- if($nok) {die "Incorrect factors supplied to 3rd argument to Rgenerator_zp() function"}
-
- if(defined($_[3])) {
- $nok = 0;
- for(@{$_[3]}) {
- if(!Rmpz_divisible_p($order, $_)) {$nok = 1}
- Rmpz_remove($check, $check, $_);
- }
- if($nok) {die "Incorrect factors supplied to 4th argument to Rgenerator_zp function"}
- }
-
- if(Rmpz_cmp_ui($check, 1)) {die "Incomplete factorisation supplied to Rgenerator_zp function"};
-
- while(1) {
- my $flag = 1;
- if(Rmpz_cmp($_[0], $order) > 0){warn "Generator greater than order. Re-setting generator %= order and continuing....";
- Rmpz_tdiv_r($_[0], $_[0], $order);
- }
- for(@{$_[2]}) {
- Rmpz_divexact_ui($temp, $order, $_);
- Rmpz_powm($check, $_[0], $temp, $_[1]);
- if(!Rmpz_cmp_ui($check, 1)) {
- $flag = 0;
- last;
- }
- }
-
- if($flag && defined($_[3])) {
- for(@{$_[3]}) {
- Rmpz_divexact($temp, $order, $_);
- Rmpz_powm($check, $_[0], $temp, $_[1]);
- if(!Rmpz_cmp_ui($check, 1)) {
- $flag = 0;
- last;
- }
- }
- }
-
- if($flag) {last}
- Rmpz_add_ui($_[0], $_[0], 1);
- }
-
-}
-
-sub Rnext_proven {
- my $s = Rmpz_sizeinbase($_[1], 2);
- my $r = Rmpz_init2($s);
- my $c = Rmpz_init2($s);
- my $two = Rmpz_init_set_ui(2);
-
- if(!defined($_[5])) {
- Rmpz_set($r, $_[1]);
- Rmpz_sub_ui($r, $r, 1);
- }
- else {Rmpz_set($r, $_[5])}
-
- while(1) {
- if($_[2]) {print STDERR "."}
- if(Rmpz_cmp_si($r, 1) < 0) {die "Failed to find next prime in Rnext_proven function"}
- Rmpz_mul_2exp($_[0], $r, 1);
- Rmpz_mul($_[0], $_[1], $_[0]);
- Rmpz_add_ui($_[0], $_[0], 1);
- if(Math::GMPz::trial_div_ul($_[0], $_[4]) == 1) {
- Rmpz_set($c, $_[0]);
- Rmpz_sub_ui($c, $c, 1);
- Rmpz_powm($c, $two, $c, $_[0]);
- if(!Rmpz_cmp_ui($c, 1)) {
- if($_[2]) {print STDERR "*"}
- Rmpz_mul_2exp($c, $r, 1);
- Rmpz_powm($c, $two, $c, $_[0]);
- Rmpz_sub_ui($c, $c, 1);
- Rmpz_gcd($c, $c, $_[0]);
- if(!Rmpz_cmp_ui($c, 1)) {last}
- }
- }
- Rmpz_sub_ui($r, $r, 1);
- }
-
- if($_[3]) {
- if(!Rmpz_probab_prime_p($_[0], 10)) {die "Rnext_proven returned a composite"}
- }
-
-
- if($_[2]) {print STDERR Rmpz_sizeinbase($_[0], 2), "\n"}
-
-}
-
-sub _rewrite {
- my $len = length($_[0]);
- my @split = ();
- my @ret = ();
- for(my $i = 0; $i < $len - 1; $i++) {
- if(substr($_[0], $i, 1) eq '%') {
- if(substr($_[0], $i + 1, 1) eq '%') { $i++ }
- else { push(@split, $i) }
- }
- }
-
- push(@split, $len);
- shift(@split);
-
- my $start = 0;
-
- for(@split) {
- push(@ret, substr($_[0], $start, $_ - $start));
- $start = $_;
- }
-
- return @ret;
-}
-
-sub Rmpz_printf {
- local $| = 1;
- push @_, 0 if @_ == 1; # add a dummy second argument
- die "Rmpz_printf must pass 2 arguments: format string, and variable" if @_ != 2;
- wrap_gmp_printf(@_);
-}
-
-sub Rmpz_fprintf {
- push @_, 0 if @_ == 2; # add a dummy third argument
- die "Rmpz_fprintf must pass 3 arguments: filehandle, format string, and variable" if @_ != 3;
- wrap_gmp_fprintf(@_);
-}
-
-sub Rmpz_sprintf {
-
- my $len;
-
- if(@_ == 3) { # optional arg wasn't provided
- $len = wrap_gmp_sprintf($_[0], $_[1], 0, $_[2]); # Set missing arg to 0
- }
- else {
- die "Rmpz_sprintf must pass 4 arguments: buffer, format string, variable, buflen" if @_ != 4;
- $len = wrap_gmp_sprintf(@_);
- }
-
- return $len;
-}
-
-sub Rmpz_snprintf {
-
- my $len;
-
- if(@_ == 4) { # optional arg wasn't provided
- $len = wrap_gmp_sprintf($_[0], $_[1], $_[2], 0, $_[3]); # Set missing arg to 0
- }
- else {
- die "Rmpz_snprintf must pass 5 arguments: buffer, bytes written, format string, variable and buflen" if @_ != 5;
- $len = wrap_gmp_snprintf(@_);
- }
-
- return $len;
-}
-
-sub __GNU_MP_VERSION {return ___GNU_MP_VERSION()}
-sub __GNU_MP_VERSION_MINOR {return ___GNU_MP_VERSION_MINOR()}
-sub __GNU_MP_VERSION_PATCHLEVEL {return ___GNU_MP_VERSION_PATCHLEVEL()}
-sub __GNU_MP_RELEASE {return ___GNU_MP_RELEASE()}
-sub __GMP_CC {return ___GMP_CC()}
-sub __GMP_CFLAGS {return ___GMP_CFLAGS()}
-
-*zgmp_randseed = \&Math::GMPz::Random::Rgmp_randseed;
-*zgmp_randseed_ui = \&Math::GMPz::Random::Rgmp_randseed_ui;
-*zgmp_randclear = \&Math::GMPz::Random::Rgmp_randclear;
-*zgmp_randinit_default = \&Math::GMPz::Random::Rgmp_randinit_default;
-*zgmp_randinit_mt = \&Math::GMPz::Random::Rgmp_randinit_mt;
-*zgmp_randinit_lc_2exp = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp;
-*zgmp_randinit_lc_2exp_size = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_size;
-*zgmp_randinit_set = \&Math::GMPz::Random::Rgmp_randinit_set;
-*zgmp_randinit_default_nobless = \&Math::GMPz::Random::Rgmp_randinit_default_nobless;
-*zgmp_randinit_mt_nobless = \&Math::GMPz::Random::Rgmp_randinit_mt_nobless;
-*zgmp_randinit_lc_2exp_nobless = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_nobless;
-*zgmp_randinit_lc_2exp_size_nobless = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_size_nobless;
-*zgmp_randinit_set_nobless = \&Math::GMPz::Random::Rgmp_randinit_set_nobless;
-*zgmp_urandomb_ui = \&Math::GMPz::Random::Rgmp_urandomb_ui;
-*zgmp_urandomm_ui = \&Math::GMPz::Random::Rgmp_urandomm_ui;
-
-1;
-
-__END__
-
-=head1 NAME
-
- Math::GMPz - perl interface to the GMP library's integer (mpz) functions.
-
-=head1 DEPENDENCIES
-
- This module needs the GMP C library - available from:
- http://gmplib.org
-
-=head1 DESCRIPTION
-
- A bignum module utilising the Gnu MP (GMP) library.
- Basically this module simply wraps nearly all of
- the integer functions provided by that library.
- The documentation below extensively plagiarises
- the documentation at http://gmplib.org.
- See the Math::GMPz test suite for examples of
- usage.
-
-=head1 SYNOPSIS
-
- use Math::GMPz qw(:mpz :primes :supp);
-
- my $string = 'fa9eeeeeeeeeeeeea1234dcbaef1';
- my $base = 16;
-
- # Create the Math::GMPz object
- my $bn1 = Rmpz_init_set_str($string, $base);
-
- # Create another Math::GMPz object that holds
- # an initial value of zero, but has enough
- # memory allocated to store a 131-bit number.
- # If 131 bits turns out to be insufficient, it
- # doesn't matter - additional memory is allocated
- # automatically to Math::GMPz objects as needed
- # by the GMP library.
- my $bn2 = Rmpz_init2(131);
-
- # Create another Math::GMPz object initialised to 0.
- my $bn3 = Rmpz_init();
-
- # or use the new() function:
- my $bn4 = Math::GMPz->new(12345);
-
- # Perform some operations ... see 'FUNCTIONS' below.
-
- .
- .
-
- # print out the value held by $bn1 (in octal):
- print Rmpz_get_str($bn1, 8), "\n";
-
- # print out the value held by $bn1 (in decimal):
- print Rmpz_get_str($bn1, 10);
-
- # print out the value held by $bn1 (in base 29)
- # using the (alternative) Rmpz_out_str()
- # function. (This function doesn't print a newline.)
- Rmpz_out_str($bn1, 29);
-
-=head1 MEMORY MANAGEMENT
-
- Objects created with the Rmpz_init* functions have
- been blessed into package Math::GMPz. They will
- therefore be automatically cleaned up by the DESTROY()
- function whenever they go out of scope.
-
- For each Rmpz_init* function there is a corresponding function
- called Rmpz_init*_nobless which returns an
- unblessed object. If you create Math::GMPz objects
- using the '_nobless' versions, it will then be up to you
- to clean up the memory associated with these objects by
- calling Rmpz_clear($op) for each object. Alternatively
- such objects will be cleaned up when the script ends.
- I don't know why you would want to create unblessed
- objects. The point is that you can if you want to.
-
-=head1 FUNCTIONS
-
- See the GMP documentation at http://gmplib.org.
-
- These next 3 functions are demonstrated above:
- $rop = Rmpz_init_set_str($str, $base); # 1 < $base < 37
- $rop = Rmpz_init2($bits); # $bits > 0
- $str = Rmpz_get_str($r, $base); # 1 < $base < 37
-
- The following functions are simply wrappers around a GMP
- function of the same name. eg. Rmpz_swap() is a wrapper around
- mpz_swap().
-
- "$rop", "$op1", "$op2", etc. are Math::GMPz objects - the
- return values of one of the Rmpz_init* functions.
- They are in fact references to GMP structures.
- The "$rop" argument(s) contain the result(s) of the calculation
- being done, the "$op" argument(s) being the input(s) into that
- calculation.
- Generally, $rop, $op1, $op2, etc. can be the same perl variable,
- though usually they will be distinct perl variables
- referencing distinct GMP structures.
- Eg something like Rmpz_add($r1, $r1, $r1),
- where $r1 *is* the same reference to the same GMP structure,
- would add $r1 to itself and store the result in $r1. Think of it
- as $r1 += $r1. Otoh, Rmpz_add($r1, $r2, $r3), where each of the
- arguments is a different reference to a different GMP structure
- would add $r2 to $r3 and store the result in $r1. Think of it as
- $r1 = $r2 + $r3.
- Mostly, the first argument is the argument that
- stores the result and subsequent arguments provide the input values.
- Exceptions to this can be found in some of the functions that
- actually return a value, and, eg., the div_qr functions (which
- yield both quotient and remainder as their first *two* arguments).
- Like I say, see the GMP manual for details. I hope it's
- intuitively obvious or quickly becomes so. Also see the test
- suite that comes with the distro for some examples of usage.
-
- "$ui" means any integer that will fit into a C 'unsigned long int'.
-
- "$si" means any integer that will fit into a C 'signed long int'.
-
- "$double" means any number (not necessarily integer) that will fit
- into a C 'double'.
-
- "$bool" means a value (usually a 'signed long int') in which
- the only interest is whether it evaluates as true or not.
-
- "$str" simply means a string of symbols that represent a number,
- eg "1234567890987654321234567" which might be a base 10 number,
- or "zsa34760sdfgq123r5" which would have to represent at least
- a base 36 number (because "z" is a valid digit only in bases 36
- and higher). Valid bases for GMP numbers are 0 and 2..62 .
-
- "$NULL" is $Math::GMPz::NULL (the NULL mpz type).
-
- #####################
-
- INITIALIZING INTEGERS
-
- Normally, a variable should be initialized once only or at least be
- cleared, using `Rmpz_clear', between initializations.
- 'DESTROY' (which calls 'Rmpz_clear') is automatically called on
- blessed objects whenever they go out of scope.
-
- First read the section 'MEMORY MANAGEMENT' (above).
-
- $rop = Math::GMPz::new();
- $rop = Math::GMPz->new();
- $rop = new Math::GMPz();
- $rop = Rmpz_init();
- $rop = Rmpz_init_nobless();
- Initialize $rop, and set its value to 0.
-
- $rop = Rmpz_init2($bits);
- $rop = Rmpz_init2_nobless($bits);
- Initialize $rop, with space for $bits bits, and set its value
- to 0. $bits is only the initial space, $rop will grow
- automatically if necessary, for subsequent values stored.
- `Rmpz_init2' makes it possible to avoid such reallocations if a
- maximum size is known in advance.
-
- Rmpz_realloc2($rop, $ui);
- Change the space allocated for $rop to $ui bits. The value in
- $rop is preserved if it fits, or is set to 0 if not.
-
- ##################
-
- ASSIGNING INTEGERS
-
-
- Rmpz_set($rop, $op);
- Assign the value in $op to $rop.
-
- Rmpz_set_si($rop, $si);
- Assign the 'signed int', $si, to $rop.
-
- Rmpz_set_ui($rop, $ui);
- Assign the 'unsigned int', $ui, to $rop.
-
- Rmpz_set_d($rop, $double);
- Assign $double to $rop. (Truncate to an integer if necessary.)
-
- Rmpz_set_q($rop, $q); # $q is a Math::GMPq or GMP::Mpq object
- Assign $q to $rop. (Truncate to an integer if necessary.)
-
- Rmpz_set_f($rop, $f); # $f is a Math::GMPf or GMP::Mpf object
- Assign $f to $rop. (Truncate to an integer if necessary.)
-
- Rmpz_set_str($rop, $str, $base);
- Set $rop to the base $base value of $str. $base may vary from
- 2 to 62. If $base is 0, the actual base is determined from the
- leading characters: if the first two characters are "0x" or "0X",
- hexadecimal is assumed, otherwise if the first character is "0",
- octal is assumed, otherwise decimal is assumed.
-
- Rmpz_swap($rop1, $rop2); # swap the values
-
- ######################################
-
- COMBINED INITIALIZATION AND ASSIGNMENT
-
- NOTE: Do NOT use these functions if $rop has already
- been initialised. Instead use the Rmpz_set* functions
- in 'Assigning Integers' (above)
-
- First read the section 'MEMORY MANAGEMENT' (above).
-
- $rop = Math::GMPz->new($arg);
- $rop = Math::GMPz::new($arg);
- $rop = new Math::GMPz($arg);
- Returns a Math::GMPz object with the value of $arg.
- $arg can be either an integer (signed integer, unsigned
- integer, signed fraction or unsigned fraction) or a string that
- represents a numeric value. If $arg is a string, an optional
- additional argument that specifies the base of the number can be
- supplied to new(). If base is 0 (or not supplied) then the leading
- characters of the string are used: 0x or 0X for hex, 0b or 0B for
- binary, 0 for octal, or decimal otherwise. Legal values for the
- base are 0 and 2..62 .
-
- $rop = Rmpz_init_set($op);
- $rop = Rmpz_init_set_nobless($op);
- $rop = Rmpz_init_set_ui($ui);
- $rop = Rmpz_init_set_ui_nobless($ui);
- $rop = Rmpz_init_set_si($si);
- $rop = Rmpz_init_set_si_nobless($si);
- $rop = Rmpz_init_set_d($double);
- $rop = Rmpz_init_set_d_nobless($double);
- $rop = Rmpz_init_set_str($str, $base);
- $rop = Rmpz_init_set_str_nobless($str, $base);
-
- ###################
-
- CONVERTING INTEGERS
-
-
- $ui = Rmpz_get_ui($op);
- Return the value of $op as an `unsigned long'.
- The sign of $op is ignored, only the absolute value is used.
-
- $si = Rmpz_get_si($op);
- If $op fits into a `signed long int' return the value of $op.
- Otherwise return the least significant part of OP, with the
- same sign as $op. If $op is too big to fit in a `signed long
- int', the returned result is probably not very useful. To
- find out if the value will fit, use the function
- `Rmpz_fits_slong_p'.
-
- $double = Rmpz_get_d($op);
- Place the value of $op into a normal perl scalar.
-
- ($double, $si) = Rmpz_get_d_2exp($op);
- Find $double and $si such that $double times 2 raised to
- $si, with 0.5<=abs($double)<1, is a good approximation to $op.
-
- $ul = Rmpz_getlimbn($op, $ui);
- Return limb number $ui from $op. The sign of $op is ignored,
- just the absolute value is used. The least significant limb
- is number 0. `Rmpz_size' can be used to find how many limbs
- make up $op. `Rmpz_getlimbn' returns zero if $ui is outside the
- range 0 to `Rmpz_size($op)-1'.
-
- $str = Rmpz_get_str($op, $base);
- Convert $op to a string of digits in base $base.
- The base may vary from -36..-2, 2..62.
-
- ##################
-
- INTEGER ARITHMETIC
-
- Rmpz_add($rop, $op1, $op2);
- Rmpz_add_ui($rop, $op, $ui);
- $rop = 2nd arg + 3rd arg.
-
- Rmpz_sub($rop, $op1, $op2);
- Rmpz_sub_ui($rop, $op, $ui);
- Rmpz_ui_sub($rop, $ui, $op);
- $rop = 2nd arg - 3rd arg.
-
- Rmpz_mul($rop, $op1, $op2);
- Rmpz_mul_si($rop, $op, $si);
- Rmpz_mul_ui($rop, $op, $ui);
- $rop = 2nd arg * 3rd arg.
-
- Rmpz_addmul($rop, $op1, $op2);
- Rmpz_addmul_ui($rop, $op, $ui);
- $rop += 2nd arg * 3rd arg.
-
- Rmpz_submul($rop, $op1, $op2);
- Rmpz_submul_ui($rop, $op, $ui);
- $rop -= 2nd arg * 3rd arg.
-
- Rmpz_mul_2exp($rop, $op, $ui);
- Set $rop to $op * (2 ** $ui). This operation can
- also be defined as a left shift by $ui bits.
-
- Rmpz_div_2exp($rop, $op, $ui); # Same as Rmpz_fdiv_q_2exp
- Set $rop to $op / (2 ** $ui). This operation can
- also be defined as a right shift by $ui bits.
-
- Rmpz_neg($rop, $op);
- $rop = -$op.
-
- Rmpz_abs($rop, $op);
- $rop = abs($op).
-
- ################
-
- INTEGER DIVISION
-
- `cdiv' rounds quotient up towards +infinity, and remainder
- will have the opposite sign to divisor.
- The `c' stands for "ceil".
-
- `fdiv' rounds quotient down towards -infinity, and remainder
- will have the same sign as divisor.
- The `f' stands for "floor".
-
- `tdiv' rounds quotient towards zero, and remainder
- will have the same sign as the number.
- The `t' stands for "truncate".
-
- Rmpz_div($rop, $op1, $op2); # Same as Rmpz_fdiv_q
- Rmpz_cdiv_q($rop, $op1, $op2);
- Rmpz_fdiv_q($rop, $op1, $op2);
- Rmpz_tdiv_q($rop, $op1, $op2);
- $rop = $op1 / $op2.
-
- Rmpz_cdiv_r($rop, $op1, $op2);
- Rmpz_fdiv_r($rop, $op1, $op2);
- Rmpz_tdiv_r($rop, $op1, $op2);
- $rop = $op1 % $op2.
-
- Rmpz_divmod($rop1, $rop2m $op1, $op2); # Same as Rmpz_fdiv_qr
- Rmpz_cdiv_qr($rop1, $rop2, $op1, $op2);
- Rmpz_fdiv_qr($rop1, $rop2, $op1, $op2);
- Rmpz_tdiv_qr($rop1, $rop1, $op1, $op2);
- $rop1 = $op1 / $op2.
- $rop2 = $op1 % $op2.
-
- $ul = Rmpz_div_ui($rop, $op, $ui); # Same as Rmpz_fdiv_q_ui
- $ul = Rmpz_cdiv_q_ui($rop, $op, $ui);
- $ul = Rmpz_fdiv_q_ui($rop, $op, $ui);
- $ul = Rmpz_tdiv_q_ui($rop, $op, $ui);
- $rop = $op / $ui.
- $ul = $op % $ui.
-
- $ul = Rmpz_cdiv_r_ui($rop, $op, $ui);
- $ul = Rmpz_fdiv_r_ui($rop $op, $ui);
- $ul = Rmpz_tdiv_r_ui($rop, $op, $ui);
- $rop = $op % $ui.
- $ul = $op % $ui.
-
- $ul = Rmpz_divmod_ui($rop1, $rop2, $op1, $ui); # Same as Rmpz_fdiv_qr_ui
- $ul = Rmpz_cdiv_qr_ui($rop1, $rop2, $op, $ui);
- $ul = Rmpz_fdiv_qr_ui($rop1, $rop2, $op, $ui);
- $ul = Rmpz_tdiv_qr_ui($rop1, $rop2, $op, $ui);
- $rop1 = $op / $ui.
- $rop2 = $op % $ui.
- $ul = $op % $ui.
-
- $ul = Rmpz_cdiv_ui($op, $ui);
- $ul = Rmpz_fdiv_ui($op, $ui);
- $ul = Rmpz_tdiv_ui($op, $ui);
- $ul = $op % $ui.
-
- Rmpz_cdiv_q_2exp($rop, $op, $ui);
- Rmpz_fdiv_q_2exp($rop, $op, $ui);
- Rmpz_tdiv_q_2exp($rop, $op, $ui);
- $rop = $op / (2 ** $ui). ie $rop is $op right-shifted
- by $ui bits.
-
- Rmpz_mod_2exp($rop, $op, $ui); # Same as Rmpz_fdiv_r_2exp
- Rmpz_cdiv_r_2exp($rop, $op, $ui);
- Rmpz_fdiv_r_2exp($rop, $op, $ui);
- Rmpz_tdiv_r_2exp($rop, $op, $ui);
- $rop = $op % (2 ** $ui).
-
- Rmpz_mod($rop, $op1, $op2);
- $rop = $op1 % $op2. The sign of the divisor is ignored.
- The result is never negative.
-
- $ul = Rmpz_mod_ui($rop, $op, $ui);
- $rop = $op % $ui.
- $ul = $op % $ui.
- The sign of the divisor is ignored. The result is never negative.
-
- Rmpz_divexact($rop, $op1, $op2);
- Rmpz_divexact_ui($rop, $op, $ui);
- $rop = 2nd arg / 3rd arg.
- These 2 functions provide correct results only when it
- is known that the 3rd arg divides the 2nd arg.
-
- $bool = Rmpz_divisible_p($op1, $op2);
- $bool = Rmpz_divisible_ui_p($op, $ui);
- $bool = Rmpz_divisible_2exp_p($op, $ui);
- Return non-zero if 1st arg is exactly divisible by 2nd arg,
- or in the case of `Rmpz_divisible_2exp_p' by 2 ** 2nd arg.
-
- $bool = Rmpz_congruent_p($op1, $op2, $op3);
- $bool = Rmpz_congruent_ui_p($op, $ui, $ui);
- $bool = Rmpz_congruent_2exp_p($op1, $op2, $ui);
- Return non-zero if 1st arg is congruent to 2nd arg modulo
- 3rd arg, or in the case of `Rmpz_congruent_2exp_p' modulo
- 2 ** 3rd arg.
-
- ######################
-
- INTEGER EXPONENTIATION
-
- Rmpz_powm($rop, $op1, $op2, $op3);
- Rmpz_powm_sec($rop, $op1, $op2, $op3); # gmp-5.0 and later only
- $rop = ($op1 ** $op2 ) % $op3
- In the case of Rmpz_powm_sec, $op2 must be > 0, and $op3 must
- be odd.
-
- Rmpz_powm_ui($rop, $op1, $ui, $op2);
- $rop = ($op1 ** $ui) % $op2
-
- Rmpz_pow_ui($rop, $op, $ui);
- $rop = $op ** $ui
-
- Rmpz_ui_pow_ui($rop, $ui1, $ui2);
- $rop = $ui1 ** $ui2
-
- #############
-
- INTEGER ROOTS
-
- Rmpz_root($rop, $op, $ui);
- $rop = $op ** (1 / $ui).
-
- Rmpz_sqrt($rop, $op);
- $rop = $op ** 0.5.
-
- Rmpz_sqrtrem($rop1, $rop2, $op);
- $rop1 = $op ** 0.5.
- $op = $rop2 + ($rop1 ** 2).
-
- $bool = Rmpz_perfect_power_p($op);
- Return zero if $op is not a perfect power.
- Else return non-zero.
-
- $bool = Rmpz_perfect_square_p($op);
- Return zero if $op is not a perfect square.
- Else return non-zero.
-
- ##########################
-
- NUMBER THEORETIC FUNCTIONS
-
- $si = Rmpz_probab_prime_p($rop, $ui);
- Determine whether $rop is prime. Return 2 if $rop is
- definitely prime, return 1 if $rop is probably prime
- (without being certain), or return 0 if $rop is definitely
- composite. This function does some trial divisions, then
- some Miller-Rabin probabilistic primality tests. $ui
- controls how many such tests are done, 5 to 10 is a
- reasonable number, more will reduce the chances of a
- composite being returned as "probably prime".
- Miller-Rabin and similar tests can be more properly called
- compositeness tests. Numbers which fail are known to be
- composite but those which pass might be prime or might be
- composite. Only a few composites pass, hence those which
- pass are considered probably prime.
-
- Rmpz_nextprime($rop, $op);
- This function uses a probabilistic algorithm to identify
- primes. For practical purposes it's adequate, the chance
- of a composite passing will be extremely small.
-
- Rmpz_gcd($rop, $op1, $op2);
- Set $rop to the greatest common divisor of $op1 and $op2.
- The result is always positive even if one or both input
- operands are negative.
-
- $ui2 = Rmpz_gcd_ui($rop, $op, $ui1); # GCD in $ui2 & $rop
- $ui2 = Rmpz_gcd_ui($NULL, $op, $ui1); # GCD in $ui2 only
- Compute the greatest common divisor of $op and $ui1.
- Store the result in $rop (iff $rop is not $Math::GMPz::NULL).
- If the result is small enough to fit in an `unsigned long
- int', it is returned. If the result does not fit, 0 is
- returned, and the result is equal to the argument $op.
- Note that the result will always fit if $ui1 is non-zero.
-
- Rmpz_gcdext($rop1, $rop2, $rop3, $op1, $op2);
- Rmpz_gcdext($rop1, $rop2, $NULL, $op1, $op2);
- Set $rop1 to the greatest common divisor of $op1 and $op2,
- and in addition set $rop2 and $rop3 to coefficients
- satisfying $op1*$rop2 + $op2*$rop3 = $rop1. $rop1 is
- always positive, even if one or both of $op1 and $op2
- are negative.
- If $rop3 is $Math::GMPz::NULL then that value is not
- computed.
-
- Rmpz_lcm($rop, $op1, $op2);
- Rmpz_lcm_ui($rop, $op, $ui);
- Set $rop to the least common multiple of 2nd and 3rd args.
- $rop is always positive, irrespective of the signs of the
- 2nd and 3rd args. $rop will be zero if either
- 2nd or 3rd arg is zero.
-
- $bool = Rmpz_invert($rop, $op1, $op2);
- Compute the inverse of $op1 modulo $op2 and put the result
- in $rop. If the inverse exists, the return value is
- non-zero and $rop will satisfy 0 <= $rop < $op2.
- If an inverse doesn't exist the return value is zero and
- $rop is undefined.
-
- $si = Rmpz_jacobi($op1, $op2);
- Calculate the Jacobi symbol ($op1/$op2). This is defined
- only for $op2 odd.
-
- $si = Rmpz_legendre($op1, $op2);
- Calculate the Legendre symbol ($op1/$op2). This is defined
- only for $op2 an odd positive prime, and for such $op2
- it's identical to the Jacobi symbol.
-
- $si = Rmpz_kronecker($op1, $op2);
- $si = Rmpz_kronecker_si($op, $si);
- $si = Rmpz_kronecker_ui($op, $ui);
- $si = Rmpz_si_kronecker($si, $op);
- $si = Rmpz_ui_kronecker($ui, $op);
- Calculate the Jacobi symbol (1st arg/2nd arg) with the
- Kronecker extension (a/2)=(2/a) when a odd, or (a/2)=0
- when a even. When 2nd arg is odd the Jacobi symbol and
- Kronecker symbol are identical, so `mpz_kronecker_ui'
- etc can be used for mixed precision Jacobi symbols too.
-
- $ui = Rmpz_remove($rop, $op1, $op2);
- Remove all occurrences of the factor $op2 from $op1 and
- store the result in $rop. The return value is how many
- such occurrences were removed.
-
- Rmpz_fac_ui($rop, $ui);
- Set $rop to the factorial of $ui.
-
- Rmpz_2fac_ui($rop, $ui); # Available only with gmp-5.1.0
- # or later
- Set $rop to the double-factorial (n!!) of $ui.
-
- Rmpz_mfac_uiui($rop, $ui1, $u2); # Available only with
- # gmp-5.1.0 or later
- Set $rop to the $ui2-multi-factorial of $ui1, $ui2.
-
- Rmpz_primorial_ui($rop, $ui); # Available only with gmp-5.1.0
- # or later
- Set $rop to the primorial of $ui, i.e. the product of all
- positive prime numbers smaller than or equal to $ui.
-
- Rmpz_bin_ui($rop, $op, $ui);
- Rmpz_bin_uiui($rop, $ui, $ui);
- Compute the binomial coefficient 2nd arg over 3rd arg and
- store the result in $rop. Negative values of 2nd arg are
- supported by `mpz_bin_ui', using the identity
- bin(-n,k) = (-1)^k * bin(n+k-1,k), see Knuth volume 1
- section 1.2.6 part G.
-
- Rmpz_fib_ui($rop, $ui);
- Rmpz_fib2_ui($rop1, $rop2, $ui);
- `Rmpz_fib_ui' sets $rop to to F[$ui], the $ui'th
- Fibonacci number. `Rmpz_fib2_ui' sets $rop1 to F[$ui],
- and $rop2 to F[$ui-1]. These functions are designed for
- calculating isolated Fibonacci numbers. When a sequence
- of values is wanted it's best to start with `Rmpz_fib2_ui'
- and iterate the defining F[n+1]=F[n]+F[n-1] or similar.
-
- Rmpz_lucnum_ui($rop, $ui);
- Rmpz_lucnum2_ui($rop1, $rop2, $ui);
- `Rmpz_lucnum_ui' sets $rop to to L[$ui], the $ui'th
- Lucas number. `Rmpz_lucnum2_ui' sets $rop1 to L[$ui],
- and $rop2 to L[$ui-1]. These functions are designed for
- calculating isolated Lucas numbers. When a sequence of
- values is wanted it's best to start with `Rmpz_lucnum2_ui'
- and iterate the defining L[n+1]=L[n]+L[n-1] or similar.
-
- ###################
-
- INTEGER COMPARISONS
-
- $si = Rmpz_cmp($op1, $op2);
- $si = Rmpz_cmp_d($op, $double);
- $si = Rmpz_cmp_si($op, $si);
- $si = Rmpz_cmp_ui($op, $ui);
- Compare 1st and 2nd args. Return a positive value if
- 1st arg > 2nd arg, zero if 1st arg = 2nd arg, or a
- negative value if 1st arg < 2nd arg.
-
- $si = Rmpz_cmpabs($op1, $op2);
- $si = Rmpz_cmpabs_d($op, $double);
- $si = Rmpz_cmpabs_ui($op, $ui);
- Compare the absolute values of 1st and 2nd args. Return
- a positive value if abs(1st arg) > abs(2nd arg), zero if
- abs(1st arg) = abs(2nd arg), or a negative value if
- abs(1st arg) < abs(2nd arg).
-
- $si = Rmpz_sgn($op);
- Return +1 if $op > 0, 0 if $opP = 0, and -1 if $op < 0.
-
- ##############################
-
- INTEGER LOGIC AND BIT FIDDLING
-
- Rmpz_and($rop, $op1, $op2);
- Set $rop to $op1 logical-and $op2.
-
- Rmpz_ior($rop, $op1, $op2);
- Set $rop to $op1 inclusive-or $op2.
-
- Rmpz_xor($rop, $op1, $op2);
- Set $rop to $op1 exclusive-or $op2.
-
- Rmpz_com($rop, $op);
- Set $rop to the one's complement of $op.
-
- $ui = Rmpz_popcount($op);
- If $op>=0, return the population count of $op, which is the
- number of 1 bits in the binary representation. If $op<0, the
- number of 1s is infinite, and the return value is MAX_ULONG,
- the largest possible `unsigned long'.
-
- $ui = Rmpz_hamdist($op1, $op2);
- If $op1 and $op2 are both >=0 or both <0, return the hamming
- distance between the two operands, which is the number of bit
- positions where $op1 and $op2 have different bit values. If
- one operand is >=0 and the other <0 then the number of bits
- different is infinite, and the return value is MAX_ULONG,
- the largest possible `unsigned long'.
-
- $ui = Rmpz_scan0($op, $ui);
- $ui = Rmpz_scan1($op, $ui);
- Scan $op, starting from bit index $ui, towards more
- significant bits, until the first 0 or 1 bit (respectively)
- is found. Return the index of the found bit. If the bit at
- index $ui is already what's sought, then $ui is returned.
- If there's no bit found, then MAX_ULONG is returned. This
- will happen in `Rmpz_scan0' past the end of a positive
- number, or `Rmpz_scan1' past the end of a negative.
-
- Rmpz_setbit($rop, $ui);
- Set bit index $ui in $rop.
-
- Rmpz_clrbit($rop, $ui);
- Clear bit index $ui in $rop.
-
- $si = Rmpz_tstbit($op, $ui);
- Test bit index $ui in $op and return 0 or 1 accordingly.
-
- ###############
-
- I/O of INTEGERS
-
- $bytes_written = Rmpz_out_str([$prefix,] $op, $base [, $suffix]);
- BEST TO USE TRmpz_out_str INSTEAD.
- Output $op to STDOUT, as a string of digits in base $base.
- The base may vary from -36..-2, 2..62. Return the number
- of bytes written, or if an error occurred,return 0.
- The optional arguments ($prefix and $suffix) are strings
- that will be prepended/appended to the mpz_out_str output.
- $bytes_written does not include the bytes contained in
- $prefix and $suffix.
-
- $bytes_written = TRmpz_out_str([$prefix,] $stream, $base, $op, [, $suffix]);
- As for Rmpz_out_str, except that there's the capability to print
- to somewhere other than STDOUT. Note that the order of the args
- is different (to match the order of the mpz_out_str args).
- To print to STDERR:
- TRmpz_out_str(*stderr, $base, $digits, $op);
- To print to an open filehandle (let's call it FH):
- TRmpz_out_str(\*FH, $base, $digits, $op);
-
- $bytes_written = Rmpz_out_raw(\*FH, $op);
- Output $op to filehandle FH, in raw binary format. The integer is
- written in a portable format, with 4 bytes of size information, and
- that many bytes of limbs. Both the size and the limbs are written
- in decreasing significance order (i.e., in big-endian). The output
- can be read with mpz_inp_raw.
-
- $bytes_read = Rmpz_inp_str($rop, $base);
- BEST TO USE TRmpz_inp_str instead.
- Input a string in base $base from STDIN, and put the read
- integer in $rop. The base may vary from 2 to 62. If $base
- is 0, the actual base is determined from the leading
- characters: if the first two characters are `0x' or `0X',
- hexadecimal is assumed, otherwise if the first character is
- `0', octal is assumed, otherwise decimal is assumed.
- Return the number of bytes read, or if an error occurred, return 0.
-
- $bytes_read = TRmpz_inp_str($rop, $stream, $base);
- As for Rmpz_inp_str, except that there's the capability to read
- from somewhere other than STDIN.
- To read from STDIN:
- TRmpz_inp_str($rop, *stdin, $base);
- To read from an open filehandle (let's call it FH):
- TRmpz_inp_str($rop, \*FH, $base);
-
- $bytes_read = Rmpz_inp_raw($rop, \*FH);
- Input from filehandle FH in the format written by Rmpz_out_raw,
- and put the result in $rop. Return the number of bytes read, or
- if an error occurred, return 0.
-
-
- #######################
-
- RANDOM NUMBER FUNCTIONS
-
- In the random number functions, @r is an array of
- Math::GMPz objects (one for each random number that is
- required). $how_many is the number of random numbers you
- want and must be equal to scalar(@r). $bits is simply the
- number of random bits required. Before calling the random
- number functions, $state must be initialised and seeded.
-
- $state = rand_init($op); # $op is the seed.
- Initialises and seeds $state, ready for use with the random
- number functions. However, $state has not been blessed into
- any package, and therefore does not get cleaned up when it
- goes out of scope. To avoid memory leaks you therefore need
- to call 'rand_clear($state);' once you have finished with it
- and before it goes out of scope. Also, it uses the default
- algorithm. Consider using the following initialisation and
- seeding routines - they provide a choice of algorithm, and
- there's no need to call rand_clear() when you've finished with
- them.
-
- $state = zgmp_randinit_default();
- This is the Math::GMPz interface to the gmp library function
- 'gmp_randinit_default'.
- $state is blessed into package Math::GMPz::Random and will be
- automatically cleaned up when it goes out of scope.
- Initialize $state with a default algorithm. This will be a
- compromise between speed and randomness, and is recommended for
- applications with no special requirements. Currently this is
- the gmp_randinit_mt function (Mersenne Twister algorithm).
-
- $state = zgmp_randinit_mt();
- This is the Math::GMPz interface to the gmp library function
- 'gmp_randinit_mt'.
- Currently identical to zgmp_randinit_default().
-
- $state = zgmp_randinit_lc_2exp($mpz, $ui, $m2exp);
- This is the Math::GMPz interface to the gmp library function
- 'gmp_randinit_lc_2exp'.
- $state is blessed into package Math::GMPz::Random and will be
- automatically cleaned up when it goes out of scope.
- Initialize $state with a linear congruential algorithm
- X = ($mpz*X + $ui) mod (2 ** $m2exp). The low bits of X in this
- algorithm are not very random. The least significant bit will have a
- period no more than 2, and the second bit no more than 4, etc. For
- this reason only the high half of each X is actually used.
- When a random number of more than m2exp/2 bits is to be generated,
- multiple iterations of the recurrence are used and the results
- concatenated.
-
- $state = zgmp_randinit_lc_2exp_size($ui);
- This is the Math::GMPz interface to the gmp library function
- 'gmp_randinit_lc_2exp_size'.
- $state is blessed into package Math::GMPz::Random and will be
- automatically cleaned up when it goes out of scope.
- Initialize state for a linear congruential algorithm as per
- gmp_randinit_lc_2exp. a, c and m2exp are selected from a table,
- chosen so that $ui bits (or more) of each X will be used,
- ie. m2exp/2 >= $ui.
- If $ui is bigger than the table data provides then the function fails
- and dies with an appropriate error message. The maximum value for $ui
- currently supported is 128.
-
- $state2 = zgmp_randinit_set($state1);
- This is the Math::GMPz interface to the gmp library function
- 'gmp_randinit_set'.
- $state2 is blessed into package Math::GMPz::Random and will be
- automatically cleaned up when it goes out of scope.
- Initialize $state2 with a copy of the algorithm and state from
- $state1.
-
- $state = zgmp_randinit_default_nobless();
- $state = zgmp_randinit_mt_nobless();
- $state = zgmp_randinit_lc_2exp_nobless($mpz, $ui, $m2exp);
- $state2 = zgmp_randinit_set_nobless($state1);
- As for the above comparable function, but $state is not blessed into
- any package. (Generally not useful - but they're available if you
- want them.)
-
- zgmp_randseed($state, $mpz);
- zgmp_randseed_ui($state, $ui);
- These are the Math::GMPz interfaces to the gmp library functions
- 'gmp_randseed' and 'gmp_randseed_ui'.
- Seed an initialised (but not yet seeded) $state with $mpz/$ui.
-
- $ui = zgmp_urandomb_ui($state, $bits);
- This is the Math::GMPz interface to the gmp library function
- 'gmp_urandomb_ui'.
- Return a uniformly distributed random number of $bits bits, ie. in
- the range 0 to 2 ** ($bits - 1) inclusive. $bits must be less than or
- equal to the number of bits in an unsigned long.
-
- $ui2 = zgmp_urandomm_ui($state, $ui1);
- This is the Math::GMPz interface to the gmp library function
- 'gmp_urandomm_ui'.
- Return a uniformly distributed random number in the range 0 to
- $ui1 - 1, inclusive.
-
- Rmpz_urandomm(@r, $state, $mpz, $how_many);
- Generate $how_many uniform random integers in the range
- 0 to $op-1, inclusive.
-
- Rmpz_urandomb(@r, $state, $bits, $how_many);
- Generate $how_many uniformly distributed random integers
- in the range 0 to 2**($bits-1), inclusive.
-
- Rmpz_rrandomb(@r, $state, $bits, $how_many);
- Generate $how_many random integers with long strings of
- zeros and ones in the binary representation. Useful for
- testing functions and algorithms, since this kind of random
- numbers have proven to be more likely to trigger corner-case bugs.
- The random number will be in the range 0 to 2**($bits-1), inclusive.
-
- zgmp_randclear($state);
- rand_clear($state);
- Destroys $state, as also does Math::GMPz::Random::DESTROY - three
- identical functions.
- Use only if $state is an unblessed object - ie if it was initialised
- using rand_init() or one of the zgmp_randinit*_nobless functions.
-
- #########################
-
- INTEGER IMPORT AND EXPORT
-
- Rmpz_import($rop, $len, $order, $size, $endian, $nails, $bstr);
-
- Take a binary string ("$bstr") and convert it to a GMP
- bignum structure, treating the string as a base 256
- number. "$rop" is a Math::GMPz object holding that number.
- "$len" is the length of the string segment to be
- converted to the GMP bignum. Normally, $len = length($bstr),
- but you can opt not to take the entire string if you like.
-
- Usually ($order, $size, $endian, $nails) = (1, 1, 0, 0);
-
- See the GMP manual for a full explanation of what these
- variables mean.
-
- $bstr = Rmpz_export($order, $size, $endian, $nails, $op);
-
- Rmpz_export() is simply the reverse of Rmpz_import().
- It returns a base 256 string representation of the
- number held by the Math::GMPz object, "$op".
-
- ###############################
-
- MISCELLANEOUS INTEGER FUNCTIONS
-
- $bool = Rmpz_fits_ulong_p($op);
- $bool = Rmpz_fits_slong_p($op);
- $bool = Rmpz_fits_uint_p($op);
- $bool = Rmpz_fits_sint_p($op);
- $bool = Rmpz_fits_ushort_p($op);
- $bool = Rmpz_fits_sshort_p($op);
- Return non-zero iff the value of $op fits an `unsigned long int',
- `signed long int', `unsigned int', `signed int', `unsigned short
- int', or `signed short int', respectively. Otherwise, return zero.
-
- $bool = Rmpz_odd_p($op);
- $bool = Rmpz_even_p($op);
- Determine whether $op is odd or even, respectively.
- Return non-zero if yes, zero if no.
-
- $ui = Rmpz_size($op);
- Return the size of $op measured in number of limbs.
- If $op is zero, the returned value will be zero.
-
- $ui = Rmpz_sizeinbase($op, $base);
- Return the size of $op measured in number of digits in base
- $base. The base may vary from 2 to 62. The sign of $op is
- ignored, just the absolute value is used. The result will be
- exact or 1 too big. If $base is a power of 2, the result will
- always be exact. If $op is zero the return value is always 1.
-
- ####################
-
- OPERATOR OVERLOADING
-
- Overloading works with numbers, strings, Math::GMPz objects
- and, to a limited extent, Math::MPFR objects (iff version 3.13
- or later of Math::MPFR has been installed).
-
- The following operators are overloaded:
- + - * / %
- += -= *= /= %=
- << >> <<= >>=
- & | ^ ~
- &= |= ^=
- < <= > >= == != <=>
- ! abs
-
- Division uses 'tdiv' (see 'Integer Division', above).
- Check that '~', '%', and '%=' are working as you expect
- (especially in relation to negative values).
-
- Atempting to use the overloaded operators with objects that
- have been blessed into some package other than 'Math::GMPz'
- or 'Math::MPFR' (limited applications) will not work.
- Math::MPFR objects can be used only with '+', '-', '*', '/'
- and '**' operators, and will work only if Math::MPFR is at
- version 3.13 or later - in which case the operation will
- return a Math::MPFR object.
-
- In those situations where the overload subroutine operates on 2
- perl variables, then obviously one of those perl variables is
- a Math::GMPz object. To determine the value of the other variable
- the subroutine works through the following steps (in order),
- using the first value it finds, or croaking if it gets
- to step 6:
-
- 1. If the variable is an unsigned long then that value is used.
- The variable is considered to be an unsigned long if
- (perl 5.8) the UOK flag is set or if (perl 5.6) SvIsUV()
- returns true.
-
- 2. If the variable is a signed long int, then that value is used.
- The variable is considered to be a signed long int if the
- IOK flag is set. (In the case of perls built with
- -Duse64bitint, the variable is treated as a signed long long
- int if the IOK flag is set.)
-
- 3. If the variable is a double, then that value is used. The
- variable is considered to be a double if the NOK flag is set.
-
- 4. If the variable is a string (ie the POK flag is set) then the
- value of that string is used. Octal strings must begin with
- '0', hex strings must begin with either '0x' or '0X' -
- otherwise the string is assumed to be decimal. If the POK
- flag is set, but the string is not a valid base 8, 10, or 16
- number, the subroutine croaks with an appropriate error
- message.
-
- 5. If the variable is a Math::GMPz object (or, for operators
- specified above, a Math::MPFR object) then the value of that
- object is used.
-
- 6. If none of the above is true, then the second variable is
- deemed to be of an invalid type. The subroutine croaks with
- an appropriate error message.
-
- If the second operand is a 'double' (ie if the other
- operand's NOK flag is set) then it is first truncated
- to an integer value before the operation is performed.
-
- For example:
- my $x = Rmpz_init_set_ui(112);
- $x *= 2.9;
- print "$x"; # prints 224
-
- Atempting to use the overloaded operators with objects that
- have been blessed into some package other than 'Math::GMPz'
- will not work.
-
- #####
-
- OTHER
-
- $GMP_version = Math::GMPz::gmp_v;
- Returns the version of the GMP library (eg 4.2.3) being used by
- Math::GMPz. The function is not exportable.
-
- $GMP_cc = Math::GMPz::__GMP_CC;
- $GMP_cflags = Math::GMPz::__GMP_CFLAGS;
- If Math::GMPz has been built against gmp-4.2.3 or later,
- returns respectively the CC and CFLAGS settings that were used
- to compile the gmp library against which Math::GMPz was built.
- (Values are as specified in the gmp.h that was used to build
- Math::GMPz.)
- Returns undef if Math::GMPz has been built against an earlier
- version of the gmp library.
- (These functions are in @EXPORT_OK and are therefore exportable
- by request. They are not listed under the ":mpz" tag.)
-
-
- $major = Math::GMPz::__GNU_MP_VERSION;
- $minor = Math::GMPz::__GNU_MP_VERSION_MINOR;
- $patchlevel = Math::GMPz::__GNU_MP_VERSION_PATCHLEVEL;
- Returns respectively the major, minor, and patchlevel numbers
- for the GMP library version used to build Math::GMPz. Values are
- as specified in the gmp.h that was used to build Math::GMPz.
- (These functions are in @EXPORT_OK and are therefore exportable
- by request. They are not listed under the ":mpz" tag.)
-
- ################
-
- FORMATTED OUTPUT
-
- NOTE: The format specification can be found at:
- http://gmplib.org/manual/Formatted-Output-Strings.html#Formatted-Output-Strings
- However, the use of '*' to take an extra variable for width and
- precision is not allowed in this implementation. Instead, it is
- necessary to interpolate the variable into the format string - ie,
- instead of:
- Rmpz_printf("%*Zd\n", $width, $mpz);
- we need:
- Rmpz_printf("%${width}Zd\n", $mpz);
-
- $si = Rmpz_printf($format_string, $var);
-
- This function changed with the release of Math-GMPz-0.27.
- Now (unlike the GMP counterpart), it is limited to taking 2
- arguments - the format string, and the variable to be formatted.
- That is, you can format only one variable at a time.
- If there is no variable to be formatted, then the final arg
- can be omitted - a suitable dummy arg will be passed to the XS
- code for you. ie the following will work:
- Rmpz_printf("hello world\n");
- Returns the number of characters written, or -1 if an error
- occurred.
-
- $si = Rmpz_fprintf($fh, $format_string, $var);
-
- This function (unlike the GMP counterpart) is limited to taking
- 3 arguments - the filehandle, the format string, and the variable
- to be formatted. That is, you can format only one variable at a time.
- If there is no variable to be formatted, then the final arg
- can be omitted - a suitable dummy arg will be passed to the XS
- code for you. ie the following will work:
- Rmpz_fprintf($fh, "hello world\n");
- Returns the number of characters written, or -1 if an error
- occurred.
-
- $si = Rmpz_sprintf($buffer, $format_string, [$var,] $buflen);
-
- This function (unlike the GMP counterpart) is limited to taking
- 4 arguments - the buffer, the format string, the variable to be
- formatted and the buffer length. If there is no variable to be
- formatted, then the "$var" arg can be omitted - a suitable dummy
- arg will be passed to the XS code for you. ie the following will
- work:
- Rmpz_sprintf($buffer, "hello world\n", 12);
- $buflen must be large enough to accommodate the formatted string,
- Sets $buffer to the formatted string and returns the number of
- characters written, or -1 if an error occurred.
-
- $si = Rmpz_snprintf($buffer, $bytes, $format_string, [$var,] $buflen);
-
- Form a null-terminated string in $buffer. No more than $bytes
- bytes will be written. To get the full output, $bytes must be
- enough for the string and null-terminator. $buflen must be large
- enough to accommodate the string and null-terminator..
- The return value is the total number of characters which ought
- to have been produced, excluding the terminating null.
- If $si >= $bytes then the actual output has been truncated to
- the first $bytes-1 characters, and a null appended.
- This function (unlike the GMP counterpart) is limited to taking
- 5 arguments - the buffer, the maximum number of bytes to be
- returned, the format string, the variable to be formatted, and
- the length of the buffer to which the formatted string will be
- written.
- If there is no variable to be formatted, then the "$var" arg can
- be omitted - a suitable dummy arg will be passed to the XS code
- for you. ie the following will work:
- Rmpz_snprintf($buffer, 6 "hello world", 12);
-
- ###################
- ###################
-
-=head1 BUGS
-
- You can get segfaults if you pass the wrong type of
- argument to the functions - so if you get a segfault, the
- first thing to do is to check that the argument types
- you have supplied are appropriate.
-
-=head1 LICENSE
-
- This program is free software; you may redistribute it and/or
- modify it under the same terms as Perl itself.
- Copyright 2006-20011, 2013 Sisyphus
-
-=head1 AUTHOR
-
- Sisyphus <sisyphus at(@) cpan dot (.) org>
-
-=cut
\ No newline at end of file
+ package Math::GMPz;
+ use strict;
+ use Math::GMPz::Random;
+ require Exporter;
+ *import = \&Exporter::import;
+ require DynaLoader;
+
+ use constant _UOK_T => 1;
+ use constant _IOK_T => 2;
+ use constant _NOK_T => 3;
+ use constant _POK_T => 4;
+ use constant _MATH_MPFR_T => 5;
+ use constant _MATH_GMPf_T => 6;
+ use constant _MATH_GMPq_T => 7;
+ use constant _MATH_GMPz_T => 8;
+ use constant _MATH_GMP_T => 9;
+ use constant _MATH_MPC_T => 10;
+
+use subs qw( __GNU_MP_VERSION __GNU_MP_VERSION_MINOR __GNU_MP_VERSION_PATCHLEVEL
+ __GNU_MP_RELEASE __GMP_CC __GMP_CFLAGS);
+
+use overload
+ '+' => \&overload_add,
+ '-' => \&overload_sub,
+ '*' => \&overload_mul,
+ '/' => \&overload_div,
+ '+=' => \&overload_add_eq,
+ '-=' => \&overload_sub_eq,
+ '*=' => \&overload_mul_eq,
+ '/=' => \&overload_div_eq,
+ '%' => \&overload_mod,
+ '%=' => \&overload_mod_eq,
+ '<<' => \&overload_lshift,
+ '<<=' => \&overload_lshift_eq,
+ '>>' => \&overload_rshift,
+ '>>=' => \&overload_rshift_eq,
+ '&' => \&overload_and,
+ '&=' => \&overload_and_eq,
+ '|' => \&overload_ior,
+ '|=' => \&overload_ior_eq,
+ '^' => \&overload_xor,
+ '^=' => \&overload_xor_eq,
+ '~' => \&overload_com,
+ '**' => \&overload_pow,
+ '**=' => \&overload_pow_eq,
+ 'sqrt' => \&overload_sqrt,
+ '""' => \&overload_string,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ '>' => \&overload_gt,
+ '>=' => \&overload_gte,
+ '<' => \&overload_lt,
+ '<=' => \&overload_lte,
+ '<=>' => \&overload_spaceship,
+ '==' => \&overload_equiv,
+ '!=' => \&overload_not_equiv,
+ '!' => \&overload_not,
+ '=' => \&overload_copy,
+ 'abs' => \&overload_abs;
+
+ @Math::GMPz::EXPORT_OK = qw(
+__GNU_MP_VERSION __GNU_MP_VERSION_MINOR __GNU_MP_VERSION_PATCHLEVEL
+__GNU_MP_RELEASE __GMP_CC __GMP_CFLAGS
+Rmpz_abs Rmpz_add Rmpz_add_ui Rmpz_addmul Rmpz_addmul_ui Rmpz_and Rmpz_bin_ui
+Rmpz_bin_uiui Rmpz_bin_si Rmpz_cdiv_q Rmpz_cdiv_q_2exp Rmpz_cdiv_q_ui Rmpz_cdiv_qr
+Rmpz_cdiv_qr_ui Rmpz_cdiv_r Rmpz_cdiv_r_2exp Rmpz_cdiv_r_ui Rmpz_cdiv_ui
+Rmpz_clear Rmpz_clrbit Rmpz_cmp Rmpz_cmp_d Rmpz_cmp_si Rmpz_cmp_ui Rmpz_cmpabs
+Rmpz_cmpabs_d Rmpz_cmpabs_ui Rmpz_com Rmpz_combit Rmpz_congruent_2exp_p
+Rmpz_congruent_p Rmpz_congruent_ui_p Rmpz_div Rmpz_divmod Rmpz_div_ui
+Rmpz_divmod_ui Rmpz_div_2exp Rmpz_mod_2exp Rmpz_divexact Rmpz_divexact_ui
+Rmpz_divisible_2exp_p Rmpz_divisible_p Rmpz_divisible_ui_p Rmpz_even_p
+Rmpz_export Rmpz_fac_ui Rmpz_2fac_ui Rmpz_mfac_uiui Rmpz_primorial_ui
+Rmpz_fdiv_q Rmpz_fdiv_q_2exp Rmpz_fdiv_q_ui
+Rmpz_fdiv_qr Rmpz_fdiv_qr_ui Rmpz_fdiv_r Rmpz_fdiv_r_2exp Rmpz_fdiv_r_ui
+Rmpz_fdiv_ui Rmpz_fib2_ui Rmpz_fib_ui Rmpz_fits_sint_p Rmpz_fits_slong_p
+Rmpz_fits_sshort_p Rmpz_fits_uint_p Rmpz_fits_ulong_p Rmpz_fits_ushort_p
+Rmpz_fprintf Rmpz_sprintf Rmpz_snprintf
+Rmpz_gcd Rmpz_gcd_ui Rmpz_gcdext Rmpz_get_d_2exp Rmpz_get_si Rmpz_get_str
+Rmpz_get_ui Rmpz_getlimbn Rmpz_hamdist Rmpz_import Rmpz_init Rmpz_init2
+Rmpz_init2_nobless Rmpz_init_nobless Rmpz_init_set Rmpz_init_set_d
+Rmpz_init_set_d_nobless Rmpz_init_set_nobless Rmpz_init_set_si
+Rmpz_init_set_si_nobless Rmpz_init_set_str Rmpz_init_set_str_nobless
+Rmpz_init_set_ui Rmpz_init_set_ui_nobless Rmpz_inp_str Rmpz_inp_raw
+Rmpz_invert Rmpz_ior
+Rmpz_jacobi Rmpz_kronecker Rmpz_kronecker_si Rmpz_kronecker_ui Rmpz_lcm
+Rmpz_lcm_ui Rmpz_legendre Rmpz_lucnum2_ui Rmpz_lucnum_ui Rmpz_mod Rmpz_mod_ui
+Rmpz_mul Rmpz_mul_2exp Rmpz_mul_si Rmpz_mul_ui Rmpz_neg Rmpz_nextprime
+Rmpz_odd_p Rmpz_out_str Rmpz_out_raw
+Rmpz_perfect_power_p Rmpz_perfect_square_p
+Rmpz_popcount Rmpz_pow_ui Rmpz_powm Rmpz_powm_sec Rmpz_powm_ui Rmpz_printf
+Rmpz_probab_prime_p Rmpz_realloc2 Rmpz_remove Rmpz_root Rmpz_rootrem
+Rmpz_rrandomb Rmpz_scan0 Rmpz_scan1 Rmpz_set Rmpz_set_d Rmpz_set_f Rmpz_set_q
+Rmpz_set_si Rmpz_set_str Rmpz_set_ui Rmpz_setbit Rmpz_sgn Rmpz_si_kronecker
+Rmpz_size Rmpz_sizeinbase Rmpz_sqrt Rmpz_sqrtrem Rmpz_sub Rmpz_sub_ui
+Rmpz_submul Rmpz_submul_ui Rmpz_swap Rmpz_tdiv_q Rmpz_tdiv_q_2exp
+Rmpz_tdiv_q_ui Rmpz_tdiv_qr Rmpz_tdiv_qr_ui Rmpz_tdiv_r Rmpz_tdiv_r_2exp
+Rmpz_tdiv_r_ui Rmpz_tdiv_ui Rmpz_tstbit Rmpz_ui_kronecker Rmpz_ui_pow_ui
+Rmpz_ui_sub Rmpz_urandomb Rmpz_urandomm Rmpz_xor
+rand_init rand_clear
+TRmpz_out_str TRmpz_inp_str
+zgmp_randseed zgmp_randseed_ui zgmp_randclear
+zgmp_randinit_default zgmp_randinit_mt zgmp_randinit_lc_2exp zgmp_randinit_lc_2exp_size
+zgmp_randinit_set zgmp_randinit_default_nobless zgmp_randinit_mt_nobless
+zgmp_randinit_lc_2exp_nobless zgmp_randinit_lc_2exp_size_nobless zgmp_randinit_set_nobless
+zgmp_urandomb_ui zgmp_urandomm_ui
+ );
+ our $VERSION = '0.39';
+ #$VERSION = eval $VERSION;
+
+ DynaLoader::bootstrap Math::GMPz $VERSION;
+
+ $Math::GMPz::NULL = _Rmpz_NULL();
+
+ %Math::GMPz::EXPORT_TAGS =(mpz => [qw(
+Rmpz_abs Rmpz_add Rmpz_add_ui Rmpz_addmul Rmpz_addmul_ui Rmpz_and Rmpz_bin_ui
+Rmpz_bin_uiui Rmpz_bin_si Rmpz_cdiv_q Rmpz_cdiv_q_2exp Rmpz_cdiv_q_ui Rmpz_cdiv_qr
+Rmpz_cdiv_qr_ui Rmpz_cdiv_r Rmpz_cdiv_r_2exp Rmpz_cdiv_r_ui Rmpz_cdiv_ui
+Rmpz_clear Rmpz_clrbit Rmpz_cmp Rmpz_cmp_d Rmpz_cmp_si Rmpz_cmp_ui Rmpz_cmpabs
+Rmpz_cmpabs_d Rmpz_cmpabs_ui Rmpz_com Rmpz_combit Rmpz_congruent_2exp_p
+Rmpz_congruent_p Rmpz_congruent_ui_p Rmpz_div Rmpz_divmod Rmpz_div_ui
+Rmpz_divmod_ui Rmpz_div_2exp Rmpz_mod_2exp Rmpz_divexact Rmpz_divexact_ui
+Rmpz_divisible_2exp_p Rmpz_divisible_p Rmpz_divisible_ui_p Rmpz_even_p
+Rmpz_export Rmpz_fac_ui Rmpz_2fac_ui Rmpz_mfac_uiui Rmpz_primorial_ui
+Rmpz_fdiv_q Rmpz_fdiv_q_2exp Rmpz_fdiv_q_ui
+Rmpz_fdiv_qr Rmpz_fdiv_qr_ui Rmpz_fdiv_r Rmpz_fdiv_r_2exp Rmpz_fdiv_r_ui
+Rmpz_fdiv_ui Rmpz_fib2_ui Rmpz_fib_ui Rmpz_fits_sint_p Rmpz_fits_slong_p
+Rmpz_fits_sshort_p Rmpz_fits_uint_p Rmpz_fits_ulong_p Rmpz_fits_ushort_p
+Rmpz_fprintf Rmpz_sprintf Rmpz_snprintf
+Rmpz_gcd Rmpz_gcd_ui Rmpz_gcdext Rmpz_get_d_2exp Rmpz_get_si Rmpz_get_str
+Rmpz_get_ui Rmpz_getlimbn Rmpz_hamdist Rmpz_import Rmpz_init Rmpz_init2
+Rmpz_init2_nobless Rmpz_init_nobless Rmpz_init_set Rmpz_init_set_d
+Rmpz_init_set_d_nobless Rmpz_init_set_nobless Rmpz_init_set_si
+Rmpz_init_set_si_nobless Rmpz_init_set_str Rmpz_init_set_str_nobless
+Rmpz_init_set_ui Rmpz_init_set_ui_nobless Rmpz_inp_str Rmpz_inp_raw
+Rmpz_invert Rmpz_ior
+Rmpz_jacobi Rmpz_kronecker Rmpz_kronecker_si Rmpz_kronecker_ui Rmpz_lcm
+Rmpz_lcm_ui Rmpz_legendre Rmpz_lucnum2_ui Rmpz_lucnum_ui Rmpz_mod Rmpz_mod_ui
+Rmpz_mul Rmpz_mul_2exp Rmpz_mul_si Rmpz_mul_ui Rmpz_neg Rmpz_nextprime
+Rmpz_odd_p Rmpz_out_str Rmpz_out_raw
+Rmpz_perfect_power_p Rmpz_perfect_square_p
+Rmpz_popcount Rmpz_pow_ui Rmpz_powm Rmpz_powm_sec Rmpz_powm_ui Rmpz_printf
+Rmpz_probab_prime_p Rmpz_realloc2 Rmpz_remove Rmpz_root Rmpz_rootrem
+Rmpz_rrandomb Rmpz_scan0 Rmpz_scan1 Rmpz_set Rmpz_set_d Rmpz_set_f Rmpz_set_q
+Rmpz_set_si Rmpz_set_str Rmpz_set_ui Rmpz_setbit Rmpz_sgn Rmpz_si_kronecker
+Rmpz_size Rmpz_sizeinbase Rmpz_sqrt Rmpz_sqrtrem Rmpz_sub Rmpz_sub_ui
+Rmpz_submul Rmpz_submul_ui Rmpz_swap Rmpz_tdiv_q Rmpz_tdiv_q_2exp
+Rmpz_tdiv_q_ui Rmpz_tdiv_qr Rmpz_tdiv_qr_ui Rmpz_tdiv_r Rmpz_tdiv_r_2exp
+Rmpz_tdiv_r_ui Rmpz_tdiv_ui Rmpz_tstbit Rmpz_ui_kronecker Rmpz_ui_pow_ui
+Rmpz_ui_sub Rmpz_urandomb Rmpz_urandomm Rmpz_xor
+rand_init rand_clear
+TRmpz_out_str TRmpz_inp_str
+zgmp_randseed zgmp_randseed_ui zgmp_randclear
+zgmp_randinit_default zgmp_randinit_mt zgmp_randinit_lc_2exp zgmp_randinit_lc_2exp_size
+zgmp_randinit_set zgmp_randinit_default_nobless zgmp_randinit_mt_nobless
+zgmp_randinit_lc_2exp_nobless zgmp_randinit_lc_2exp_size_nobless zgmp_randinit_set_nobless
+zgmp_urandomb_ui zgmp_urandomm_ui )]
+);
+
+sub dl_load_flags {0} # Prevent DynaLoader from complaining and croaking
+
+sub new {
+
+ # This function caters for 2 possibilities:
+ # 1) that 'new' has been called OOP style - in which
+ # case there will be a maximum of 3 args
+ # 2) that 'new' has been called as a function - in
+ # which case there will be a maximum of 2 args.
+ # If there are no args, then we just want to return an
+ # initialized Math::GMPz
+ if(!@_) {return Rmpz_init()}
+
+ if(@_ > 3) {die "Too many arguments supplied to new()"}
+
+ # If 'new' has been called OOP style, the first arg is the string
+ # "Math::GMPz" which we don't need - so let's remove it. However,
+ # if the first arg is a Math::GMPz object (which is a possibility),
+ # then we'll get a fatal error when we check it for equivalence to
+ # the string "Math::GMPz". So we first need to check that it's not
+ # an object - which we'll do by using the ref() function:
+ if(!ref($_[0]) && $_[0] eq "Math::GMPz") {
+ shift;
+ if(!@_) {return Rmpz_init()}
+ }
+
+ # @_ can now contain a maximum of 2 args - the value, and iff the value is
+ # a string, (optionally) the base of the numeric string.
+ if(@_ > 2) {die "Too many arguments supplied to new() - expected no more than two"}
+
+ my ($arg1, $type, $base);
+
+ # $_[0] is the value, $_[1] (if supplied) is the base of the number
+ # in the string $[_0].
+ $arg1 = shift;
+ $base = 0;
+
+ $type = _itsa($arg1);
+ if(!$type) {die "Inappropriate argument supplied to new()"}
+
+ # Create a Math::GMPz object that has $arg1 as its value.
+ # Die if there are any additional args (unless $type == _POK_T)
+ if($type == _UOK_T || $type == _IOK_T) {
+ if(@_ ) {die "Too many arguments supplied to new() - expected only one"}
+ return Rmpz_init_set_str($arg1, 10);
+ }
+
+ if($type == _NOK_T) {
+ if(@_ ) {die "Too many arguments supplied to new() - expected only one"}
+ if(Math::GMPz::_has_longdouble()) {
+ return _Rmpz_init_set_ld($arg1);
+ }
+ return Rmpz_init_set_d($arg1);
+
+ }
+
+ if($type == _POK_T) { # POK
+ if(@_ > 1) {die "Too many arguments supplied to new() - expected no more than two"}
+ $base = shift if @_;
+ if($base < 0 || $base == 1 || $base > 62) {die "Invalid value for base"}
+ return Rmpz_init_set_str($arg1, $base);
+ }
+
+ if($type == _MATH_GMPz_T || $type == _MATH_GMP_T) { # Math::GMPz or Math::GMP object
+ if(@_) {die "Too many arguments supplied to new() - expected only one"}
+ return Rmpz_init_set($arg1);
+ }
+}
+
+sub Rmpz_out_str {
+ if(@_ == 2) {
+ die "Inappropriate 1st arg supplied to Rmpz_out_str" if _itsa($_[0]) != _MATH_GMPz_T && _itsa($_[0]) != _MATH_GMP_T;
+ return _Rmpz_out_str($_[0], $_[1]);
+ }
+ if(@_ == 3) {
+ if(_itsa($_[0]) == _MATH_GMPz_T || _itsa($_[0]) == _MATH_GMP_T) {return _Rmpz_out_strS($_[0], $_[1], $_[2])}
+ die "Incorrect args supplied to Rmpz_out_str" if _itsa($_[1]) != _MATH_GMPz_T && _itsa($_[1]) != _MATH_GMP_T;
+ return _Rmpz_out_strP($_[0], $_[1], $_[2]);
+ }
+ if(@_ == 4) {
+ die "Inappropriate 2nd arg supplied to Rmpz_out_str" if _itsa($_[1]) != _MATH_GMPz_T && _itsa($_[1]) != _MATH_GMP_T;
+ return _Rmpz_out_strPS($_[0], $_[1], $_[2], $_[3]);
+ }
+ die "Wrong number of arguments supplied to Rmpz_out_str()";
+}
+
+sub TRmpz_out_str {
+ if(@_ == 3) {
+ die "Inappropriate 3rd arg supplied to TRmpz_out_str" if _itsa($_[2]) != _MATH_GMPz_T && _itsa($_[2]) != _MATH_GMP_T;
+ return _TRmpz_out_str($_[0], $_[1], $_[2]);
+ }
+ if(@_ == 4) {
+ if(_itsa($_[2]) == _MATH_GMPz_T || _itsa($_[2]) == _MATH_GMP_T) {return _TRmpz_out_strS($_[0], $_[1], $_[2], $_[3])}
+ die "Incorrect args supplied to TRmpz_out_str" if _itsa($_[3]) != _MATH_GMPz_T && _itsa($_[3]) != _MATH_GMP_T;
+ return _TRmpz_out_strP($_[0], $_[1], $_[2], $_[3]);
+ }
+ if(@_ == 5) {
+ die "Inappropriate 4th arg supplied to TRmpz_out_str" if _itsa($_[3]) != _MATH_GMPz_T && _itsa($_[3]) != _MATH_GMP_T;
+ return _TRmpz_out_strPS($_[0], $_[1], $_[2], $_[3], $_[4]);
+ }
+ die "Wrong number of arguments supplied to TRmpz_out_str()";
+}
+
+sub Rpi_x {
+ Rmpz_set_ui($_[0], 1);
+ Rmpz_mul_2exp($_[0], $_[0], $_[1]);
+ Rmpz_tdiv_q_ui($_[0], $_[0], int(0.693147180559945 * $_[1]));
+ }
+
+sub prime_ratio {
+ return int($_[0] * 0.3465735902799726);
+ }
+
+sub Rprovable_small {
+ my $lim = 341550071728321;
+ my $last = 0;
+ if(Rmpz_cmp_ui($_[0], 2) < 0 || Rmpz_cmp_d($_[0], $lim) >= 0)
+ {die "Argument to provable_small (= ", Rmpz_get_str($_[0], 10), " must be in range [2..341550071728321]"}
+ if(Rmpz_cmp_ui($_[0], 18) < 0) {
+ if(Rmpz_cmp_ui($_[0], 2) <= 0) {Rmpz_set_ui($_[0], 2)}
+ if(!Rmpz_cmp_ui($_[0], 3)) {Rmpz_set_ui($_[0], 3)}
+ if(Rmpz_cmp_ui($_[0], 5) <= 0) {Rmpz_set_ui($_[0], 5)}
+ if(Rmpz_cmp_ui($_[0], 7) <= 0) {Rmpz_set_ui($_[0], 7)}
+ if(Rmpz_cmp_ui($_[0], 11) <= 0) {Rmpz_set_ui($_[0], 11)}
+ if(Rmpz_cmp_ui($_[0], 13) <= 0) {Rmpz_set_ui($_[0], 13)}
+ Rmpz_set_ui($_[0], 17);
+ }
+
+ else {
+ if(!Rmpz_tstbit($_[0], 0)) {Rmpz_add_ui($_[0], $_[0], 1)};
+ while(Rmpz_cmp_d($_[0], $lim) < 0) {
+ if(Rrm_gmp($_[0], 2) && Rrm_gmp($_[0], 3) && Rrm_gmp($_[0], 5) && Rrm_gmp($_[0], 7)
+ && Rrm_gmp($_[0], 11) && Rrm_gmp($_[0], 13) && Rrm_gmp($_[0], 17))
+ {$last = 1;
+ last;
+ }
+ Rmpz_add_ui($_[0], $_[0], 2);
+ }
+ if(!$last) {Rmpz_set_ui($_[0], 0)}
+ }
+
+ }
+
+sub Rprime_test {
+ my $ul = $_[1] + 1;
+ for(2..$ul) {
+ if(!Rrm_gmp($_[0], $_)) {return 0}
+ }
+ return 1;
+ }
+
+sub Rnext_germaine_prime {
+ my $last = 0;
+ my @range = Rsieve_gmp($_[4], $_[5], $_[2]);
+ Rmpz_set($_[0], $_[2]);
+ my $sub = 0;
+ my $mod;
+ for(@range) {
+ Rmpz_add_ui($_[0], $_[0], $_ - $sub);
+ $sub = $_;
+ $mod = Rmpz_tdiv_ui($_[0], 3);
+ if($mod == 2) {
+ if(Rprime_test($_[0], $_[3])) {
+ Rmpz_mul_2exp($_[1], $_[0], 1);
+ Rmpz_add_ui($_[1], $_[1], 1);
+ if(Rprime_test($_[1], $_[3])) {
+ $last = 1;
+ last;
+ }
+ }
+ }
+ }
+ if(!$last) {
+ Rmpz_set_ui($_[0], 0);
+ Rmpz_set_ui($_[1], 0);
+ }
+ }
+
+sub merten {
+ my $gamma = 0.57721566490153286; # Euler's constant
+ return 1 / exp($gamma) / log($_[0]);
+ }
+
+sub Rgenerator_zp {
+ my $s = Rmpz_sizeinbase($_[1], 2);
+ my $order = Rmpz_init2($s);
+ my $temp = Rmpz_init2($s);
+ my $check = Rmpz_init2($s);
+ Rmpz_set($order, $_[1]);
+ Rmpz_sub_ui($order, $order, 1);
+ Rmpz_set($check, $order);
+
+ my $nok = (1,0);
+ for(@{$_[2]}) {
+ if(!Rmpz_divisible_ui_p($order, $_)) {$nok = 1}
+ Rmpz_set_ui($temp, $_);
+ Rmpz_remove($check, $check, $temp);
+ }
+
+ if($nok) {die "Incorrect factors supplied to 3rd argument to Rgenerator_zp() function"}
+
+ if(defined($_[3])) {
+ $nok = 0;
+ for(@{$_[3]}) {
+ if(!Rmpz_divisible_p($order, $_)) {$nok = 1}
+ Rmpz_remove($check, $check, $_);
+ }
+ if($nok) {die "Incorrect factors supplied to 4th argument to Rgenerator_zp function"}
+ }
+
+ if(Rmpz_cmp_ui($check, 1)) {die "Incomplete factorisation supplied to Rgenerator_zp function"};
+
+ while(1) {
+ my $flag = 1;
+ if(Rmpz_cmp($_[0], $order) > 0){warn "Generator greater than order. Re-setting generator %= order and continuing....";
+ Rmpz_tdiv_r($_[0], $_[0], $order);
+ }
+ for(@{$_[2]}) {
+ Rmpz_divexact_ui($temp, $order, $_);
+ Rmpz_powm($check, $_[0], $temp, $_[1]);
+ if(!Rmpz_cmp_ui($check, 1)) {
+ $flag = 0;
+ last;
+ }
+ }
+
+ if($flag && defined($_[3])) {
+ for(@{$_[3]}) {
+ Rmpz_divexact($temp, $order, $_);
+ Rmpz_powm($check, $_[0], $temp, $_[1]);
+ if(!Rmpz_cmp_ui($check, 1)) {
+ $flag = 0;
+ last;
+ }
+ }
+ }
+
+ if($flag) {last}
+ Rmpz_add_ui($_[0], $_[0], 1);
+ }
+
+}
+
+sub Rnext_proven {
+ my $s = Rmpz_sizeinbase($_[1], 2);
+ my $r = Rmpz_init2($s);
+ my $c = Rmpz_init2($s);
+ my $two = Rmpz_init_set_ui(2);
+
+ if(!defined($_[5])) {
+ Rmpz_set($r, $_[1]);
+ Rmpz_sub_ui($r, $r, 1);
+ }
+ else {Rmpz_set($r, $_[5])}
+
+ while(1) {
+ if($_[2]) {print STDERR "."}
+ if(Rmpz_cmp_si($r, 1) < 0) {die "Failed to find next prime in Rnext_proven function"}
+ Rmpz_mul_2exp($_[0], $r, 1);
+ Rmpz_mul($_[0], $_[1], $_[0]);
+ Rmpz_add_ui($_[0], $_[0], 1);
+ if(Math::GMPz::trial_div_ul($_[0], $_[4]) == 1) {
+ Rmpz_set($c, $_[0]);
+ Rmpz_sub_ui($c, $c, 1);
+ Rmpz_powm($c, $two, $c, $_[0]);
+ if(!Rmpz_cmp_ui($c, 1)) {
+ if($_[2]) {print STDERR "*"}
+ Rmpz_mul_2exp($c, $r, 1);
+ Rmpz_powm($c, $two, $c, $_[0]);
+ Rmpz_sub_ui($c, $c, 1);
+ Rmpz_gcd($c, $c, $_[0]);
+ if(!Rmpz_cmp_ui($c, 1)) {last}
+ }
+ }
+ Rmpz_sub_ui($r, $r, 1);
+ }
+
+ if($_[3]) {
+ if(!Rmpz_probab_prime_p($_[0], 10)) {die "Rnext_proven returned a composite"}
+ }
+
+
+ if($_[2]) {print STDERR Rmpz_sizeinbase($_[0], 2), "\n"}
+
+}
+
+sub _rewrite {
+ my $len = length($_[0]);
+ my @split = ();
+ my @ret = ();
+ for(my $i = 0; $i < $len - 1; $i++) {
+ if(substr($_[0], $i, 1) eq '%') {
+ if(substr($_[0], $i + 1, 1) eq '%') { $i++ }
+ else { push(@split, $i) }
+ }
+ }
+
+ push(@split, $len);
+ shift(@split);
+
+ my $start = 0;
+
+ for(@split) {
+ push(@ret, substr($_[0], $start, $_ - $start));
+ $start = $_;
+ }
+
+ return @ret;
+}
+
+sub Rmpz_printf {
+ local $| = 1;
+ push @_, 0 if @_ == 1; # add a dummy second argument
+ die "Rmpz_printf must pass 2 arguments: format string, and variable" if @_ != 2;
+ wrap_gmp_printf(@_);
+}
+
+sub Rmpz_fprintf {
+ push @_, 0 if @_ == 2; # add a dummy third argument
+ die "Rmpz_fprintf must pass 3 arguments: filehandle, format string, and variable" if @_ != 3;
+ wrap_gmp_fprintf(@_);
+}
+
+sub Rmpz_sprintf {
+
+ my $len;
+
+ if(@_ == 3) { # optional arg wasn't provided
+ $len = wrap_gmp_sprintf($_[0], $_[1], 0, $_[2]); # Set missing arg to 0
+ }
+ else {
+ die "Rmpz_sprintf must pass 4 arguments: buffer, format string, variable, buflen" if @_ != 4;
+ $len = wrap_gmp_sprintf(@_);
+ }
+
+ return $len;
+}
+
+sub Rmpz_snprintf {
+
+ my $len;
+
+ if(@_ == 4) { # optional arg wasn't provided
+ $len = wrap_gmp_sprintf($_[0], $_[1], $_[2], 0, $_[3]); # Set missing arg to 0
+ }
+ else {
+ die "Rmpz_snprintf must pass 5 arguments: buffer, bytes written, format string, variable and buflen" if @_ != 5;
+ $len = wrap_gmp_snprintf(@_);
+ }
+
+ return $len;
+}
+
+sub __GNU_MP_VERSION {return ___GNU_MP_VERSION()}
+sub __GNU_MP_VERSION_MINOR {return ___GNU_MP_VERSION_MINOR()}
+sub __GNU_MP_VERSION_PATCHLEVEL {return ___GNU_MP_VERSION_PATCHLEVEL()}
+sub __GNU_MP_RELEASE {return ___GNU_MP_RELEASE()}
+sub __GMP_CC {return ___GMP_CC()}
+sub __GMP_CFLAGS {return ___GMP_CFLAGS()}
+
+*zgmp_randseed = \&Math::GMPz::Random::Rgmp_randseed;
+*zgmp_randseed_ui = \&Math::GMPz::Random::Rgmp_randseed_ui;
+*zgmp_randclear = \&Math::GMPz::Random::Rgmp_randclear;
+*zgmp_randinit_default = \&Math::GMPz::Random::Rgmp_randinit_default;
+*zgmp_randinit_mt = \&Math::GMPz::Random::Rgmp_randinit_mt;
+*zgmp_randinit_lc_2exp = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp;
+*zgmp_randinit_lc_2exp_size = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_size;
+*zgmp_randinit_set = \&Math::GMPz::Random::Rgmp_randinit_set;
+*zgmp_randinit_default_nobless = \&Math::GMPz::Random::Rgmp_randinit_default_nobless;
+*zgmp_randinit_mt_nobless = \&Math::GMPz::Random::Rgmp_randinit_mt_nobless;
+*zgmp_randinit_lc_2exp_nobless = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_nobless;
+*zgmp_randinit_lc_2exp_size_nobless = \&Math::GMPz::Random::Rgmp_randinit_lc_2exp_size_nobless;
+*zgmp_randinit_set_nobless = \&Math::GMPz::Random::Rgmp_randinit_set_nobless;
+*zgmp_urandomb_ui = \&Math::GMPz::Random::Rgmp_urandomb_ui;
+*zgmp_urandomm_ui = \&Math::GMPz::Random::Rgmp_urandomm_ui;
+
+1;
+
+__END__
+
+=head1 NAME
+
+ Math::GMPz - perl interface to the GMP library's integer (mpz) functions.
+
+=head1 DEPENDENCIES
+
+ This module needs the GMP C library - available from:
+ http://gmplib.org
+
+=head1 DESCRIPTION
+
+ A bignum module utilising the Gnu MP (GMP) library.
+ Basically this module simply wraps nearly all of
+ the integer functions provided by that library.
+ The documentation below extensively plagiarises
+ the documentation at http://gmplib.org.
+ See the Math::GMPz test suite for examples of
+ usage.
+
+=head1 SYNOPSIS
+
+ use Math::GMPz qw(:mpz :primes :supp);
+
+ my $string = 'fa9eeeeeeeeeeeeea1234dcbaef1';
+ my $base = 16;
+
+ # Create the Math::GMPz object
+ my $bn1 = Rmpz_init_set_str($string, $base);
+
+ # Create another Math::GMPz object that holds
+ # an initial value of zero, but has enough
+ # memory allocated to store a 131-bit number.
+ # If 131 bits turns out to be insufficient, it
+ # doesn't matter - additional memory is allocated
+ # automatically to Math::GMPz objects as needed
+ # by the GMP library.
+ my $bn2 = Rmpz_init2(131);
+
+ # Create another Math::GMPz object initialised to 0.
+ my $bn3 = Rmpz_init();
+
+ # or use the new() function:
+ my $bn4 = Math::GMPz->new(12345);
+
+ # Perform some operations ... see 'FUNCTIONS' below.
+
+ .
+ .
+
+ # print out the value held by $bn1 (in octal):
+ print Rmpz_get_str($bn1, 8), "\n";
+
+ # print out the value held by $bn1 (in decimal):
+ print Rmpz_get_str($bn1, 10);
+
+ # print out the value held by $bn1 (in base 29)
+ # using the (alternative) Rmpz_out_str()
+ # function. (This function doesn't print a newline.)
+ Rmpz_out_str($bn1, 29);
+
+=head1 MEMORY MANAGEMENT
+
+ Objects created with the Rmpz_init* functions have
+ been blessed into package Math::GMPz. They will
+ therefore be automatically cleaned up by the DESTROY()
+ function whenever they go out of scope.
+
+ For each Rmpz_init* function there is a corresponding function
+ called Rmpz_init*_nobless which returns an
+ unblessed object. If you create Math::GMPz objects
+ using the '_nobless' versions, it will then be up to you
+ to clean up the memory associated with these objects by
+ calling Rmpz_clear($op) for each object. Alternatively
+ such objects will be cleaned up when the script ends.
+ I don't know why you would want to create unblessed
+ objects. The point is that you can if you want to.
+
+=head1 FUNCTIONS
+
+ See the GMP documentation at http://gmplib.org.
+
+ These next 3 functions are demonstrated above:
+ $rop = Rmpz_init_set_str($str, $base); # 1 < $base < 37
+ $rop = Rmpz_init2($bits); # $bits > 0
+ $str = Rmpz_get_str($r, $base); # 1 < $base < 37
+
+ The following functions are simply wrappers around a GMP
+ function of the same name. eg. Rmpz_swap() is a wrapper around
+ mpz_swap().
+
+ "$rop", "$op1", "$op2", etc. are Math::GMPz objects - the
+ return values of one of the Rmpz_init* functions.
+ They are in fact references to GMP structures.
+ The "$rop" argument(s) contain the result(s) of the calculation
+ being done, the "$op" argument(s) being the input(s) into that
+ calculation.
+ Generally, $rop, $op1, $op2, etc. can be the same perl variable,
+ though usually they will be distinct perl variables
+ referencing distinct GMP structures.
+ Eg something like Rmpz_add($r1, $r1, $r1),
+ where $r1 *is* the same reference to the same GMP structure,
+ would add $r1 to itself and store the result in $r1. Think of it
+ as $r1 += $r1. Otoh, Rmpz_add($r1, $r2, $r3), where each of the
+ arguments is a different reference to a different GMP structure
+ would add $r2 to $r3 and store the result in $r1. Think of it as
+ $r1 = $r2 + $r3.
+ Mostly, the first argument is the argument that
+ stores the result and subsequent arguments provide the input values.
+ Exceptions to this can be found in some of the functions that
+ actually return a value, and, eg., the div_qr functions (which
+ yield both quotient and remainder as their first *two* arguments).
+ Like I say, see the GMP manual for details. I hope it's
+ intuitively obvious or quickly becomes so. Also see the test
+ suite that comes with the distro for some examples of usage.
+
+ "$ui" means any integer that will fit into a C 'unsigned long int'.
+
+ "$si" means any integer that will fit into a C 'signed long int'.
+
+ "$double" means any number (not necessarily integer) that will fit
+ into a C 'double'.
+
+ "$bool" means a value (usually a 'signed long int') in which
+ the only interest is whether it evaluates as true or not.
+
+ "$str" simply means a string of symbols that represent a number,
+ eg "1234567890987654321234567" which might be a base 10 number,
+ or "zsa34760sdfgq123r5" which would have to represent at least
+ a base 36 number (because "z" is a valid digit only in bases 36
+ and higher). Valid bases for GMP numbers are 0 and 2..62 .
+
+ "$NULL" is $Math::GMPz::NULL (the NULL mpz type).
+
+ #####################
+
+ INITIALIZING INTEGERS
+
+ Normally, a variable should be initialized once only or at least be
+ cleared, using `Rmpz_clear', between initializations.
+ 'DESTROY' (which calls 'Rmpz_clear') is automatically called on
+ blessed objects whenever they go out of scope.
+
+ First read the section 'MEMORY MANAGEMENT' (above).
+
+ $rop = Math::GMPz::new();
+ $rop = Math::GMPz->new();
+ $rop = new Math::GMPz();
+ $rop = Rmpz_init();
+ $rop = Rmpz_init_nobless();
+ Initialize $rop, and set its value to 0.
+
+ $rop = Rmpz_init2($bits);
+ $rop = Rmpz_init2_nobless($bits);
+ Initialize $rop, with space for $bits bits, and set its value
+ to 0. $bits is only the initial space, $rop will grow
+ automatically if necessary, for subsequent values stored.
+ `Rmpz_init2' makes it possible to avoid such reallocations if a
+ maximum size is known in advance.
+
+ Rmpz_realloc2($rop, $ui);
+ Change the space allocated for $rop to $ui bits. The value in
+ $rop is preserved if it fits, or is set to 0 if not.
+
+ ##################
+
+ ASSIGNING INTEGERS
+
+
+ Rmpz_set($rop, $op);
+ Assign the value in $op to $rop.
+
+ Rmpz_set_si($rop, $si);
+ Assign the 'signed int', $si, to $rop.
+
+ Rmpz_set_ui($rop, $ui);
+ Assign the 'unsigned int', $ui, to $rop.
+
+ Rmpz_set_d($rop, $double);
+ Assign $double to $rop. (Truncate to an integer if necessary.)
+
+ Rmpz_set_q($rop, $q); # $q is a Math::GMPq or GMP::Mpq object
+ Assign $q to $rop. (Truncate to an integer if necessary.)
+
+ Rmpz_set_f($rop, $f); # $f is a Math::GMPf or GMP::Mpf object
+ Assign $f to $rop. (Truncate to an integer if necessary.)
+
+ Rmpz_set_str($rop, $str, $base);
+ Set $rop to the base $base value of $str. $base may vary from
+ 2 to 62. If $base is 0, the actual base is determined from the
+ leading characters: if the first two characters are "0x" or "0X",
+ hexadecimal is assumed, otherwise if the first character is "0",
+ octal is assumed, otherwise decimal is assumed.
+
+ Rmpz_swap($rop1, $rop2); # swap the values
+
+ ######################################
+
+ COMBINED INITIALIZATION AND ASSIGNMENT
+
+ NOTE: Do NOT use these functions if $rop has already
+ been initialised. Instead use the Rmpz_set* functions
+ in 'Assigning Integers' (above)
+
+ First read the section 'MEMORY MANAGEMENT' (above).
+
+ $rop = Math::GMPz->new($arg);
+ $rop = Math::GMPz::new($arg);
+ $rop = new Math::GMPz($arg);
+ Returns a Math::GMPz object with the value of $arg.
+ $arg can be either an integer (signed integer, unsigned
+ integer, signed fraction or unsigned fraction) or a string that
+ represents a numeric value. If $arg is a string, an optional
+ additional argument that specifies the base of the number can be
+ supplied to new(). If base is 0 (or not supplied) then the leading
+ characters of the string are used: 0x or 0X for hex, 0b or 0B for
+ binary, 0 for octal, or decimal otherwise. Legal values for the
+ base are 0 and 2..62 .
+
+ $rop = Rmpz_init_set($op);
+ $rop = Rmpz_init_set_nobless($op);
+ $rop = Rmpz_init_set_ui($ui);
+ $rop = Rmpz_init_set_ui_nobless($ui);
+ $rop = Rmpz_init_set_si($si);
+ $rop = Rmpz_init_set_si_nobless($si);
+ $rop = Rmpz_init_set_d($double);
+ $rop = Rmpz_init_set_d_nobless($double);
+ $rop = Rmpz_init_set_str($str, $base);
+ $rop = Rmpz_init_set_str_nobless($str, $base);
+
+ ###################
+
+ CONVERTING INTEGERS
+
+
+ $ui = Rmpz_get_ui($op);
+ Return the value of $op as an `unsigned long'.
+ The sign of $op is ignored, only the absolute value is used.
+
+ $si = Rmpz_get_si($op);
+ If $op fits into a `signed long int' return the value of $op.
+ Otherwise return the least significant part of OP, with the
+ same sign as $op. If $op is too big to fit in a `signed long
+ int', the returned result is probably not very useful. To
+ find out if the value will fit, use the function
+ `Rmpz_fits_slong_p'.
+
+ $double = Rmpz_get_d($op);
+ Place the value of $op into a normal perl scalar.
+
+ ($double, $si) = Rmpz_get_d_2exp($op);
+ Find $double and $si such that $double times 2 raised to
+ $si, with 0.5<=abs($double)<1, is a good approximation to $op.
+
+ $ul = Rmpz_getlimbn($op, $ui);
+ Return limb number $ui from $op. The sign of $op is ignored,
+ just the absolute value is used. The least significant limb
+ is number 0. `Rmpz_size' can be used to find how many limbs
+ make up $op. `Rmpz_getlimbn' returns zero if $ui is outside the
+ range 0 to `Rmpz_size($op)-1'.
+
+ $str = Rmpz_get_str($op, $base);
+ Convert $op to a string of digits in base $base.
+ The base may vary from -36..-2, 2..62.
+
+ ##################
+
+ INTEGER ARITHMETIC
+
+ Rmpz_add($rop, $op1, $op2);
+ Rmpz_add_ui($rop, $op, $ui);
+ $rop = 2nd arg + 3rd arg.
+
+ Rmpz_sub($rop, $op1, $op2);
+ Rmpz_sub_ui($rop, $op, $ui);
+ Rmpz_ui_sub($rop, $ui, $op);
+ $rop = 2nd arg - 3rd arg.
+
+ Rmpz_mul($rop, $op1, $op2);
+ Rmpz_mul_si($rop, $op, $si);
+ Rmpz_mul_ui($rop, $op, $ui);
+ $rop = 2nd arg * 3rd arg.
+
+ Rmpz_addmul($rop, $op1, $op2);
+ Rmpz_addmul_ui($rop, $op, $ui);
+ $rop += 2nd arg * 3rd arg.
+
+ Rmpz_submul($rop, $op1, $op2);
+ Rmpz_submul_ui($rop, $op, $ui);
+ $rop -= 2nd arg * 3rd arg.
+
+ Rmpz_mul_2exp($rop, $op, $ui);
+ Set $rop to $op * (2 ** $ui). This operation can
+ also be defined as a left shift by $ui bits.
+
+ Rmpz_div_2exp($rop, $op, $ui); # Same as Rmpz_fdiv_q_2exp
+ Set $rop to $op / (2 ** $ui). This operation can
+ also be defined as a right shift by $ui bits.
+
+ Rmpz_neg($rop, $op);
+ $rop = -$op.
+
+ Rmpz_abs($rop, $op);
+ $rop = abs($op).
+
+ ################
+
+ INTEGER DIVISION
+
+ `cdiv' rounds quotient up towards +infinity, and remainder
+ will have the opposite sign to divisor.
+ The `c' stands for "ceil".
+
+ `fdiv' rounds quotient down towards -infinity, and remainder
+ will have the same sign as divisor.
+ The `f' stands for "floor".
+
+ `tdiv' rounds quotient towards zero, and remainder
+ will have the same sign as the number.
+ The `t' stands for "truncate".
+
+ Rmpz_div($rop, $op1, $op2); # Same as Rmpz_fdiv_q
+ Rmpz_cdiv_q($rop, $op1, $op2);
+ Rmpz_fdiv_q($rop, $op1, $op2);
+ Rmpz_tdiv_q($rop, $op1, $op2);
+ $rop = $op1 / $op2.
+
+ Rmpz_cdiv_r($rop, $op1, $op2);
+ Rmpz_fdiv_r($rop, $op1, $op2);
+ Rmpz_tdiv_r($rop, $op1, $op2);
+ $rop = $op1 % $op2.
+
+ Rmpz_divmod($rop1, $rop2m $op1, $op2); # Same as Rmpz_fdiv_qr
+ Rmpz_cdiv_qr($rop1, $rop2, $op1, $op2);
+ Rmpz_fdiv_qr($rop1, $rop2, $op1, $op2);
+ Rmpz_tdiv_qr($rop1, $rop1, $op1, $op2);
+ $rop1 = $op1 / $op2.
+ $rop2 = $op1 % $op2.
+
+ $ul = Rmpz_div_ui($rop, $op, $ui); # Same as Rmpz_fdiv_q_ui
+ $ul = Rmpz_cdiv_q_ui($rop, $op, $ui);
+ $ul = Rmpz_fdiv_q_ui($rop, $op, $ui);
+ $ul = Rmpz_tdiv_q_ui($rop, $op, $ui);
+ $rop = $op / $ui.
+ $ul = $op % $ui.
+
+ $ul = Rmpz_cdiv_r_ui($rop, $op, $ui);
+ $ul = Rmpz_fdiv_r_ui($rop $op, $ui);
+ $ul = Rmpz_tdiv_r_ui($rop, $op, $ui);
+ $rop = $op % $ui.
+ $ul = $op % $ui.
+
+ $ul = Rmpz_divmod_ui($rop1, $rop2, $op1, $ui); # Same as Rmpz_fdiv_qr_ui
+ $ul = Rmpz_cdiv_qr_ui($rop1, $rop2, $op, $ui);
+ $ul = Rmpz_fdiv_qr_ui($rop1, $rop2, $op, $ui);
+ $ul = Rmpz_tdiv_qr_ui($rop1, $rop2, $op, $ui);
+ $rop1 = $op / $ui.
+ $rop2 = $op % $ui.
+ $ul = $op % $ui.
+
+ $ul = Rmpz_cdiv_ui($op, $ui);
+ $ul = Rmpz_fdiv_ui($op, $ui);
+ $ul = Rmpz_tdiv_ui($op, $ui);
+ $ul = $op % $ui.
+
+ Rmpz_cdiv_q_2exp($rop, $op, $ui);
+ Rmpz_fdiv_q_2exp($rop, $op, $ui);
+ Rmpz_tdiv_q_2exp($rop, $op, $ui);
+ $rop = $op / (2 ** $ui). ie $rop is $op right-shifted
+ by $ui bits.
+
+ Rmpz_mod_2exp($rop, $op, $ui); # Same as Rmpz_fdiv_r_2exp
+ Rmpz_cdiv_r_2exp($rop, $op, $ui);
+ Rmpz_fdiv_r_2exp($rop, $op, $ui);
+ Rmpz_tdiv_r_2exp($rop, $op, $ui);
+ $rop = $op % (2 ** $ui).
+
+ Rmpz_mod($rop, $op1, $op2);
+ $rop = $op1 % $op2. The sign of the divisor is ignored.
+ The result is never negative.
+
+ $ul = Rmpz_mod_ui($rop, $op, $ui);
+ $rop = $op % $ui.
+ $ul = $op % $ui.
+ The sign of the divisor is ignored. The result is never negative.
+
+ Rmpz_divexact($rop, $op1, $op2);
+ Rmpz_divexact_ui($rop, $op, $ui);
+ $rop = 2nd arg / 3rd arg.
+ These 2 functions provide correct results only when it
+ is known that the 3rd arg divides the 2nd arg.
+
+ $bool = Rmpz_divisible_p($op1, $op2);
+ $bool = Rmpz_divisible_ui_p($op, $ui);
+ $bool = Rmpz_divisible_2exp_p($op, $ui);
+ Return non-zero if 1st arg is exactly divisible by 2nd arg,
+ or in the case of `Rmpz_divisible_2exp_p' by 2 ** 2nd arg.
+
+ $bool = Rmpz_congruent_p($op1, $op2, $op3);
+ $bool = Rmpz_congruent_ui_p($op, $ui, $ui);
+ $bool = Rmpz_congruent_2exp_p($op1, $op2, $ui);
+ Return non-zero if 1st arg is congruent to 2nd arg modulo
+ 3rd arg, or in the case of `Rmpz_congruent_2exp_p' modulo
+ 2 ** 3rd arg.
+
+ ######################
+
+ INTEGER EXPONENTIATION
+
+ Rmpz_powm($rop, $op1, $op2, $op3);
+ Rmpz_powm_sec($rop, $op1, $op2, $op3); # gmp-5.0 and later only
+ $rop = ($op1 ** $op2 ) % $op3
+ In the case of Rmpz_powm_sec, $op2 must be > 0, and $op3 must
+ be odd.
+
+ Rmpz_powm_ui($rop, $op1, $ui, $op2);
+ $rop = ($op1 ** $ui) % $op2
+
+ Rmpz_pow_ui($rop, $op, $ui);
+ $rop = $op ** $ui
+
+ Rmpz_ui_pow_ui($rop, $ui1, $ui2);
+ $rop = $ui1 ** $ui2
+
+ #############
+
+ INTEGER ROOTS
+
+ Rmpz_root($rop, $op, $ui);
+ $rop = $op ** (1 / $ui).
+
+ Rmpz_sqrt($rop, $op);
+ $rop = $op ** 0.5.
+
+ Rmpz_sqrtrem($rop1, $rop2, $op);
+ $rop1 = $op ** 0.5.
+ $op = $rop2 + ($rop1 ** 2).
+
+ $bool = Rmpz_perfect_power_p($op);
+ Return zero if $op is not a perfect power.
+ Else return non-zero.
+
+ $bool = Rmpz_perfect_square_p($op);
+ Return zero if $op is not a perfect square.
+ Else return non-zero.
+
+ ##########################
+
+ NUMBER THEORETIC FUNCTIONS
+
+ $si = Rmpz_probab_prime_p($rop, $ui);
+ Determine whether $rop is prime. Return 2 if $rop is
+ definitely prime, return 1 if $rop is probably prime
+ (without being certain), or return 0 if $rop is definitely
+ composite. This function does some trial divisions, then
+ some Miller-Rabin probabilistic primality tests. $ui
+ controls how many such tests are done, 5 to 10 is a
+ reasonable number, more will reduce the chances of a
+ composite being returned as "probably prime".
+ Miller-Rabin and similar tests can be more properly called
+ compositeness tests. Numbers which fail are known to be
+ composite but those which pass might be prime or might be
+ composite. Only a few composites pass, hence those which
+ pass are considered probably prime.
+
+ Rmpz_nextprime($rop, $op);
+ This function uses a probabilistic algorithm to identify
+ primes. For practical purposes it's adequate, the chance
+ of a composite passing will be extremely small.
+
+ Rmpz_gcd($rop, $op1, $op2);
+ Set $rop to the greatest common divisor of $op1 and $op2.
+ The result is always positive even if one or both input
+ operands are negative.
+
+ $ui2 = Rmpz_gcd_ui($rop, $op, $ui1); # GCD in $ui2 & $rop
+ $ui2 = Rmpz_gcd_ui($NULL, $op, $ui1); # GCD in $ui2 only
+ Compute the greatest common divisor of $op and $ui1.
+ Store the result in $rop (iff $rop is not $Math::GMPz::NULL).
+ If the result is small enough to fit in an `unsigned long
+ int', it is returned. If the result does not fit, 0 is
+ returned, and the result is equal to the argument $op.
+ Note that the result will always fit if $ui1 is non-zero.
+
+ Rmpz_gcdext($rop1, $rop2, $rop3, $op1, $op2);
+ Rmpz_gcdext($rop1, $rop2, $NULL, $op1, $op2);
+ Set $rop1 to the greatest common divisor of $op1 and $op2,
+ and in addition set $rop2 and $rop3 to coefficients
+ satisfying $op1*$rop2 + $op2*$rop3 = $rop1. $rop1 is
+ always positive, even if one or both of $op1 and $op2
+ are negative.
+ If $rop3 is $Math::GMPz::NULL then that value is not
+ computed.
+
+ Rmpz_lcm($rop, $op1, $op2);
+ Rmpz_lcm_ui($rop, $op, $ui);
+ Set $rop to the least common multiple of 2nd and 3rd args.
+ $rop is always positive, irrespective of the signs of the
+ 2nd and 3rd args. $rop will be zero if either
+ 2nd or 3rd arg is zero.
+
+ $bool = Rmpz_invert($rop, $op1, $op2);
+ Compute the inverse of $op1 modulo $op2 and put the result
+ in $rop. If the inverse exists, the return value is
+ non-zero and $rop will satisfy 0 <= $rop < $op2.
+ If an inverse doesn't exist the return value is zero and
+ $rop is undefined.
+
+ $si = Rmpz_jacobi($op1, $op2);
+ Calculate the Jacobi symbol ($op1/$op2). This is defined
+ only for $op2 odd.
+
+ $si = Rmpz_legendre($op1, $op2);
+ Calculate the Legendre symbol ($op1/$op2). This is defined
+ only for $op2 an odd positive prime, and for such $op2
+ it's identical to the Jacobi symbol.
+
+ $si = Rmpz_kronecker($op1, $op2);
+ $si = Rmpz_kronecker_si($op, $si);
+ $si = Rmpz_kronecker_ui($op, $ui);
+ $si = Rmpz_si_kronecker($si, $op);
+ $si = Rmpz_ui_kronecker($ui, $op);
+ Calculate the Jacobi symbol (1st arg/2nd arg) with the
+ Kronecker extension (a/2)=(2/a) when a odd, or (a/2)=0
+ when a even. When 2nd arg is odd the Jacobi symbol and
+ Kronecker symbol are identical, so `mpz_kronecker_ui'
+ etc can be used for mixed precision Jacobi symbols too.
+
+ $ui = Rmpz_remove($rop, $op1, $op2);
+ Remove all occurrences of the factor $op2 from $op1 and
+ store the result in $rop. The return value is how many
+ such occurrences were removed.
+
+ Rmpz_fac_ui($rop, $ui);
+ Set $rop to the factorial of $ui.
+
+ Rmpz_2fac_ui($rop, $ui); # Available only with gmp-5.1.0
+ # or later
+ Set $rop to the double-factorial (n!!) of $ui.
+
+ Rmpz_mfac_uiui($rop, $ui1, $u2); # Available only with
+ # gmp-5.1.0 or later
+ Set $rop to the $ui2-multi-factorial of $ui1, $ui2.
+
+ Rmpz_primorial_ui($rop, $ui); # Available only with gmp-5.1.0
+ # or later
+ Set $rop to the primorial of $ui, i.e. the product of all
+ positive prime numbers smaller than or equal to $ui.
+
+ Rmpz_bin_ui($rop, $op, $ui);
+ Rmpz_bin_uiui($rop, $ui, $ui);
+ Rmpz_bin_si($rop, $op, $si);
+ Compute the binomial coefficient 2nd arg over 3rd arg and
+ store the result in $rop. Negative values of 2nd arg are
+ supported by `Rmpz_bin_ui' & `Rmpz_bin_si'.
+ (NOTE: The GMP library does not provide an `mpz_bin_si'
+ function.)
+
+ Rmpz_fib_ui($rop, $ui);
+ Rmpz_fib2_ui($rop1, $rop2, $ui);
+ `Rmpz_fib_ui' sets $rop to to F[$ui], the $ui'th
+ Fibonacci number. `Rmpz_fib2_ui' sets $rop1 to F[$ui],
+ and $rop2 to F[$ui-1]. These functions are designed for
+ calculating isolated Fibonacci numbers. When a sequence
+ of values is wanted it's best to start with `Rmpz_fib2_ui'
+ and iterate the defining F[n+1]=F[n]+F[n-1] or similar.
+
+ Rmpz_lucnum_ui($rop, $ui);
+ Rmpz_lucnum2_ui($rop1, $rop2, $ui);
+ `Rmpz_lucnum_ui' sets $rop to to L[$ui], the $ui'th
+ Lucas number. `Rmpz_lucnum2_ui' sets $rop1 to L[$ui],
+ and $rop2 to L[$ui-1]. These functions are designed for
+ calculating isolated Lucas numbers. When a sequence of
+ values is wanted it's best to start with `Rmpz_lucnum2_ui'
+ and iterate the defining L[n+1]=L[n]+L[n-1] or similar.
+
+ ###################
+
+ INTEGER COMPARISONS
+
+ $si = Rmpz_cmp($op1, $op2);
+ $si = Rmpz_cmp_d($op, $double);
+ $si = Rmpz_cmp_si($op, $si);
+ $si = Rmpz_cmp_ui($op, $ui);
+ Compare 1st and 2nd args. Return a positive value if
+ 1st arg > 2nd arg, zero if 1st arg = 2nd arg, or a
+ negative value if 1st arg < 2nd arg.
+
+ $si = Rmpz_cmpabs($op1, $op2);
+ $si = Rmpz_cmpabs_d($op, $double);
+ $si = Rmpz_cmpabs_ui($op, $ui);
+ Compare the absolute values of 1st and 2nd args. Return
+ a positive value if abs(1st arg) > abs(2nd arg), zero if
+ abs(1st arg) = abs(2nd arg), or a negative value if
+ abs(1st arg) < abs(2nd arg).
+
+ $si = Rmpz_sgn($op);
+ Return +1 if $op > 0, 0 if $opP = 0, and -1 if $op < 0.
+
+ ##############################
+
+ INTEGER LOGIC AND BIT FIDDLING
+
+ Rmpz_and($rop, $op1, $op2);
+ Set $rop to $op1 logical-and $op2.
+
+ Rmpz_ior($rop, $op1, $op2);
+ Set $rop to $op1 inclusive-or $op2.
+
+ Rmpz_xor($rop, $op1, $op2);
+ Set $rop to $op1 exclusive-or $op2.
+
+ Rmpz_com($rop, $op);
+ Set $rop to the one's complement of $op.
+
+ $ui = Rmpz_popcount($op);
+ If $op>=0, return the population count of $op, which is the
+ number of 1 bits in the binary representation. If $op<0, the
+ number of 1s is infinite, and the return value is MAX_ULONG,
+ the largest possible `unsigned long'.
+
+ $ui = Rmpz_hamdist($op1, $op2);
+ If $op1 and $op2 are both >=0 or both <0, return the hamming
+ distance between the two operands, which is the number of bit
+ positions where $op1 and $op2 have different bit values. If
+ one operand is >=0 and the other <0 then the number of bits
+ different is infinite, and the return value is MAX_ULONG,
+ the largest possible `unsigned long'.
+
+ $ui = Rmpz_scan0($op, $ui);
+ $ui = Rmpz_scan1($op, $ui);
+ Scan $op, starting from bit index $ui, towards more
+ significant bits, until the first 0 or 1 bit (respectively)
+ is found. Return the index of the found bit. If the bit at
+ index $ui is already what's sought, then $ui is returned.
+ If there's no bit found, then MAX_ULONG is returned. This
+ will happen in `Rmpz_scan0' past the end of a positive
+ number, or `Rmpz_scan1' past the end of a negative.
+
+ Rmpz_setbit($rop, $ui);
+ Set bit index $ui in $rop.
+
+ Rmpz_clrbit($rop, $ui);
+ Clear bit index $ui in $rop.
+
+ $si = Rmpz_tstbit($op, $ui);
+ Test bit index $ui in $op and return 0 or 1 accordingly.
+
+ ###############
+
+ I/O of INTEGERS
+
+ $bytes_written = Rmpz_out_str([$prefix,] $op, $base [, $suffix]);
+ BEST TO USE TRmpz_out_str INSTEAD.
+ Output $op to STDOUT, as a string of digits in base $base.
+ The base may vary from -36..-2, 2..62. Return the number
+ of bytes written, or if an error occurred,return 0.
+ The optional arguments ($prefix and $suffix) are strings
+ that will be prepended/appended to the mpz_out_str output.
+ $bytes_written does not include the bytes contained in
+ $prefix and $suffix.
+
+ $bytes_written = TRmpz_out_str([$prefix,] $stream, $base, $op, [, $suffix]);
+ As for Rmpz_out_str, except that there's the capability to print
+ to somewhere other than STDOUT. Note that the order of the args
+ is different (to match the order of the mpz_out_str args).
+ To print to STDERR:
+ TRmpz_out_str(*stderr, $base, $digits, $op);
+ To print to an open filehandle (let's call it FH):
+ TRmpz_out_str(\*FH, $base, $digits, $op);
+
+ $bytes_written = Rmpz_out_raw(\*FH, $op);
+ Output $op to filehandle FH, in raw binary format. The integer is
+ written in a portable format, with 4 bytes of size information, and
+ that many bytes of limbs. Both the size and the limbs are written
+ in decreasing significance order (i.e., in big-endian). The output
+ can be read with mpz_inp_raw.
+
+ $bytes_read = Rmpz_inp_str($rop, $base);
+ BEST TO USE TRmpz_inp_str instead.
+ Input a string in base $base from STDIN, and put the read
+ integer in $rop. The base may vary from 2 to 62. If $base
+ is 0, the actual base is determined from the leading
+ characters: if the first two characters are `0x' or `0X',
+ hexadecimal is assumed, otherwise if the first character is
+ `0', octal is assumed, otherwise decimal is assumed.
+ Return the number of bytes read, or if an error occurred, return 0.
+
+ $bytes_read = TRmpz_inp_str($rop, $stream, $base);
+ As for Rmpz_inp_str, except that there's the capability to read
+ from somewhere other than STDIN.
+ To read from STDIN:
+ TRmpz_inp_str($rop, *stdin, $base);
+ To read from an open filehandle (let's call it FH):
+ TRmpz_inp_str($rop, \*FH, $base);
+
+ $bytes_read = Rmpz_inp_raw($rop, \*FH);
+ Input from filehandle FH in the format written by Rmpz_out_raw,
+ and put the result in $rop. Return the number of bytes read, or
+ if an error occurred, return 0.
+
+
+ #######################
+
+ RANDOM NUMBER FUNCTIONS
+
+ In the random number functions, @r is an array of
+ Math::GMPz objects (one for each random number that is
+ required). $how_many is the number of random numbers you
+ want and must be equal to scalar(@r). $bits is simply the
+ number of random bits required. Before calling the random
+ number functions, $state must be initialised and seeded.
+
+ $state = rand_init($op); # $op is the seed.
+ Initialises and seeds $state, ready for use with the random
+ number functions. However, $state has not been blessed into
+ any package, and therefore does not get cleaned up when it
+ goes out of scope. To avoid memory leaks you therefore need
+ to call 'rand_clear($state);' once you have finished with it
+ and before it goes out of scope. Also, it uses the default
+ algorithm. Consider using the following initialisation and
+ seeding routines - they provide a choice of algorithm, and
+ there's no need to call rand_clear() when you've finished with
+ them.
+
+ $state = zgmp_randinit_default();
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_randinit_default'.
+ $state is blessed into package Math::GMPz::Random and will be
+ automatically cleaned up when it goes out of scope.
+ Initialize $state with a default algorithm. This will be a
+ compromise between speed and randomness, and is recommended for
+ applications with no special requirements. Currently this is
+ the gmp_randinit_mt function (Mersenne Twister algorithm).
+
+ $state = zgmp_randinit_mt();
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_randinit_mt'.
+ Currently identical to zgmp_randinit_default().
+
+ $state = zgmp_randinit_lc_2exp($mpz, $ui, $m2exp);
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_randinit_lc_2exp'.
+ $state is blessed into package Math::GMPz::Random and will be
+ automatically cleaned up when it goes out of scope.
+ Initialize $state with a linear congruential algorithm
+ X = ($mpz*X + $ui) mod (2 ** $m2exp). The low bits of X in this
+ algorithm are not very random. The least significant bit will have a
+ period no more than 2, and the second bit no more than 4, etc. For
+ this reason only the high half of each X is actually used.
+ When a random number of more than m2exp/2 bits is to be generated,
+ multiple iterations of the recurrence are used and the results
+ concatenated.
+
+ $state = zgmp_randinit_lc_2exp_size($ui);
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_randinit_lc_2exp_size'.
+ $state is blessed into package Math::GMPz::Random and will be
+ automatically cleaned up when it goes out of scope.
+ Initialize state for a linear congruential algorithm as per
+ gmp_randinit_lc_2exp. a, c and m2exp are selected from a table,
+ chosen so that $ui bits (or more) of each X will be used,
+ ie. m2exp/2 >= $ui.
+ If $ui is bigger than the table data provides then the function fails
+ and dies with an appropriate error message. The maximum value for $ui
+ currently supported is 128.
+
+ $state2 = zgmp_randinit_set($state1);
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_randinit_set'.
+ $state2 is blessed into package Math::GMPz::Random and will be
+ automatically cleaned up when it goes out of scope.
+ Initialize $state2 with a copy of the algorithm and state from
+ $state1.
+
+ $state = zgmp_randinit_default_nobless();
+ $state = zgmp_randinit_mt_nobless();
+ $state = zgmp_randinit_lc_2exp_nobless($mpz, $ui, $m2exp);
+ $state2 = zgmp_randinit_set_nobless($state1);
+ As for the above comparable function, but $state is not blessed into
+ any package. (Generally not useful - but they're available if you
+ want them.)
+
+ zgmp_randseed($state, $mpz);
+ zgmp_randseed_ui($state, $ui);
+ These are the Math::GMPz interfaces to the gmp library functions
+ 'gmp_randseed' and 'gmp_randseed_ui'.
+ Seed an initialised (but not yet seeded) $state with $mpz/$ui.
+
+ $ui = zgmp_urandomb_ui($state, $bits);
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_urandomb_ui'.
+ Return a uniformly distributed random number of $bits bits, ie. in
+ the range 0 to 2 ** ($bits - 1) inclusive. $bits must be less than or
+ equal to the number of bits in an unsigned long.
+
+ $ui2 = zgmp_urandomm_ui($state, $ui1);
+ This is the Math::GMPz interface to the gmp library function
+ 'gmp_urandomm_ui'.
+ Return a uniformly distributed random number in the range 0 to
+ $ui1 - 1, inclusive.
+
+ Rmpz_urandomm(@r, $state, $mpz, $how_many);
+ Generate $how_many uniform random integers in the range
+ 0 to $op-1, inclusive.
+
+ Rmpz_urandomb(@r, $state, $bits, $how_many);
+ Generate $how_many uniformly distributed random integers
+ in the range 0 to 2**($bits-1), inclusive.
+
+ Rmpz_rrandomb(@r, $state, $bits, $how_many);
+ Generate $how_many random integers with long strings of
+ zeros and ones in the binary representation. Useful for
+ testing functions and algorithms, since this kind of random
+ numbers have proven to be more likely to trigger corner-case bugs.
+ The random number will be in the range 0 to 2**($bits-1), inclusive.
+
+ zgmp_randclear($state);
+ rand_clear($state);
+ Destroys $state, as also does Math::GMPz::Random::DESTROY - three
+ identical functions.
+ Use only if $state is an unblessed object - ie if it was initialised
+ using rand_init() or one of the zgmp_randinit*_nobless functions.
+
+ #########################
+
+ INTEGER IMPORT AND EXPORT
+
+ Rmpz_import($rop, $len, $order, $size, $endian, $nails, $bstr);
+
+ Take a binary string ("$bstr") and convert it to a GMP
+ bignum structure, treating the string as a base 256
+ number. "$rop" is a Math::GMPz object holding that number.
+ "$len" is the length of the string segment to be
+ converted to the GMP bignum. Normally, $len = length($bstr),
+ but you can opt not to take the entire string if you like.
+
+ Usually ($order, $size, $endian, $nails) = (1, 1, 0, 0);
+
+ See the GMP manual for a full explanation of what these
+ variables mean.
+
+ $bstr = Rmpz_export($order, $size, $endian, $nails, $op);
+
+ Rmpz_export() is simply the reverse of Rmpz_import().
+ It returns a base 256 string representation of the
+ number held by the Math::GMPz object, "$op".
+
+ ###############################
+
+ MISCELLANEOUS INTEGER FUNCTIONS
+
+ $bool = Rmpz_fits_ulong_p($op);
+ $bool = Rmpz_fits_slong_p($op);
+ $bool = Rmpz_fits_uint_p($op);
+ $bool = Rmpz_fits_sint_p($op);
+ $bool = Rmpz_fits_ushort_p($op);
+ $bool = Rmpz_fits_sshort_p($op);
+ Return non-zero iff the value of $op fits an `unsigned long int',
+ `signed long int', `unsigned int', `signed int', `unsigned short
+ int', or `signed short int', respectively. Otherwise, return zero.
+
+ $bool = Rmpz_odd_p($op);
+ $bool = Rmpz_even_p($op);
+ Determine whether $op is odd or even, respectively.
+ Return non-zero if yes, zero if no.
+
+ $ui = Rmpz_size($op);
+ Return the size of $op measured in number of limbs.
+ If $op is zero, the returned value will be zero.
+
+ $ui = Rmpz_sizeinbase($op, $base);
+ Return the size of $op measured in number of digits in base
+ $base. The base may vary from 2 to 62. The sign of $op is
+ ignored, just the absolute value is used. The result will be
+ exact or 1 too big. If $base is a power of 2, the result will
+ always be exact. If $op is zero the return value is always 1.
+
+ ####################
+
+ OPERATOR OVERLOADING
+
+ Overloading works with numbers, strings, Math::GMPz objects
+ and, to a limited extent, Math::MPFR objects (iff version 3.13
+ or later of Math::MPFR has been installed).
+
+ The following operators are overloaded:
+ + - * / %
+ += -= *= /= %=
+ << >> <<= >>=
+ & | ^ ~
+ &= |= ^=
+ < <= > >= == != <=>
+ ! abs
+
+ Division uses 'tdiv' (see 'Integer Division', above).
+ Check that '~', '%', and '%=' are working as you expect
+ (especially in relation to negative values).
+
+ Atempting to use the overloaded operators with objects that
+ have been blessed into some package other than 'Math::GMPz'
+ or 'Math::MPFR' (limited applications) will not work.
+ Math::MPFR objects can be used only with '+', '-', '*', '/'
+ and '**' operators, and will work only if Math::MPFR is at
+ version 3.13 or later - in which case the operation will
+ return a Math::MPFR object.
+
+ In those situations where the overload subroutine operates on 2
+ perl variables, then obviously one of those perl variables is
+ a Math::GMPz object. To determine the value of the other variable
+ the subroutine works through the following steps (in order),
+ using the first value it finds, or croaking if it gets
+ to step 6:
+
+ 1. If the variable is an unsigned long then that value is used.
+ The variable is considered to be an unsigned long if
+ (perl 5.8) the UOK flag is set or if (perl 5.6) SvIsUV()
+ returns true.
+
+ 2. If the variable is a signed long int, then that value is used.
+ The variable is considered to be a signed long int if the
+ IOK flag is set. (In the case of perls built with
+ -Duse64bitint, the variable is treated as a signed long long
+ int if the IOK flag is set.)
+
+ 3. If the variable is a double, then that value is used. The
+ variable is considered to be a double if the NOK flag is set.
+
+ 4. If the variable is a string (ie the POK flag is set) then the
+ value of that string is used. Octal strings must begin with
+ '0', hex strings must begin with either '0x' or '0X' -
+ otherwise the string is assumed to be decimal. If the POK
+ flag is set, but the string is not a valid base 8, 10, or 16
+ number, the subroutine croaks with an appropriate error
+ message.
+
+ 5. If the variable is a Math::GMPz object (or, for operators
+ specified above, a Math::MPFR object) then the value of that
+ object is used.
+
+ 6. If none of the above is true, then the second variable is
+ deemed to be of an invalid type. The subroutine croaks with
+ an appropriate error message.
+
+ If the second operand is a 'double' (ie if the other
+ operand's NOK flag is set) then it is first truncated
+ to an integer value before the operation is performed.
+
+ For example:
+ my $x = Rmpz_init_set_ui(112);
+ $x *= 2.9;
+ print "$x"; # prints 224
+
+ Atempting to use the overloaded operators with objects that
+ have been blessed into some package other than 'Math::GMPz'
+ will not work.
+
+ #####
+
+ OTHER
+
+ $GMP_version = Math::GMPz::gmp_v;
+ Returns the version of the GMP library (eg 4.2.3) being used by
+ Math::GMPz. The function is not exportable.
+
+ $GMP_cc = Math::GMPz::__GMP_CC;
+ $GMP_cflags = Math::GMPz::__GMP_CFLAGS;
+ If Math::GMPz has been built against gmp-4.2.3 or later,
+ returns respectively the CC and CFLAGS settings that were used
+ to compile the gmp library against which Math::GMPz was built.
+ (Values are as specified in the gmp.h that was used to build
+ Math::GMPz.)
+ Returns undef if Math::GMPz has been built against an earlier
+ version of the gmp library.
+ (These functions are in @EXPORT_OK and are therefore exportable
+ by request. They are not listed under the ":mpz" tag.)
+
+
+ $major = Math::GMPz::__GNU_MP_VERSION;
+ $minor = Math::GMPz::__GNU_MP_VERSION_MINOR;
+ $patchlevel = Math::GMPz::__GNU_MP_VERSION_PATCHLEVEL;
+ Returns respectively the major, minor, and patchlevel numbers
+ for the GMP library version used to build Math::GMPz. Values are
+ as specified in the gmp.h that was used to build Math::GMPz.
+ (These functions are in @EXPORT_OK and are therefore exportable
+ by request. They are not listed under the ":mpz" tag.)
+
+ ################
+
+ FORMATTED OUTPUT
+
+ NOTE: The format specification can be found at:
+ http://gmplib.org/manual/Formatted-Output-Strings.html#Formatted-Output-Strings
+ However, the use of '*' to take an extra variable for width and
+ precision is not allowed in this implementation. Instead, it is
+ necessary to interpolate the variable into the format string - ie,
+ instead of:
+ Rmpz_printf("%*Zd\n", $width, $mpz);
+ we need:
+ Rmpz_printf("%${width}Zd\n", $mpz);
+
+ $si = Rmpz_printf($format_string, $var);
+
+ This function changed with the release of Math-GMPz-0.27.
+ Now (unlike the GMP counterpart), it is limited to taking 2
+ arguments - the format string, and the variable to be formatted.
+ That is, you can format only one variable at a time.
+ If there is no variable to be formatted, then the final arg
+ can be omitted - a suitable dummy arg will be passed to the XS
+ code for you. ie the following will work:
+ Rmpz_printf("hello world\n");
+ Returns the number of characters written, or -1 if an error
+ occurred.
+
+ $si = Rmpz_fprintf($fh, $format_string, $var);
+
+ This function (unlike the GMP counterpart) is limited to taking
+ 3 arguments - the filehandle, the format string, and the variable
+ to be formatted. That is, you can format only one variable at a time.
+ If there is no variable to be formatted, then the final arg
+ can be omitted - a suitable dummy arg will be passed to the XS
+ code for you. ie the following will work:
+ Rmpz_fprintf($fh, "hello world\n");
+ Returns the number of characters written, or -1 if an error
+ occurred.
+
+ $si = Rmpz_sprintf($buffer, $format_string, [$var,] $buflen);
+
+ This function (unlike the GMP counterpart) is limited to taking
+ 4 arguments - the buffer, the format string, the variable to be
+ formatted and the buffer length. If there is no variable to be
+ formatted, then the "$var" arg can be omitted - a suitable dummy
+ arg will be passed to the XS code for you. ie the following will
+ work:
+ Rmpz_sprintf($buffer, "hello world\n", 12);
+ $buflen must be large enough to accommodate the formatted string,
+ Sets $buffer to the formatted string and returns the number of
+ characters written, or -1 if an error occurred.
+
+ $si = Rmpz_snprintf($buffer, $bytes, $format_string, [$var,] $buflen);
+
+ Form a null-terminated string in $buffer. No more than $bytes
+ bytes will be written. To get the full output, $bytes must be
+ enough for the string and null-terminator. $buflen must be large
+ enough to accommodate the string and null-terminator..
+ The return value is the total number of characters which ought
+ to have been produced, excluding the terminating null.
+ If $si >= $bytes then the actual output has been truncated to
+ the first $bytes-1 characters, and a null appended.
+ This function (unlike the GMP counterpart) is limited to taking
+ 5 arguments - the buffer, the maximum number of bytes to be
+ returned, the format string, the variable to be formatted, and
+ the length of the buffer to which the formatted string will be
+ written.
+ If there is no variable to be formatted, then the "$var" arg can
+ be omitted - a suitable dummy arg will be passed to the XS code
+ for you. ie the following will work:
+ Rmpz_snprintf($buffer, 6 "hello world", 12);
+
+ ###################
+ ###################
+
+=head1 BUGS
+
+ You can get segfaults if you pass the wrong type of
+ argument to the functions - so if you get a segfault, the
+ first thing to do is to check that the argument types
+ you have supplied are appropriate.
+
+=head1 LICENSE
+
+ This program is free software; you may redistribute it and/or
+ modify it under the same terms as Perl itself.
+ Copyright 2006-20011, 2013 Sisyphus
+
+=head1 AUTHOR
+
+ Sisyphus <sisyphus at(@) cpan dot (.) org>
+
+=cut
@@ -1,6886 +1,6840 @@
-#define PERL_NO_GET_CONTEXT 1
-
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <gmp.h>
-
-#ifdef _MSC_VER
-#pragma warning(disable:4700 4715 4716)
-#endif
-
-#if defined USE_64_BIT_INT
-#ifndef _MSC_VER
-#include <inttypes.h>
-#endif
-#endif
-
-#ifdef OLDPERL
-#define SvUOK SvIsUV
-#endif
-
-#ifndef Newx
-# define Newx(v,n,t) New(0,v,n,t)
-#endif
-
-#ifndef Newxz
-# define Newxz(v,n,t) Newz(0,v,n,t)
-#endif
-
-SV * Rmpz_init_set_str_nobless(pTHX_ SV * num, SV * base) {
- mpz_t * mpz_t_obj;
- unsigned long b = SvUV(base);
- SV * obj_ref, * obj;
-
- if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str_nobless() is not in acceptable range");
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_create function");
- if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
- croak("First argument supplied to Rmpz_create_init_nobless() is not a valid base %u integer", b);
-
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-
-}
-
-SV * Rmpz_init2_nobless(pTHX_ SV * bits) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init2 (*mpz_t_obj, SvUV(bits));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-
-}
-
-SV * Rmpz_init_nobless(pTHX) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init(*mpz_t_obj);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set_nobless(pTHX_ mpz_t * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init_set(*mpz_t_obj, *p);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set_ui_nobless(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init_set_ui(*mpz_t_obj, SvUV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set_si_nobless(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init_set_si(*mpz_t_obj, SvIV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-
-SV * Rmpz_init_set_d_nobless(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d_nobless function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- mpz_init_set_d(*mpz_t_obj, SvNV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init(pTHX) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set(pTHX_ mpz_t * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init_set(*mpz_t_obj, *p);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set_ui(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init_set_ui(*mpz_t_obj, SvUV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * Rmpz_init_set_si(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init_set_si(*mpz_t_obj, SvIV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-
-SV * Rmpz_init_set_d(pTHX_ SV * p) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init_set_d(*mpz_t_obj, SvNV(p));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * _Rmpz_init_set_ld(pTHX_ SV * p) {
-#ifdef USE_LONG_DOUBLE
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
- char buffer[50];
- long double ld = (long double)SvNV(p) >= 0 ? floorl((long double)SvNV(p)) : ceill((long double)SvNV(p));
-
- sprintf(buffer, "%.0Lf", ld);
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in _Rmpz_init_set_ld function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init_set_str(*mpz_t_obj, buffer, 10);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-#else
- croak("_Rmpz_init_set_ld not implemented on this build of perl");
-#endif
-}
-
-
-SV * Rmpz_init_set_str(pTHX_ SV * num, SV * base) {
- mpz_t * mpz_t_obj;
- unsigned long b = SvUV(base);
- SV * obj_ref, * obj;
-
- if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str() is not in acceptable range");
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_str function");
- if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
- croak("First argument supplied to Rmpz_init_set_str() is not a valid base %u integer", b);
-
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-
-}
-
-SV * Rmpz_init2(pTHX_ SV * bits) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2 function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init2 (*mpz_t_obj, SvUV(bits));
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-
-}
-
-SV * Rmpz_get_str(pTHX_ mpz_t * p, SV * base) {
- char * out;
- SV * outsv;
- int c = (int)SvIV(base), b = (int)SvIV(base);
-
- if((b > -2 && b < 2) || b < -36 || b > 62) croak("Second argument supplied to Rmpz_get_str() is not in acceptable range");
-
- if(c < 0) c *= -1;
-
- New(2, out, mpz_sizeinbase(*p, c) + 5, char);
- if(out == NULL) croak("Failed to allocate memory in Rmpz_deref function");
-
- mpz_get_str(out, b, *p);
- outsv = newSVpv(out, 0);
- Safefree(out);
- return outsv;
-}
-
-void DESTROY(pTHX_ mpz_t * p) {
-/* printf("Destroying mpz "); */
- mpz_clear(*p);
- Safefree(p);
-/* printf("...destroyed\n"); */
-}
-
-void Rmpz_clear(pTHX_ mpz_t * p) {
- mpz_clear(*p);
- Safefree(p);
-}
-
-void Rmpz_clear_mpz(pTHX_ mpz_t * p) {
- mpz_clear(*p);
-}
-
-void Rmpz_clear_ptr(pTHX_ mpz_t * p) {
- Safefree(p);
-}
-
-void Rmpz_realloc2(pTHX_ mpz_t * integer, SV * bits){
- mpz_realloc2(*integer, SvUV(bits));
-}
-
-void Rmpz_set(pTHX_ mpz_t * copy, mpz_t * original) {
- mpz_set(*copy, *original);
-}
-
-void Rmpz_set_q(pTHX_ mpz_t * copy, mpq_t * original) {
- mpz_set_q(*copy, *original);
-}
-
-void Rmpz_set_f(pTHX_ mpz_t * copy, mpf_t * original) {
- mpz_set_f(*copy, *original);
-}
-
-void Rmpz_set_si(pTHX_ mpz_t * copy, SV * original) {
- mpz_set_si(*copy, SvIV(original));
-}
-
-void Rmpz_set_ui(pTHX_ mpz_t * copy, SV * original) {
- mpz_set_ui(*copy, SvUV(original));
-}
-
-void Rmpz_set_d(pTHX_ mpz_t * copy, SV * original) {
- mpz_set_d(*copy, SvNV(original));
-}
-
-void Rmpz_set_str(pTHX_ mpz_t * copy, SV * original, SV * base) {
- if(SvUV(base) == 1 || SvUV(base) > 62) croak("Second argument supplied to Rmpz_set_str() is not in acceptable range");
- if(mpz_set_str(*copy, SvPV_nolen(original), SvUV(base)))
- croak("Second argument supplied to Rmpz_set_str() is not a valid base %u integer", SvUV(base));
-}
-
-void Rmpz_swap(pTHX_ mpz_t * a, mpz_t * b) {
- mpz_swap(*a, *b);
-}
-
-SV * Rmpz_get_ui(pTHX_ mpz_t * n) {
- return newSVuv(mpz_get_ui(*n));
-}
-
-SV * Rmpz_get_si(pTHX_ mpz_t * n) {
- return newSViv(mpz_get_si(*n));
-}
-
-SV * Rmpz_get_d(pTHX_ mpz_t * n) {
- return newSVnv(mpz_get_d(*n));
-}
-
-void Rmpz_get_d_2exp(pTHX_ mpz_t * n) {
- dXSARGS;
- double d;
- long exp;
-
- d = mpz_get_d_2exp(&exp, *n);
-
- /* sp = mark; */ /* not needed */
- EXTEND(SP, 2);
- ST(0) = sv_2mortal(newSVnv(d));
- ST(1) = sv_2mortal(newSVuv(exp));
- /* PUTBACK; */ /* not needed */
- XSRETURN(2);
-}
-
-SV * Rmpz_getlimbn(pTHX_ mpz_t * p, SV * n) {
- return newSVuv(mpz_getlimbn(*p, SvUV(n)));
-}
-
-void Rmpz_add(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_add(*dest, *src1, *src2 );
-}
-
-void Rmpz_add_ui(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_add_ui(*dest, *src, SvUV(num));
-/* return sv_setref_pv(newSViv(0), Nullch, INT2PTR(mpz_t *, SvIV(SvRV(dest)))); */
-}
-
-void Rmpz_sub(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_sub(*dest, *src1, *src2 );
-}
-
-void Rmpz_sub_ui(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_sub_ui(*dest, *src, SvUV(num));
-}
-
-void Rmpz_ui_sub(pTHX_ mpz_t * dest, SV * num, mpz_t * src) {
- mpz_ui_sub(*dest, SvUV(num), *src);
-}
-
-void Rmpz_mul(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_mul(*dest, *src1, *src2 );
-}
-
-void Rmpz_mul_si(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_mul_si(*dest, *src, SvIV(num));
-}
-
-void Rmpz_mul_ui(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_mul_ui(*dest, *src, SvUV(num));
-}
-
-void Rmpz_addmul(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_addmul(*dest, *src1, *src2 );
-}
-
-void Rmpz_addmul_ui(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_addmul_ui(*dest, *src, SvUV(num));
-}
-
-void Rmpz_submul(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_submul(*dest, *src1, *src2 );
-}
-
-void Rmpz_submul_ui(pTHX_ mpz_t * dest, mpz_t * src, SV * num) {
- mpz_submul_ui(*dest, *src, SvUV(num));
-}
-
-void Rmpz_mul_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
- mpz_mul_2exp(*dest, *src1, SvUV(b));
-}
-
-void Rmpz_div_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
- mpz_div_2exp(*dest, *src1, SvUV(b));
-}
-
-void Rmpz_neg(pTHX_ mpz_t * dest, mpz_t * src) {
- mpz_neg(*dest, *src );
-}
-
-void Rmpz_abs(pTHX_ mpz_t * dest, mpz_t * src) {
- mpz_abs(*dest, *src );
-}
-
-void Rmpz_cdiv_q(pTHX_ mpz_t * q, mpz_t * n, mpz_t * d) {
- mpz_cdiv_q(*q, *n, *d);
-}
-
-void Rmpz_cdiv_r(pTHX_ mpz_t * mod, mpz_t * n, mpz_t * d) {
- mpz_cdiv_r(*mod, *n, *d);
-}
-
-void Rmpz_cdiv_qr(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
- mpz_cdiv_qr(*q, *r, *n, *d);
-}
-
-SV * Rmpz_cdiv_q_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_cdiv_q_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_cdiv_r_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_cdiv_r_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_cdiv_qr_ui(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, SV * d) {
- return newSVuv(mpz_cdiv_qr_ui(*q, *r, *n, SvUV(d)));
-}
-
-SV * Rmpz_cdiv_ui(pTHX_ mpz_t * n, SV * d) {
- return newSVuv(mpz_cdiv_ui(*n, SvUV(d)));
-}
-
-void Rmpz_cdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
- mpz_cdiv_q_2exp(*q, *n, SvUV(b));
-}
-
-void Rmpz_cdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
- mpz_cdiv_r_2exp(*r, *n, SvUV(b));
-}
-
-void Rmpz_fdiv_q(pTHX_ mpz_t * q, mpz_t * n, mpz_t * d) {
- mpz_fdiv_q(*q, *n, *d);
-}
-
-void Rmpz_div(pTHX_ mpz_t * q, mpz_t * n, mpz_t * d) {
- mpz_div(*q, *n, *d);
-}
-
-/* % mpz-t (modulus) operator */
-void Rmpz_fdiv_r(pTHX_ mpz_t * mod, mpz_t * n, mpz_t * d) {
- mpz_fdiv_r(*mod, *n, *d);
-}
-
-void Rmpz_fdiv_qr(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
- mpz_fdiv_qr(*q, *r, *n, *d);
-}
-
-void Rmpz_divmod(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
- mpz_divmod(*q, *r, *n, *d);
-}
-
-SV * Rmpz_fdiv_q_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_fdiv_q_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_div_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_div_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_fdiv_r_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_fdiv_r_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_fdiv_qr_ui(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, SV * d) {
- return newSVuv(mpz_fdiv_qr_ui(*q, *r, *n, SvUV(d)));
-}
-
-SV * Rmpz_divmod_ui(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, SV * d) {
- return newSVuv(mpz_divmod_ui(*q, *r, *n, SvUV(d)));
-}
-
-/* % int (modulus) operator */
-SV * Rmpz_fdiv_ui(pTHX_ mpz_t * n, SV * d) {
- return newSVuv(mpz_fdiv_ui(*n, SvUV(d)));
-}
-
-void Rmpz_fdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
- mpz_fdiv_q_2exp(*q, *n, SvUV(b));
-}
-
-void Rmpz_fdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
- mpz_fdiv_r_2exp(*r, *n, SvUV(b));
-}
-
-void Rmpz_mod_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
- mpz_mod_2exp(*r, *n, SvUV(b));
-}
-
-void Rmpz_tdiv_q(pTHX_ mpz_t * q, mpz_t * n, mpz_t * d) {
- mpz_tdiv_q(*q, *n, *d);
-}
-
-/* % mpz-t (modulus) operator */
-void Rmpz_tdiv_r(pTHX_ mpz_t * mod, mpz_t * n, mpz_t * d) {
- mpz_tdiv_r(*mod, *n, *d);
-}
-
-void Rmpz_tdiv_qr(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
- mpz_tdiv_qr(*q, *r, *n, *d);
-}
-
-SV * Rmpz_tdiv_q_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_tdiv_q_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_tdiv_r_ui(pTHX_ mpz_t * q, mpz_t * n, SV * d) {
- return newSVuv(mpz_tdiv_r_ui(*q, *n, SvUV(d)));
-}
-
-SV * Rmpz_tdiv_qr_ui(pTHX_ mpz_t * q, mpz_t * r, mpz_t * n, SV * d) {
- return newSVuv(mpz_tdiv_qr_ui(*q, *r, *n, SvUV(d)));
-}
-
-/* % int (modulus) operator */
-SV * Rmpz_tdiv_ui(pTHX_ mpz_t * n, SV * d) {
- return newSVuv(mpz_tdiv_ui(*n, SvUV(d)));
-}
-
-void Rmpz_tdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
- mpz_tdiv_q_2exp(*q, *n, SvUV(b));
-}
-
-void Rmpz_tdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
- mpz_tdiv_r_2exp(*r, *n, SvUV(b));
-}
-
-void Rmpz_mod(pTHX_ mpz_t * r, mpz_t * n, mpz_t * d) {
- mpz_mod(*r, *n, *d);
-}
-
-SV * Rmpz_mod_ui(pTHX_ mpz_t * r, mpz_t * n, SV * d) {
- return newSVuv(mpz_mod_ui(*r, *n, SvUV(d)));
-}
-
-void Rmpz_divexact(pTHX_ mpz_t * dest, mpz_t * n, mpz_t * d) {
- mpz_divexact(*dest, *n, *d );
-}
-
-void Rmpz_divexact_ui(pTHX_ mpz_t * dest, mpz_t * n, SV * d) {
- mpz_divexact_ui(*dest, *n, SvUV(d));
-}
-
-int Rmpz_divisible_p(mpz_t * n, mpz_t * d) {
- return mpz_divisible_p(*n, *d);
-}
-
-SV * Rmpz_divisible_ui_p(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_divisible_ui_p(*n, SvUV(d)));
-}
-
-SV * Rmpz_divisible_2exp_p(pTHX_ mpz_t * n, SV * b) {
- return newSViv(mpz_divisible_2exp_p(*n, SvUV(b)));
-}
-
-SV * Rmpz_congruent_p(pTHX_ mpz_t * n, mpz_t * c, mpz_t * d) {
- return newSViv(mpz_congruent_p(*n, *c, *d));
-}
-
-SV * Rmpz_congruent_ui_p(pTHX_ mpz_t * n, SV * c, SV * d) {
- return newSViv(mpz_congruent_ui_p(*n, SvUV(c), SvUV(d)));
-}
-
-SV * Rmpz_congruent_2exp_p(pTHX_ mpz_t * n, mpz_t * c, SV * d) {
- return newSViv(mpz_congruent_2exp_p(*n, *c, SvUV(d)));
-}
-
-void Rmpz_powm(pTHX_ mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
- mpz_powm(*dest, *base, *exp, *mod);
-}
-
-void Rmpz_powm_ui(pTHX_ mpz_t * dest, mpz_t * base, SV * exp, mpz_t * mod) {
- mpz_powm_ui(*dest, *base, SvUV(exp), *mod);
-}
-
-void Rmpz_pow_ui(pTHX_ mpz_t * dest, mpz_t * base, SV * exp) {
- mpz_pow_ui(*dest, *base, SvUV(exp));
-}
-
-void Rmpz_ui_pow_ui(pTHX_ mpz_t * dest, SV * base, SV * exp) {
- mpz_ui_pow_ui(*dest, SvUV(base), SvUV(exp));
-}
-
-SV * Rmpz_root(pTHX_ mpz_t * r, mpz_t * n, SV * d) {
- return newSViv(mpz_root(*r, *n, SvUV(d)));
-}
-
-void Rmpz_sqrt(pTHX_ mpz_t * r, mpz_t * n) {
- mpz_sqrt(*r, *n);
-}
-
-void Rmpz_sqrtrem(pTHX_ mpz_t * root, mpz_t * rem, mpz_t * src) {
- mpz_sqrtrem(*root, *rem, *src);
-}
-
-int Rmpz_perfect_power_p(mpz_t * in) {
- return mpz_perfect_power_p(*in);
-}
-
-int Rmpz_perfect_square_p(mpz_t * in) {
- return mpz_perfect_square_p(*in);
-}
-
-SV * Rmpz_probab_prime_p(pTHX_ mpz_t * cand, SV * reps) {
- return newSViv(mpz_probab_prime_p(*cand, SvUV(reps)));
-}
-
-void Rmpz_nextprime(pTHX_ mpz_t * prime, mpz_t * init) {
- mpz_nextprime(*prime, *init);
-}
-
-void Rmpz_gcd(pTHX_ mpz_t * gcd, mpz_t * src1, mpz_t * src2) {
- mpz_gcd(*gcd, *src1, *src2);
-}
-
-/* First arg can be either (the unblessed) $Math::GMPz::NULL or a
- * (blessed) Math::GMPz object.
- */
-SV * Rmpz_gcd_ui(pTHX_ mpz_t * gcd, mpz_t * n, SV * d) {
- return newSVuv(mpz_gcd_ui(*gcd, *n, SvUV(d)));
-}
-
-void Rmpz_gcdext(pTHX_ mpz_t * g, mpz_t * s, mpz_t * t, mpz_t * a, mpz_t * b) {
- mpz_gcdext(*g, *s, *t, *a, *b);
-}
-
-void Rmpz_lcm(pTHX_ mpz_t * lcm, mpz_t * src1, mpz_t * src2) {
- mpz_lcm(*lcm, *src1, *src2);
-}
-
-void Rmpz_lcm_ui(pTHX_ mpz_t * lcm, mpz_t * src1, SV * src2) {
- mpz_lcm_ui(*lcm, *src1, SvUV(src2));
-}
-
-int Rmpz_invert(mpz_t * inv, mpz_t * src1, mpz_t * src2) {
- return mpz_invert(*inv, *src1, *src2);
-}
-
-int Rmpz_jacobi(mpz_t * a, mpz_t * b) {
- return mpz_jacobi(*a, *b);
-}
-
-int Rmpz_legendre(mpz_t * a, mpz_t * b) {
- return mpz_legendre(*a, *b);
-}
-
-int Rmpz_kronecker(mpz_t * a, mpz_t * b) {
- return mpz_kronecker(*a, *b);
-}
-
-SV * Rmpz_kronecker_si(pTHX_ mpz_t * a, SV * b) {
- return newSViv(mpz_kronecker_si(*a, SvIV(b)));
-}
-
-SV * Rmpz_kronecker_ui(pTHX_ mpz_t * a, SV * b) {
- return newSViv(mpz_kronecker_ui(*a, SvUV(b)));
-}
-
-SV * Rmpz_si_kronecker(pTHX_ SV * a, mpz_t * b) {
- return newSViv(mpz_si_kronecker(SvIV(a), *b));
-}
-
-SV * Rmpz_ui_kronecker(pTHX_ SV * a, mpz_t * b) {
- return newSViv(mpz_ui_kronecker(SvUV(a), *b));
-}
-
-SV * Rmpz_remove(pTHX_ mpz_t * rem, mpz_t * src1, mpz_t * src2) {
- return newSVuv(mpz_remove(*rem, *src1, *src2));
-}
-
-void Rmpz_fac_ui(pTHX_ mpz_t * fac, SV * b) {
- mpz_fac_ui(*fac, SvUV(b));
-}
-
-#if __GNU_MP_VERSION > 5 || (__GNU_MP_VERSION == 5 && __GNU_MP_VERSION_MINOR >= 1)
-
-void Rmpz_2fac_ui(pTHX_ mpz_t * fac, SV * b) {
- mpz_2fac_ui(*fac, SvUV(b));
-}
-
-void Rmpz_mfac_uiui(pTHX_ mpz_t * fac, SV * b, SV * c) {
- mpz_mfac_uiui(*fac, SvUV(b), SvUV(c));
-}
-
-void Rmpz_primorial_ui(pTHX_ mpz_t * fac, SV * b) {
- mpz_primorial_ui(*fac, SvUV(b));
-}
-
-#else
-
-void Rmpz_2fac_ui(pTHX_ mpz_t * fac, SV * b) {
- croak("Rmpz_2fac_ui not implemented - gmp-5.1.0 (or later) is needed; we have only gmp-%s", gmp_version);
-}
-
-void Rmpz_mfac_uiui(pTHX_ mpz_t * fac, SV * b, SV * c) {
- croak("Rmpz_mfac_uiui not implemented - gmp-5.1.0 (or later) is needed; we have only gmp-%s", gmp_version);
-}
-
-void Rmpz_primorial_ui(pTHX_ mpz_t * fac, SV * b) {
- croak("Rmpz_primorial_ui not implemented - gmp-5.1.0 (or later) is needed; we have only gmp-%s", gmp_version);
-}
-
-#endif
-
-void Rmpz_bin_ui(pTHX_ mpz_t * dest, mpz_t * n, SV * d) {
- mpz_bin_ui(*dest, *n, SvUV(d));
-}
-
-void Rmpz_bin_uiui(pTHX_ mpz_t * dest, SV * n, SV * d) {
- mpz_bin_uiui(*dest, SvUV(n), SvUV(d));
-}
-
-void Rmpz_fib_ui(pTHX_ mpz_t * dest, SV * b) {
- mpz_fib_ui(*dest, SvUV(b));
-}
-
-void Rmpz_fib2_ui(pTHX_ mpz_t * fn, mpz_t * fnsub1, SV * b) {
- mpz_fib2_ui(*fn, *fnsub1, SvUV(b));
-}
-
-void Rmpz_lucnum_ui(pTHX_ mpz_t * dest, SV * b) {
- mpz_lucnum_ui(*dest, SvUV(b));
-}
-
-void Rmpz_lucnum2_ui(pTHX_ mpz_t * ln, mpz_t * lnsub1, SV * b) {
- mpz_lucnum2_ui(*ln, *lnsub1, SvUV(b));
-}
-
-int Rmpz_cmp(mpz_t * n, mpz_t * d) {
- return mpz_cmp(*n, *d );
-}
-
-SV * Rmpz_cmp_d(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_cmp_d(*n, SvNV(d)));
-}
-
-SV * Rmpz_cmp_si(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_cmp_si(*n, SvIV(d)));
-}
-
-SV * Rmpz_cmp_ui(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_cmp_ui(*n, SvUV(d)));
-}
-
-int Rmpz_cmpabs(mpz_t * n, mpz_t * d) {
- return mpz_cmpabs(*n, *d );
-}
-
-SV * Rmpz_cmpabs_d(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_cmpabs_d(*n, SvNV(d)));
-}
-
-SV * Rmpz_cmpabs_ui(pTHX_ mpz_t * n, SV * d) {
- return newSViv(mpz_cmpabs_ui(*n, SvUV(d)));
-}
-
-int Rmpz_sgn(mpz_t * n) {
- return mpz_sgn(*n);
-}
-
-void Rmpz_and(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_and(*dest, *src1, *src2 );
-}
-
-void Rmpz_ior(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_ior(*dest, *src1, *src2 );
-}
-
-void Rmpz_xor(pTHX_ mpz_t * dest, mpz_t * src1, mpz_t * src2) {
- mpz_xor(*dest, *src1, *src2 );
-}
-
-void Rmpz_com(pTHX_ mpz_t * dest, mpz_t * src) {
- mpz_com(*dest, *src );
-}
-
-int Rmpz_popcount(mpz_t * in) {
- return mpz_popcount(*in);
-}
-
-int Rmpz_hamdist(mpz_t * dest, mpz_t * src) {
- return mpz_hamdist(*dest, *src );
-}
-
-SV * Rmpz_scan0(pTHX_ mpz_t * n, SV * start_bit) {
- return newSVuv(mpz_scan0(*n, SvUV(start_bit)));
-}
-
-SV * Rmpz_scan1(pTHX_ mpz_t * n, SV * start_bit) {
- return newSVuv(mpz_scan1(*n, SvUV(start_bit)));
-}
-
-void Rmpz_setbit(pTHX_ mpz_t * num, SV * bit_index) {
- mpz_setbit(*num, SvUV(bit_index));
-}
-
-void Rmpz_clrbit(pTHX_ mpz_t * num, SV * bit_index) {
- mpz_clrbit(*num, SvUV(bit_index));
-}
-
-SV * Rmpz_tstbit(pTHX_ mpz_t * num, SV * bit_index) {
- return newSViv(mpz_tstbit(*num, SvUV(bit_index)));
-}
-
-/* Turn a binary string into an mpz_t */
-void Rmpz_import(pTHX_ mpz_t * rop, SV * count, SV * order, SV * size, SV * endian, SV * nails, SV * op){
- mpz_import(*rop, SvUV(count), SvIV(order), SvIV(size), SvIV(endian), SvUV(nails), SvPV_nolen(op));
-}
-
-/* Return an mpz_t to a binary string */
-SV * Rmpz_export(pTHX_ SV * order, SV * size, SV * endian, SV * nails, mpz_t * number) {
- SV * outsv;
- char * out;
- size_t * cptr, count;
-
- cptr = &count;
- count = mpz_sizeinbase(*number, 2);
-
- Newz(1, out, count / 8 + 7, char);
- if(out == NULL) croak("Failed to allocate memory in Rmpz_export function");
-
- mpz_export(out, cptr, SvIV(order), SvIV(size), SvIV(endian), SvIV(nails), *number);
- outsv = newSVpv(out, count);
- Safefree(out);
- return outsv;
-}
-
-int Rmpz_fits_ulong_p(mpz_t * in) {
- return mpz_fits_ulong_p(*in);
-}
-
-int Rmpz_fits_slong_p(mpz_t * in) {
- return mpz_fits_slong_p(*in);
-}
-
-int Rmpz_fits_uint_p(mpz_t * in) {
- return mpz_fits_uint_p(*in);
-}
-
-int Rmpz_fits_sint_p(mpz_t * in) {
- return mpz_fits_sint_p(*in);
-}
-
-int Rmpz_fits_ushort_p(mpz_t * in) {
- return mpz_fits_ushort_p(*in);
-}
-
-int Rmpz_fits_sshort_p(mpz_t * in) {
- return mpz_fits_sshort_p(*in);
-}
-
-int Rmpz_odd_p(mpz_t * in) {
- return mpz_odd_p(*in);
-}
-
-int Rmpz_even_p(mpz_t * in) {
- return mpz_even_p(*in);
-}
-
-SV * Rmpz_size(pTHX_ mpz_t * in) {
- return newSVuv(mpz_size(*in));
-}
-
-SV * Rmpz_sizeinbase(pTHX_ mpz_t * in, SV * base) {
- if(SvIV(base) < 2 || SvIV(base) > 62) croak("Rmpz_sizeinbase handles only bases in the range 2..62");
- return newSVuv(mpz_sizeinbase(*in, (int)SvIV(base)));
-}
-
-void Rsieve_gmp(pTHX_ int x_arg, int a, mpz_t *number) {
-dXSARGS;
-unsigned short *v, *addon, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
-unsigned long init, leap, abits, asize, i, size, b, imax, k, x = x_arg;
-
-if(sizeof(short) != 2) croak("The sieve_gmp function is unsuitable for this architecture.\nContact the author and he may do something about it.");
-if(a & 1) croak("max_add must be even in sieve_gmp function");
-if(x & 1) croak("max_prime must be even in sieve_gmp function");
-
-if(!mpz_tstbit(*number, 0)) croak("candidate must be odd in sieve_gmp function");
-
-abits = (a / 2) + 1;
-
-if(!(abits % 16)) asize = abits / 16;
-else asize = (abits / 16) + 1;
-
-Newz(1, addon, asize, unsigned short);
-if(addon == NULL) croak("1: Unable to allocate memory in sieve_gmp function");
-
-for(i = 0; i < asize; ++i) addon[i] = 65535;
-
-imax = sqrt(x - 1) / 2;
-
-b = (x + 1) / 2;
-
-if(!(b % 16)) size = b / 16;
-else size = (b / 16) + 1;
-
-Newz(2, v, size, unsigned short);
-if(v == NULL) croak("2: Unable to allocate memory in sieve_gmp function");
-
-for(i = 1; i < size; ++i) v[i] = 65535;
-v[0] = 65534;
-
-for(i = 0; i <= imax; ++i) {
-
- if(v[i / 16] & (1 << (i % 16))) {
- leap = (2 * i) + 1;
- k = 2 * i * (i + 1);
- while(k < b) {
- v[k / 16] &= set[k % 16];
- k += leap;
- }
- }
-}
-
-size = 0;
-sp = mark;
-
-for(i = 0; i < b; ++i) {
- if(v[i / 16] & (1 << (i % 16))) {
- leap = 2 * i + 1;
- init = mpz_fdiv_ui(*number, leap);
- if(init) {
- if(init & 1) init = (leap - init) / 2;
- else init = leap - (init / 2);
- }
- while(init < abits) {
- addon[init / 16] &= set[init % 16];
- init += leap;
- }
- }
- }
-
-Safefree(v);
-
-for(i = 0; i < abits; ++i) {
- if(addon[i / 16] & (1 << (i % 16))) {
- XPUSHs(sv_2mortal(newSViv(2 * i)));
- ++size;
- }
- }
-
-Safefree(addon);
-
-PUTBACK;
-XSRETURN(size);
-
-}
-
-SV * Rfermat_gmp(pTHX_ mpz_t * num, SV * base){
- mpz_t b, num_less_1;
-
- mpz_init_set_ui(b, SvUV(base));
- mpz_init_set(num_less_1, *num);
- mpz_sub_ui(num_less_1, num_less_1, 1);
- mpz_powm(b, b, num_less_1, *num);
-
- if(!mpz_cmp_si(b, 1)) {
- mpz_clear(b);
- mpz_clear(num_less_1);
- return newSViv(1);
- }
-
- mpz_clear(b);
- mpz_clear(num_less_1);
- return newSViv(0);
-}
-
-SV * Rrm_gmp(pTHX_ mpz_t * num, SV * base){
- mpz_t c_less, r, y, bb;
- unsigned long i, s = 0, b = SvUV(base);
-
- mpz_init(c_less);
- mpz_init(r);
- mpz_init(y);
-
- mpz_sub_ui(c_less, *num, 1);
- mpz_set(r, c_less);
- mpz_init_set_ui(bb, b);
-
- while(mpz_even_p(r)) {
- mpz_tdiv_q_2exp(r, r, 1);
- ++s;
- }
-
- mpz_powm(y, bb, r, *num);
- mpz_clear(r);
- mpz_clear(bb);
- if(mpz_cmp_ui(y, 1) && mpz_cmp(y, c_less)) {
- for(i = 0; i < s; ++i) {
- mpz_powm_ui(y, y, 2, *num);
- if(!mpz_cmp_ui(y, 1)) {
- mpz_clear(c_less);
- mpz_clear(y);
- return 0;
- }
- if(!mpz_cmp(y, c_less)) break;
- }
- if(mpz_cmp(y, c_less)) {
- mpz_clear(c_less);
- mpz_clear(y);
- return newSViv(0);
- }
- }
-
- mpz_clear(c_less);
- mpz_clear(y);
- return newSVuv(1);
-}
-
-SV * _Rmpz_out_str(pTHX_ mpz_t * p, SV * base) {
- unsigned long ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- ret = mpz_out_str(NULL, SvUV(base), *p);
- fflush(stdout);
- return newSVuv(ret);
-}
-
-SV * _Rmpz_out_strS(pTHX_ mpz_t * p, SV * base, SV * suff) {
- unsigned long ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- ret = mpz_out_str(NULL, SvUV(base), *p);
- printf("%s", SvPV_nolen(suff));
- fflush(stdout);
- return newSVuv(ret);
-}
-
-SV * _Rmpz_out_strP(pTHX_ SV * pre, mpz_t * p, SV * base) {
- unsigned long ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- printf("%s", SvPV_nolen(pre));
- ret = mpz_out_str(NULL, SvUV(base), *p);
- fflush(stdout);
- return newSVuv(ret);
-}
-
-SV * _Rmpz_out_strPS(pTHX_ SV * pre, mpz_t * p, SV * base, SV * suff) {
- unsigned long ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- printf("%s", SvPV_nolen(pre));
- ret = mpz_out_str(NULL, SvUV(base), *p);
- printf("%s", SvPV_nolen(suff));
- fflush(stdout);
- return newSVuv(ret);
-}
-
-SV * _TRmpz_out_str(pTHX_ FILE * stream, SV * base, mpz_t * p) {
- size_t ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- ret = mpz_out_str(stream, (int)SvIV(base), *p);
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * _TRmpz_out_strS(pTHX_ FILE * stream, SV * base, mpz_t * p, SV * suff) {
- size_t ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- ret = mpz_out_str(stream, (int)SvIV(base), *p);
- fflush(stream);
- fprintf(stream, "%s", SvPV_nolen(suff));
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * _TRmpz_out_strP(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p) {
- size_t ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- fprintf(stream, "%s", SvPV_nolen(pre));
- fflush(stream);
- ret = mpz_out_str(stream, (int)SvIV(base), *p);
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * _TRmpz_out_strPS(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p, SV * suff) {
- size_t ret;
- if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
- croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
- fprintf(stream, "%s", SvPV_nolen(pre));
- fflush(stream);
- ret = mpz_out_str(stream, (int)SvIV(base), *p);
- fflush(stream);
- fprintf(stream, "%s", SvPV_nolen(suff));
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * Rmpz_inp_str(pTHX_ mpz_t * p, SV * base) {
- size_t ret;
- if(SvUV(base) == 1 || SvUV(base) > 62)
- croak("2nd argument supplied to Rmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
- ret = mpz_inp_str(*p, NULL, SvUV(base));
- /* fflush(stdin); */
- return newSVuv(ret);
-}
-
-SV * TRmpz_inp_str(pTHX_ mpz_t * p, FILE * stream, SV * base) {
- size_t ret;
- if(SvUV(base) == 1 || SvUV(base) > 62)
- croak("4th argument supplied to TRmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
- ret = mpz_inp_str(*p, stream, (int)SvIV(base));
- /* fflush(stream); */
- return newSVuv(ret);
-}
-
-void eratosthenes(pTHX_ SV * x_arg) {
-dXSARGS;
-
-unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
-unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
-
-if(x & 1) croak("max_num argument must be even in eratosthenes function");
-
-imax = sqrt(x - 1) / 2;
-
-b = (x + 1) / 2;
-
-if(!(b % 16)) size = b / 16;
-else size = (b / 16) + 1;
-
-Newz(2, v, size, unsigned short);
-if(v == NULL) croak("2: Unable to allocate memory in eratosthenes function");
-
-for(i = 1; i < size; ++i) v[i] = 65535;
-v[0] = 65534;
-
-for(i = 0; i <= imax; ++i) {
-
- if(v[i / 16] & (1 << (i % 16))) {
- leap = (2 * i) + 1;
- k = 2 * i * (i + 1);
- while(k < b) {
- v[k / 16] &= set[k % 16];
- k += leap;
- }
- }
-}
-
-size = 1;
-sp = mark;
-XPUSHs(sv_2mortal(newSVuv(2)));
-
-for(i = 0; i < b; ++i) {
- if(v[i / 16] & (1 << (i % 16))) {
- XPUSHs(sv_2mortal(newSVuv(2 * i + 1)));
- ++size;
- }
- }
-
-Safefree(v);
-
-PUTBACK;
-XSRETURN(size);
-
-}
-
-
-SV * trial_div_ul(pTHX_ mpz_t * num, SV * x_arg) {
-
- unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
- unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
-
- if(x & 1) croak("Second argument supplied to trial_div_ul() must be even");
-
- imax = sqrt(x - 1) / 2;
-
- b = (x + 1) / 2;
-
- if(!(b % 16)) size = b / 16;
- else size = (b / 16) + 1;
-
- Newz(2, v, size, unsigned short);
- if(v == NULL) croak("2: Unable to allocate memory in trial_div_ul() function");
-
- for(i = 1; i < size; ++i) v[i] = 65535;
- v[0] = 65534;
-
- for(i = 0; i <= imax; ++i) {
-
- if(v[i / 16] & (1 << (i % 16))) {
- leap = (2 * i) + 1;
- k = 2 * i * (i + 1);
- while(k < b) {
- v[k / 16] &= set[k % 16];
- k += leap;
- }
- }
- }
-
- if(mpz_divisible_ui_p(*num, 2)) {
- Safefree(v);
- return newSViv(2);
- }
-
- for(i = 0; i < b; ++i) {
- if(v[i / 16] & (1 << (i % 16))) {
- if(mpz_divisible_ui_p(*num, 2 * i + 1)) {
- Safefree(v);
- return newSViv(2 * i + 1);
- }
- }
- }
-
- Safefree(v);
-
- return newSViv(1);
-}
-
-/* Next 2 functions became available with GMP-4.2 */
-
-void Rmpz_rootrem(pTHX_ mpz_t * root, mpz_t * rem, mpz_t * u, SV * d) {
- mpz_rootrem(*root, *rem, *u, (unsigned long)SvUV(d));
-}
-
-void Rmpz_combit(pTHX_ mpz_t * num, SV * bitpos) {
- mpz_combit(*num, (unsigned long)SvUV(bitpos));
-}
-
-/* Finish typemapping - typemap 1st arg only */
-
-SV * overload_mul(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
- const char *h;
-
- if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
-
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mul function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- }
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_mul");
- mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-#else
-
- if(SvUOK(b)) {
- mpz_mul_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- mpz_mul_si(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_mul");
- mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- if(strEQ(h, "Math::GMPz")) {
- mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- if(strEQ(h, "Math::MPFR")) {
- dSP;
- SV * ret;
- int count;
-
- ENTER;
-
- PUSHMARK(SP);
- XPUSHs(b);
- XPUSHs(a);
- XPUSHs(sv_2mortal(newSViv(1)));
- PUTBACK;
-
- count = call_pv("Math::MPFR::overload_mul", G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Error in Math::GMPz::overload_mul callback to Math::MPFR::overload_mul\n");
-
- ret = POPs;
-
- /* Avoid "Attempt to free unreferenced scalar" warning */
- SvREFCNT_inc(ret);
- LEAVE;
- return ret;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_mul");
-}
-
-SV * overload_add(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
- const char *h;
-
- if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
-
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_add function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- }
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_add");
- mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return obj_ref;
- }
- mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_add");
- mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- if(strEQ(h, "Math::GMPz")) {
- mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- if(strEQ(h, "Math::MPFR")) {
- dSP;
- SV * ret;
- int count;
-
- ENTER;
-
- PUSHMARK(SP);
- XPUSHs(b);
- XPUSHs(a);
- XPUSHs(sv_2mortal(newSViv(1)));
- PUTBACK;
-
- count = call_pv("Math::MPFR::overload_add", G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Error in Math::GMPz::overload_add callback to Math::MPFR::overload_add\n");
-
- ret = POPs;
-
- /* Avoid "Attempt to free unreferenced scalar" warning */
- SvREFCNT_inc(ret);
- LEAVE;
- return ret;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_add function");
-
-}
-
-SV * overload_sub(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
- const char *h;
-
- if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
-
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sub function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- }
-
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_sub");
- if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- if(third == &PL_sv_yes) {
- mpz_ui_sub(*mpz_t_obj, SvUV(b), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return obj_ref;
- }
- mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- if(third == &PL_sv_yes) {
- mpz_ui_sub(*mpz_t_obj, SvIV(b), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return obj_ref;
- }
- mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return obj_ref;
- }
- mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- if(third == &PL_sv_yes) mpz_neg(*mpz_t_obj, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_sub");
- if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
- if(sv_isobject(b)) {
- if(strEQ(h, "Math::GMPz")) {
- mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- if(strEQ(h, "Math::MPFR")) {
- dSP;
- SV * ret;
- int count;
-
- ENTER;
-
- PUSHMARK(SP);
- XPUSHs(b);
- XPUSHs(a);
- XPUSHs(sv_2mortal(&PL_sv_yes));
- PUTBACK;
-
- count = call_pv("Math::MPFR::overload_sub", G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Error in Math::GMPz::overload_sub callback to Math::MPFR::overload_sub\n");
-
- ret = POPs;
-
- /* Avoid "Attempt to free unreferenced scalar" warning */
- SvREFCNT_inc(ret);
- LEAVE;
- return ret;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_sub function");
-
-}
-
-SV * overload_div(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
- const char *h;
-
- if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
-
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_div function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- }
-
-
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_div");
- if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- if(third == &PL_sv_yes) {
- mpz_set_ui(*mpz_t_obj, SvUV(b));
- mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return obj_ref;
- }
- mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- if(third == &PL_sv_yes) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return obj_ref;
- }
- mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return obj_ref;
- }
- if(third == &PL_sv_yes) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return obj_ref;
- }
- mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- mpz_neg(*mpz_t_obj, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_div");
- if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- if(strEQ(h, "Math::GMPz")) {
- mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- if(strEQ(h, "Math::MPFR")) {
- dSP;
- SV * ret;
- int count;
-
- ENTER;
-
- PUSHMARK(SP);
- XPUSHs(b);
- XPUSHs(a);
- XPUSHs(sv_2mortal(&PL_sv_yes));
- PUTBACK;
-
- count = call_pv("Math::MPFR::overload_div", G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Error in Math::GMPz::overload_div callback to Math::MPFR::overload_div\n");
-
- ret = POPs;
-
- /* Avoid "Attempt to free unreferenced scalar" warning */
- SvREFCNT_inc(ret);
- LEAVE;
- return ret;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_div function");
-
-}
-
-SV * overload_mod (pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t *mpz_t_obj;
- SV * obj_ref, * obj;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mod function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_mod");
- if(third == &PL_sv_yes) {
- mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
- return obj_ref;
- }
- mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- if(third == &PL_sv_yes) {
- mpz_set_ui(*mpz_t_obj, SvUV(b));
- mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
- return obj_ref;
- }
- mpz_mod_ui(*mpz_t_obj, *a, SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- if(third == &PL_sv_yes) {
- mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
- return obj_ref;
- }
- mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- if(third == &PL_sv_yes) {
- mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
- return obj_ref;
- }
- mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak(" Invalid string supplied to Math::GMPz::overload_mod");
- if(third == &PL_sv_yes) {
- mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
- return obj_ref;
- }
- mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_mod(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_mod function");
-}
-
-SV * overload_string(pTHX_ mpz_t * p, SV * second, SV * third) {
- char * out;
- SV * outsv;
-
- New(2, out, mpz_sizeinbase(*p, 10) + 3, char);
- if(out == NULL) croak("Failed to allocate memory in overload_string function");
-
- mpz_get_str(out, 10, *p);
- outsv = newSVpv(out, 0);
- Safefree(out);
- return outsv;
-}
-
-SV * overload_copy(pTHX_ mpz_t * p, SV * second, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_copy function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
-
- mpz_init_set(*mpz_t_obj, *p);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * overload_abs(pTHX_ mpz_t * p, SV * second, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_abs function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- mpz_abs(*mpz_t_obj, *p);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * overload_lshift(pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_lshift function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- if(SvUOK(b)) {
- mpz_mul_2exp(*mpz_t_obj, *a, SvUV(b));
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_lshift");
- mpz_mul_2exp(*mpz_t_obj, *a, SvUV(b));
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_lshift");
-}
-
-SV * overload_rshift(pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_rshift function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- if(SvUOK(b)) {
- mpz_tdiv_q_2exp(*mpz_t_obj, *a, SvUV(b));
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_rshift");
- mpz_tdiv_q_2exp(*mpz_t_obj, *a, SvUV(b));
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_rshift");
-}
-
-SV * overload_pow(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- if(third == &PL_sv_yes)
- croak("Invalid third argument (&PL_sv_yes) supplied to Math::GMPz::overload_pow function");
-
- if(!sv_isobject(b)) {
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_pow function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- }
-
- if(SvUOK(b)) {
- mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))) , SvUV(b));
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_pow");
- mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::MPFR")) {
- dSP;
- SV * ret;
- int count;
-
- ENTER;
-
- PUSHMARK(SP);
- XPUSHs(b);
- XPUSHs(a);
- XPUSHs(sv_2mortal(&PL_sv_yes));
- PUTBACK;
-
- count = call_pv("Math::MPFR::overload_pow", G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Error in Math::GMPq:overload_pow callback to Math::MPFR::overload_pow\n");
-
- ret = POPs;
-
- /* Avoid "Attempt to free unreferenced scalar" warning */
- SvREFCNT_inc(ret);
- LEAVE;
- return ret;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_pow. It takes only signed/unsigned long or Math::MPFR object as exponent");
-}
-
-SV * overload_sqrt(pTHX_ mpz_t * p, SV * second, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sqrt function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- if(mpz_cmp_ui(*p, 0) < 0) croak("Negative value supplied as argument to overload_sqrt");
- mpz_sqrt(*mpz_t_obj, *p);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * overload_and(pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_and function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_and");
- mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- mpz_set_ui(*mpz_t_obj, SvUV(b));
- mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#endif
-
- mpz_set_d(*mpz_t_obj, SvNV(b));
- mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_and");
- mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_and(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_and");
-}
-
-SV * overload_ior(pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_ior function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_ior");
- mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- mpz_set_ui(*mpz_t_obj, SvUV(b));
- mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_ior");
- mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_ior(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_ior");
-}
-
-SV * overload_xor(pTHX_ mpz_t * a, SV * b, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_xor function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_xor");
- mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#else
- if(SvUOK(b)) {
- mpz_set_ui(*mpz_t_obj, SvUV(b));
- mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvIOK(b)) {
- mpz_set_si(*mpz_t_obj, SvIV(b));
- mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_set_str(*mpz_t_obj, buffer, 10);
-#else
- mpz_set_d(*mpz_t_obj, SvNV(b));
-#endif
- mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(SvPOK(b)) {
- if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_xor");
- mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
- return obj_ref;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_xor(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return obj_ref;
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_xor");
-}
-
-SV * overload_com(pTHX_ mpz_t * p, SV * second, SV * third) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- New(1, mpz_t_obj, 1, mpz_t);
- if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_com function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, "Math::GMPz");
- mpz_init(*mpz_t_obj);
-
- mpz_com(*mpz_t_obj, *p);
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * overload_gt(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_gt");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_gt");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret > 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_gt");
-}
-
-SV * overload_gte(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_gte");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_gte");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret >= 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_gte");
-}
-
-SV * overload_lt(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_lt");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_lt");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret < 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_lt");
-}
-
-SV * overload_lte(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_lte");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_lte");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret <= 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_lte");
-}
-
-SV * overload_spaceship(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_spaceship");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- return newSViv(ret);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- return newSViv(ret);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- return newSViv(ret);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- return newSViv(ret);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_spaceship");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- return newSViv(ret);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return newSViv(ret);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_spaceship");
-}
-
-SV * overload_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_equiv");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_equiv");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret == 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_equiv");
-}
-
-SV * overload_not_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
- int ret;
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_not_equiv");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
-#else
- if(SvUOK(b)) {
- ret = mpz_cmp_ui(*a, SvUV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvIOK(b)) {
- ret = mpz_cmp_si(*a, SvIV(b));
- if(third == &PL_sv_yes) ret *= -1;
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
-#else
- ret = mpz_cmp_d(*a, SvNV(b));
-#endif
- if(third == &PL_sv_yes) ret *= -1;
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0))
- croak("Invalid string supplied to Math::GMPz::overload_not_equiv");
- ret = mpz_cmp(*a, t);
- mpz_clear(t);
- if(third == &PL_sv_yes) ret *= -1;
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- if(ret != 0) return newSViv(1);
- return newSViv(0);
- }
- }
-
- croak("Invalid argument supplied to Math::GMPz::overload_not_equiv");
-}
-
-SV * overload_not(pTHX_ mpz_t * a, SV * second, SV * third) {
- if(mpz_cmp_ui(*a, 0)) return newSViv(0);
- return newSViv(1);
-}
-
-/* Finish typemapping */
-
-SV * overload_xor_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_xor_eq");
- }
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_init_set_ui(t, SvUV(b));
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvIOK(b)) {
- mpz_init_set_si(t, SvIV(b));
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_xor_eq");
- }
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_xor_eq");
-}
-
-SV * overload_ior_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_ior_eq");
- }
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_init_set_ui(t, SvUV(b));
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvIOK(b)) {
- mpz_init_set_si(t, SvIV(b));
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_ior_eq");
- }
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_ior_eq");
-}
-
-SV * overload_and_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_and_eq");
- }
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_init_set_ui(t, SvUV(b));
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvIOK(b)) {
- mpz_init_set_si(t, SvIV(b));
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_and_eq");
- }
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_and_eq");
-}
-
-SV * overload_pow_eq(pTHX_ SV * a, SV * b, SV * third) {
- SvREFCNT_inc(a);
-
- if(SvUOK(b)) {
- mpz_pow_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_pow_eq");
- mpz_pow_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_pow_eq");
-}
-
-SV * overload_rshift_eq(pTHX_ SV * a, SV * b, SV * third) {
-
- SvREFCNT_inc(a);
-
- if(SvUOK(b)) {
- mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
- mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
-}
-
-SV * overload_lshift_eq(pTHX_ SV * a, SV * b, SV * third) {
-
- SvREFCNT_inc(a);
-
- if(SvUOK(b)) {
- mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
- mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
-}
-
-SV * overload_inc(pTHX_ SV * p, SV * second, SV * third) {
- SvREFCNT_inc(p);
- mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(p)))), *(INT2PTR(mpz_t *, SvIV(SvRV(p)))), 1);
- return p;
-}
-
-SV * overload_dec(pTHX_ SV * p, SV * second, SV * third) {
- SvREFCNT_inc(p);
- mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(p)))), *(INT2PTR(mpz_t *, SvIV(SvRV(p)))), 1);
- return p;
-}
-
-SV * overload_mod_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_mod_eq");
- }
- mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_mod_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) > 0) {
- mpz_mod_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
- mpz_init_set_si(t, SvNV(b));
- mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_mod_eq");
- }
- mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_mod_eq");
-}
-
-SV * get_refcnt(pTHX_ SV * s) {
- return newSVuv(SvREFCNT(s));
-}
-
-SV * overload_div_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_div_eq");
- }
- mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
- mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- mpz_neg(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_div_eq");
- }
- mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_div_eq function");
-
-}
-
-SV * overload_sub_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_sub_eq");
- }
- mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
- mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_sub_eq");
- }
- mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_sub_eq function");
-
-}
-
-SV * overload_add_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_add_eq");
- }
- mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- if(SvIV(b) >= 0) {
- mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
- mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak("Invalid string supplied to Math::GMPz::overload_add_eq");
- }
- mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_add_eq function");
-
-}
-
-SV * overload_mul_eq(pTHX_ SV * a, SV * b, SV * third) {
- mpz_t t;
-#ifdef USE_LONG_DOUBLE
- char buffer[50];
-#endif
-
- SvREFCNT_inc(a);
-
-#ifdef USE_64_BIT_INT
- if(SvIOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak(" Invalid string supplied to Math::GMPz::overload_mul_eq");
- }
- mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-#else
- if(SvUOK(b)) {
- mpz_mul_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
- return a;
- }
-
- if(SvIOK(b)) {
- mpz_mul_si(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
- return a;
- }
-#endif
-
- if(SvNOK(b)) {
-#ifdef USE_LONG_DOUBLE
- long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
- sprintf(buffer, "%.0Lf", ld);
- mpz_init_set_str(t, buffer, 10);
-#else
- mpz_init_set_d(t, SvNV(b));
-#endif
- mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(SvPOK(b)) {
- if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
- SvREFCNT_dec(a);
- croak(" Invalid string supplied to Math::GMPz::overload_mul_eq");
- }
- mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
- mpz_clear(t);
- return a;
- }
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz")) {
- mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- return a;
- }
- }
-
- SvREFCNT_dec(a);
- croak("Invalid argument supplied to Math::GMPz::overload_mul_eq");
-}
-
-SV * eratosthenes_string(pTHX_ SV * x_arg) {
-
-unsigned char *v, set[8] = {254,253,251,247,239,223,191,127};
-unsigned long leap, i, size, b, imax, k, x = (unsigned long)SvUV(x_arg);
-SV * ret;
-
-if(x & 1) croak("max_num argument must be even in eratosthenes_string()");
-
-imax = sqrt(x - 1) / 2;
-
-b = (x + 1) / 2;
-
-if(!(b % 8)) size = b / 8;
-else size = (b / 8) + 1;
-
-ret = NEWSV(0, size);
-
-for(i = 1; i < size; ++i) SvPVX(ret)[i] = 255;
-SvPVX(ret)[0] = 254;
-
-for(i = 0; i <= imax; ++i) {
-
- if(SvPVX(ret)[i / 8] & (1 << (i % 8))) {
- leap = (2 * i) + 1;
- k = 2 * i * (i + 1);
- while(k < b) {
- SvPVX(ret)[k / 8] &= set[k % 8];
- k += leap;
- }
- }
-}
-
-SvPOK_on(ret);
-SvCUR_set(ret, size);
-*SvEND(ret) = 0;
-
-return ret;
-
-}
-
-SV * gmp_v(pTHX) {
- return newSVpv(gmp_version, 0);
-}
-
-SV * wrap_gmp_printf(pTHX_ SV * a, SV * b) {
- int ret;
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz") ||
- strEQ(h, "Math::GMP") ||
- strEQ(h, "GMP::Mpz")) {
- ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- fflush(stdout);
- return newSViv(ret);
- }
- if(strEQ(h, "Math::GMPq") ||
- strEQ(h, "GMP::Mpq")) {
- ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
- fflush(stdout);
- return newSViv(ret);
- }
- if(strEQ(h, "Math::GMPf") ||
- strEQ(h, "GMP::Mpf")) {
- ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
- fflush(stdout);
- return newSViv(ret);
- }
-
- croak("Unrecognised object supplied as argument to Rmpz_printf");
- }
-
- if(SvUOK(b)) {
- ret = gmp_printf(SvPV_nolen(a), SvUV(b));
- fflush(stdout);
- return newSViv(ret);
- }
- if(SvIOK(b)) {
- ret = gmp_printf(SvPV_nolen(a), SvIV(b));
- fflush(stdout);
- return newSViv(ret);
- }
- if(SvNOK(b)) {
- ret = gmp_printf(SvPV_nolen(a), SvNV(b));
- fflush(stdout);
- return newSViv(ret);
- }
- if(SvPOK(b)) {
- ret = gmp_printf(SvPV_nolen(a), SvPV_nolen(b));
- fflush(stdout);
- return newSViv(ret);
- }
-
- croak("Unrecognised type supplied as argument to Rmpz_printf");
-}
-
-SV * wrap_gmp_fprintf(pTHX_ FILE * stream, SV * a, SV * b) {
- int ret;
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz") ||
- strEQ(h, "Math::GMP") ||
- strEQ(h, "GMP::Mpz")) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- fflush(stream);
- return newSViv(ret);
- }
- if(strEQ(h, "Math::GMPq") ||
- strEQ(h, "GMP::Mpq")) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
- fflush(stream);
- return newSViv(ret);
- }
- if(strEQ(h, "Math::GMPf") ||
- strEQ(h, "GMP::Mpf")) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
- fflush(stream);
- return newSViv(ret);
- }
-
- else croak("Unrecognised object supplied as argument to Rmpz_fprintf");
- }
-
- if(SvUOK(b)) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), SvUV(b));
- fflush(stream);
- return newSViv(ret);
- }
- if(SvIOK(b)) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), SvIV(b));
- fflush(stream);
- return newSViv(ret);
- }
- if(SvNOK(b)) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), SvNV(b));
- fflush(stream);
- return newSViv(ret);
- }
- if(SvPOK(b)) {
- ret = gmp_fprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
- fflush(stream);
- return newSViv(ret);
- }
-
- croak("Unrecognised type supplied as argument to Rmpz_fprintf");
-}
-
-SV * wrap_gmp_sprintf(pTHX_ SV * s, SV * a, SV * b, int buflen) {
- int ret;
- char *stream;
-
- Newx(stream, buflen, char);
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz") ||
- strEQ(h, "Math::GMP") ||
- strEQ(h, "GMP::Mpz")) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(strEQ(h, "Math::GMPq") ||
- strEQ(h, "GMP::Mpq")) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(strEQ(h, "Math::GMPf") ||
- strEQ(h, "GMP::Mpf")) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- croak("Unrecognised object supplied as argument to Rmpz_sprintf");
- }
-
- if(SvUOK(b)) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), SvUV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvIOK(b)) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), SvIV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvNOK(b)) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), SvNV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvPOK(b)) {
- ret = gmp_sprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- croak("Unrecognised type supplied as argument to Rmpz_sprintf");
-}
-
-SV * wrap_gmp_snprintf(pTHX_ SV * s, SV * bytes, SV * a, SV * b, int buflen) {
- int ret;
- char * stream;
-
- Newx(stream, buflen, char);
-
- if(sv_isobject(b)) {
- const char *h = HvNAME(SvSTASH(SvRV(b)));
- if(strEQ(h, "Math::GMPz") ||
- strEQ(h, "Math::GMP") ||
- strEQ(h, "GMP::Mpz")) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(strEQ(h, "Math::GMPq") ||
- strEQ(h, "GMP::Mpq")) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(strEQ(h, "Math::GMPf") ||
- strEQ(h, "GMP::Mpf")) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- croak("Unrecognised object supplied as argument to Rmpz_snprintf");
- }
-
- if(SvUOK(b)) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvUV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvIOK(b)) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvIV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvNOK(b)) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvNV(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- if(SvPOK(b)) {
- ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvPV_nolen(b));
- sv_setpv(s, stream);
- Safefree(stream);
- return newSViv(ret);
- }
-
- croak("Unrecognised type supplied as argument to Rmpz_snprintf");
-}
-
-SV * _itsa(pTHX_ SV * a) {
- if(SvUOK(a)) return newSVuv(1);
- if(SvIOK(a)) return newSVuv(2);
- if(SvNOK(a)) return newSVuv(3);
- if(SvPOK(a)) return newSVuv(4);
- if(sv_isobject(a)) {
- const char *h = HvNAME(SvSTASH(SvRV(a)));
- if(strEQ(h, "Math::GMPz")) return newSVuv(8);
- if(strEQ(h, "Math::GMP")) return newSVuv(9);
- }
- return newSVuv(0);
-}
-
-void Rmpz_urandomb(pTHX_ SV * p, ...) {
- dXSARGS;
- unsigned long q, i, thingies;
-
- thingies = items;
- q = SvUV(ST(thingies - 1));
-
- if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomb function");
-
- for(i = 0; i < q; ++i) {
- mpz_urandomb(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
- }
-
- XSRETURN(0);
-}
-
-void Rmpz_urandomm(pTHX_ SV * x, ...){
- dXSARGS;
- unsigned long q, i, thingies;
-
- thingies = items;
- q = SvUV(ST(thingies - 1));
-
- if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomm function");
-
- for(i = 0; i < q; ++i) {
- mpz_urandomm(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), *(INT2PTR(mpz_t *, SvIV(SvRV(ST(thingies - 2))))));
- }
-
- XSRETURN(0);
-}
-
-void Rmpz_rrandomb(pTHX_ SV * x, ...) {
- dXSARGS;
- unsigned long q, i, thingies;
-
- thingies = items;
- q = SvUV(ST(thingies - 1));
-
- if((q + 3) != thingies) croak ("Wrong args supplied to mpz_rrandomb function");
-
- for(i = 0; i < q; ++i) {
- mpz_rrandomb(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
- }
-
- XSRETURN(0);
-}
-
-SV * rand_init(pTHX_ SV * seed) {
- gmp_randstate_t * state;
- SV * obj_ref, * obj;
-
- New(1, state, 1, gmp_randstate_t);
- if(state == NULL) croak("Failed to allocate memory in rand_init function");
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
- gmp_randinit_default(*state);
- gmp_randseed(*state, *(INT2PTR(mpz_t *, SvIV(SvRV(seed)))));
- sv_setiv(obj, INT2PTR(IV, state));
- SvREADONLY_on(obj);
- return obj_ref;
- }
-
-void rand_clear(pTHX_ SV * p) {
- gmp_randclear(*(INT2PTR(gmp_randstate_t *, SvIV(SvRV(p)))));
- Safefree(INT2PTR(gmp_randstate_t *, SvIV(SvRV(p))));
- }
-
-int _has_longlong(void) {
-#ifdef USE_64_BIT_INT
- return 1;
-#else
- return 0;
-#endif
-}
-
-int _has_longdouble(void) {
-#ifdef USE_LONG_DOUBLE
- return 1;
-#else
- return 0;
-#endif
-}
-
-/* Has inttypes.h been included ? */
-int _has_inttypes(void) {
-#ifdef _MSC_VER
-return 0;
-#else
-#if defined USE_64_BIT_INT
-return 1;
-#else
-return 0;
-#endif
-#endif
-}
-
-SV * Rmpz_inp_raw(pTHX_ mpz_t * a, FILE * stream) {
- size_t ret = mpz_inp_raw(*a, stream);
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * Rmpz_out_raw(pTHX_ FILE * stream, mpz_t * a) {
- size_t ret = mpz_out_raw(stream, *a);
- fflush(stream);
- return newSVuv(ret);
-}
-
-SV * ___GNU_MP_VERSION(pTHX) {
- return newSVuv(__GNU_MP_VERSION);
-}
-
-SV * ___GNU_MP_VERSION_MINOR(pTHX) {
- return newSVuv(__GNU_MP_VERSION_MINOR);
-}
-
-SV * ___GNU_MP_VERSION_PATCHLEVEL(pTHX) {
- return newSVuv(__GNU_MP_VERSION_PATCHLEVEL);
-}
-
-SV * ___GNU_MP_RELEASE(pTHX) {
-#if defined(__GNU_MP_RELEASE)
- return newSVuv(__GNU_MP_RELEASE);
-#else
- return &PL_sv_undef;
-#endif
-}
-
-SV * ___GMP_CC(pTHX) {
-#ifdef __GMP_CC
- char * ret = __GMP_CC;
- return newSVpv(ret, 0);
-#else
- return &PL_sv_undef;
-#endif
-}
-
-SV * ___GMP_CFLAGS(pTHX) {
-#ifdef __GMP_CFLAGS
- char * ret = __GMP_CFLAGS;
- return newSVpv(ret, 0);
-#else
- return &PL_sv_undef;
-#endif
-}
-
-#if __GNU_MP_VERSION >= 5
-#ifndef __MPIR_VERSION
-void Rmpz_powm_sec(pTHX_ mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
- mpz_powm_sec(*dest, *base, *exp, *mod);
-}
-#else
-void Rmpz_powm_sec(pTHX_ mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
- croak("Rmpz_powm_sec not implemented by the mpir library");
-}
-#endif
-#else
-void Rmpz_powm_sec(pTHX_ mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
- croak("Rmpz_powm_sec not implemented - gmp-5 or later needed, this is gmp-%d", __GNU_MP_VERSION);
-}
-#endif
-
-int _using_mpir(void) {
-#ifdef __MPIR_VERSION
-return 1;
-#else
-return 0;
-#endif
-}
-
-SV * _Rmpz_NULL(pTHX) {
- mpz_t * mpz_t_obj;
- SV * obj_ref, * obj;
-
- mpz_t_obj = NULL;
- obj_ref = newSV(0);
- obj = newSVrv(obj_ref, NULL);
-
- sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
- SvREADONLY_on(obj);
- return obj_ref;
-}
-
-SV * _wrap_count(pTHX) {
- return newSVuv(PL_sv_count);
-}
-
-void Rprbg_ms(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
- mpz_t n, phi, pless1, qless1, mod, keep;
- unsigned long e, k, bign, r, its, i, r_shift, check;
- double kdoub;
- gmp_randstate_t state;
-
- mpz_init(n);
- mpz_init(phi);
- mpz_init(pless1);
- mpz_init(qless1);
-
- mpz_sub_ui(qless1, *q, 1);
- mpz_sub_ui(pless1, *p, 1);
-
- mpz_mul(n, *p, *q);
-
- mpz_mul(phi, pless1, qless1);
- mpz_clear(pless1);
- mpz_clear(qless1);
-
- bign = mpz_sizeinbase(n, 2);
- e = bign / 80;
-
- while(1) {
- if(e < 1) croak("You need to choose larger primes P and Q. The product of P-1 and Q-1 needs to be at least an 80-bit number");
- if(mpz_gcd_ui(NULL, phi, e) == 1) break;
- --e;
- if(e < 3) croak("The chosen primes are unsuitable in prbg_ms() function");
- }
-
- mpz_clear(phi);
-
- kdoub = (double) 2 / (double) e;
- kdoub = (double) 1 - kdoub;
- kdoub *= (double) bign;
- k = kdoub;
- r = bign - k;
-
- gmp_randinit_default(state);
- gmp_randseed(state, *seed);
- mpz_urandomb(*seed, state, r);
- gmp_randclear(state);
-
- r_shift = bits_required % k;
-
- if(r_shift) its = (bits_required / k) + 1;
- else its = bits_required / k;
-
- mpz_init(mod);
- mpz_init(keep);
- mpz_set_ui(*outref, 0);
- mpz_ui_pow_ui(mod, 2, k);
-
- for(i = 0; i < its; ++i) {
- mpz_powm_ui(*seed, *seed, e, n);
- mpz_mod(keep, *seed, mod);
- mpz_mul_2exp(*outref, *outref, k);
- mpz_add(*outref, *outref, keep);
- mpz_fdiv_q_2exp(*seed, *seed, k);
- if(!i) check = k - mpz_sizeinbase(keep, 2);
- }
- mpz_clear(n);
- mpz_clear(keep);
- mpz_clear(mod);
-
- if(r_shift) mpz_fdiv_q_2exp(*outref, *outref, k - r_shift);
-
- if(check + mpz_sizeinbase(*outref, 2) != bits_required)
- croak("Bug in csprng() function");
-
-}
-
-void Rprbg_bbs(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
- mpz_t n, gcd, one;
- unsigned long i, k;
- gmp_randstate_t state;
-
- if(mpz_fdiv_ui(*p, 4) != 3) croak ("First prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
- if(mpz_fdiv_ui(*q, 4) != 3) croak ("Second prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
- mpz_init(n);
-
- mpz_mul(n, *p, *q);
-
- mpz_init(gcd);
- gmp_randinit_default(state);
- gmp_randseed(state, *seed);
- mpz_urandomm(*seed, state, n);
- gmp_randclear(state);
-
- while(1) {
- if(mpz_cmp_ui(*seed, 100) < 0)croak("Blum-Blum-Shub seed is ridiculously small. How did this happen ?");
- mpz_gcd(gcd, *seed, n);
- if(!mpz_cmp_ui(gcd, 1)) break;
- mpz_sub_ui(*seed, *seed, 1);
- }
-
- mpz_powm_ui(*seed, *seed, 2, n);
-
- mpz_init_set_ui(*outref, 0);
- mpz_init_set_ui(one, 1);
-
- for(i = 0; i < bits_required; ++i) {
- mpz_powm_ui(*seed, *seed, 2, n);
- k = mpz_tstbit(*seed, 0);
- if(k) {
- mpz_mul_2exp(gcd, one, i);
- mpz_add(*outref, gcd, *outref);
- }
- }
-
- mpz_clear(n);
- mpz_clear(gcd);
- mpz_clear(one);
-
-}
-
-int Rmonobit(mpz_t * bitstream) {
- unsigned long len, i, count = 0;
-
- len = mpz_sizeinbase(*bitstream, 2);
-
- if(len > 20000) croak("Wrong size random sequence for monobit test");
- if(len < 19967) {
- warn("More than 33 leading zeroes in Rmonobit test\n");
- return 0;
- }
-
- count = mpz_popcount(*bitstream);
-
- if(count > 9654 && count < 10346) return 1;
- return 0;
-
-}
-
-int Rlong_run(mpz_t * bitstream) {
- unsigned long i, el, init = 0, count = 0, len, t;
-
- len = mpz_sizeinbase(*bitstream, 2);
-
- if(len > 20000) croak("Wrong size random sequence for Rlong_run test");
- if(len < 19967) {
- warn("More than 33 leading zeroes in long_run test\n");
- return 0;
- }
-
- el = mpz_tstbit(*bitstream, 0);
-
- for(i = 0; i < len; ++i) {
- t = mpz_tstbit(*bitstream, i);
- if(t == el) ++count;
- else {
- el = t;
- if(count > init) init = count;
- count = 1;
- }
- }
-
- if(init < 34 && count < 34) return 1;
- return 0;
-
-}
-
-int Rruns(mpz_t * bitstream) {
- int b[6] = {0,0,0,0,0,0}, g[6] = {0,0,0,0,0,0},
- len, count = 1, i, t, diff;
-
- len = mpz_sizeinbase(*bitstream, 2);
- diff = 20000 - len;
-
- if(len > 20000) croak("Wrong size random sequence for monobit test");
- if(len < 19967) {
- warn("More than 33 leading zeroes in runs test\n");
- return 0;
- }
-
- --len;
-
- for(i = 0; i < len; ++i) {
- t = mpz_tstbit(*bitstream, i);
- if(t == mpz_tstbit(*bitstream, i + 1)) ++ count;
- else {
- if(t) {
- if(count >= 6) ++b[5];
- else ++b[count - 1];
- }
- else {
- if(count >= 6) ++g[5];
- else ++g[count - 1];
- }
- count = 1;
- }
- }
-
- if(count >= 6) {
- if(mpz_tstbit(*bitstream, len)) {
- ++b[5];
- if(diff) ++g[diff - 1];
- }
- else ++g[5];
- }
- else {
- if(mpz_tstbit(*bitstream, len)) {
- ++b[count - 1];
- if(diff) ++g[diff - 1];
- }
- else {
- count += diff;
- if(count >= 6) ++g[5];
- else ++g[count - 1];
- }
- }
-
-
- if (
- b[0] <= 2267 || g[0] <= 2267 ||
- b[0] >= 2733 || g[0] >= 2733 ||
- b[1] <= 1079 || g[1] <= 1079 ||
- b[1] >= 1421 || g[1] >= 1421 ||
- b[2] <= 502 || g[2] <= 502 ||
- b[2] >= 748 || g[2] >= 748 ||
- b[3] <= 223 || g[3] <= 223 ||
- b[3] >= 402 || g[3] >= 402 ||
- b[4] <= 90 || g[4] <= 90 ||
- b[4] >= 223 || g[4] >= 223 ||
- b[5] <= 90 || g[5] <= 90 ||
- b[5] >= 223 || g[5] >= 223
- ) return 0;
-
- return 1;
-
-}
-
-int Rpoker (mpz_t * bitstream) {
- int counts[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
- len, i, st, diff;
- double n = 0;
-
- len = mpz_sizeinbase(*bitstream, 2);
-
- if(len > 20000) croak("Wrong size random sequence for poker test");
- if(len < 19967) {
- warn("More than 33 leading zeroes in poker test\n");
- return 0;
- }
-
-/* pad with trailing zeroes (if necessary) to achieve length of 20000 bits. */
- diff = 20000 - len;
- if(diff) mpz_mul_2exp(*bitstream, *bitstream, diff);
- if(mpz_sizeinbase(*bitstream, 2) != 20000) croak("Bug in bit sequence manipulation in poker() function");
-
- for(i = 0; i < 20000; i += 4) {
- st = mpz_tstbit(*bitstream, i) +
- (mpz_tstbit(*bitstream, i + 1) * 2) +
- (mpz_tstbit(*bitstream, i + 2) * 4) +
- (mpz_tstbit(*bitstream, i + 3) * 8);
- ++counts[st];
- }
-
-
- for(i = 0; i < 16; ++i) n += counts[i] * counts[i];
-
- n /= 5000;
- n *= 16;
- n -= 5000;
-
- if(n > 1.03 && n < 57.4) return 1;
-
- return 0;
-}
-
-SV * _get_xs_version(pTHX) {
- return newSVpv(XS_VERSION, 0);
-}
-
-SV * query_eratosthenes_string(pTHX_ int candidate, char * str) {
- int cand = candidate - 1;
- if(cand == 1) return newSVuv(1);
- if(cand & 1 || cand <= 0) return newSVuv(0);
- if(str[cand / 16] & 1 << (cand / 2) % 8)
- return newSVuv(1);
- return newSVuv(0);
-}
-
-MODULE = Math::GMPz PACKAGE = Math::GMPz
-
-PROTOTYPES: DISABLE
-
-
-SV *
-Rmpz_init_set_str_nobless (num, base)
- SV * num
- SV * base
-CODE:
- RETVAL = Rmpz_init_set_str_nobless (aTHX_ num, base);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init2_nobless (bits)
- SV * bits
-CODE:
- RETVAL = Rmpz_init2_nobless (aTHX_ bits);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_nobless ()
-CODE:
- RETVAL = Rmpz_init_nobless (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-Rmpz_init_set_nobless (p)
- mpz_t * p
-CODE:
- RETVAL = Rmpz_init_set_nobless (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_ui_nobless (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_ui_nobless (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_si_nobless (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_si_nobless (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_d_nobless (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_d_nobless (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init ()
-CODE:
- RETVAL = Rmpz_init (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-Rmpz_init_set (p)
- mpz_t * p
-CODE:
- RETVAL = Rmpz_init_set (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_ui (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_ui (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_si (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_si (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_d (p)
- SV * p
-CODE:
- RETVAL = Rmpz_init_set_d (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-_Rmpz_init_set_ld (p)
- SV * p
-CODE:
- RETVAL = _Rmpz_init_set_ld (aTHX_ p);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init_set_str (num, base)
- SV * num
- SV * base
-CODE:
- RETVAL = Rmpz_init_set_str (aTHX_ num, base);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_init2 (bits)
- SV * bits
-CODE:
- RETVAL = Rmpz_init2 (aTHX_ bits);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_get_str (p, base)
- mpz_t * p
- SV * base
-CODE:
- RETVAL = Rmpz_get_str (aTHX_ p, base);
-OUTPUT: RETVAL
-
-void
-DESTROY (p)
- mpz_t * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- DESTROY(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_clear (p)
- mpz_t * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_clear(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_clear_mpz (p)
- mpz_t * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_clear_mpz(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_clear_ptr (p)
- mpz_t * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_clear_ptr(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_realloc2 (integer, bits)
- mpz_t * integer
- SV * bits
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_realloc2(aTHX_ integer, bits);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set (copy, original)
- mpz_t * copy
- mpz_t * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_q (copy, original)
- mpz_t * copy
- mpq_t * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_q(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_f (copy, original)
- mpz_t * copy
- mpf_t * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_f(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_si (copy, original)
- mpz_t * copy
- SV * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_si(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_ui (copy, original)
- mpz_t * copy
- SV * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_ui(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_d (copy, original)
- mpz_t * copy
- SV * original
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_d(aTHX_ copy, original);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_set_str (copy, original, base)
- mpz_t * copy
- SV * original
- SV * base
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_set_str(aTHX_ copy, original, base);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_swap (a, b)
- mpz_t * a
- mpz_t * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_swap(aTHX_ a, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_get_ui (n)
- mpz_t * n
-CODE:
- RETVAL = Rmpz_get_ui (aTHX_ n);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_get_si (n)
- mpz_t * n
-CODE:
- RETVAL = Rmpz_get_si (aTHX_ n);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_get_d (n)
- mpz_t * n
-CODE:
- RETVAL = Rmpz_get_d (aTHX_ n);
-OUTPUT: RETVAL
-
-void
-Rmpz_get_d_2exp (n)
- mpz_t * n
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_get_d_2exp(aTHX_ n);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_getlimbn (p, n)
- mpz_t * p
- SV * n
-CODE:
- RETVAL = Rmpz_getlimbn (aTHX_ p, n);
-OUTPUT: RETVAL
-
-void
-Rmpz_add (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_add(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_add_ui (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_add_ui(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_sub (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_sub(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_sub_ui (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_sub_ui(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_ui_sub (dest, num, src)
- mpz_t * dest
- SV * num
- mpz_t * src
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_ui_sub(aTHX_ dest, num, src);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mul (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mul(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mul_si (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mul_si(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mul_ui (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mul_ui(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_addmul (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_addmul(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_addmul_ui (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_addmul_ui(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_submul (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_submul(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_submul_ui (dest, src, num)
- mpz_t * dest
- mpz_t * src
- SV * num
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_submul_ui(aTHX_ dest, src, num);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mul_2exp (dest, src1, b)
- mpz_t * dest
- mpz_t * src1
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mul_2exp(aTHX_ dest, src1, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_div_2exp (dest, src1, b)
- mpz_t * dest
- mpz_t * src1
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_div_2exp(aTHX_ dest, src1, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_neg (dest, src)
- mpz_t * dest
- mpz_t * src
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_neg(aTHX_ dest, src);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_abs (dest, src)
- mpz_t * dest
- mpz_t * src
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_abs(aTHX_ dest, src);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_cdiv_q (q, n, d)
- mpz_t * q
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_cdiv_q(aTHX_ q, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_cdiv_r (mod, n, d)
- mpz_t * mod
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_cdiv_r(aTHX_ mod, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_cdiv_qr (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_cdiv_qr(aTHX_ q, r, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_cdiv_q_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cdiv_q_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cdiv_r_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cdiv_r_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cdiv_qr_ui (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cdiv_qr_ui (aTHX_ q, r, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cdiv_ui (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cdiv_ui (aTHX_ n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_cdiv_q_2exp (q, n, b)
- mpz_t * q
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_cdiv_q_2exp(aTHX_ q, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_cdiv_r_2exp (r, n, b)
- mpz_t * r
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_cdiv_r_2exp(aTHX_ r, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fdiv_q (q, n, d)
- mpz_t * q
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fdiv_q(aTHX_ q, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_div (q, n, d)
- mpz_t * q
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_div(aTHX_ q, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fdiv_r (mod, n, d)
- mpz_t * mod
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fdiv_r(aTHX_ mod, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fdiv_qr (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fdiv_qr(aTHX_ q, r, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_divmod (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_divmod(aTHX_ q, r, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_fdiv_q_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_fdiv_q_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_div_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_div_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_fdiv_r_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_fdiv_r_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_fdiv_qr_ui (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_fdiv_qr_ui (aTHX_ q, r, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_divmod_ui (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_divmod_ui (aTHX_ q, r, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_fdiv_ui (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_fdiv_ui (aTHX_ n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_fdiv_q_2exp (q, n, b)
- mpz_t * q
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fdiv_q_2exp(aTHX_ q, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fdiv_r_2exp (r, n, b)
- mpz_t * r
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fdiv_r_2exp(aTHX_ r, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mod_2exp (r, n, b)
- mpz_t * r
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mod_2exp(aTHX_ r, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_tdiv_q (q, n, d)
- mpz_t * q
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_tdiv_q(aTHX_ q, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_tdiv_r (mod, n, d)
- mpz_t * mod
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_tdiv_r(aTHX_ mod, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_tdiv_qr (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_tdiv_qr(aTHX_ q, r, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_tdiv_q_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_tdiv_q_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_tdiv_r_ui (q, n, d)
- mpz_t * q
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_tdiv_r_ui (aTHX_ q, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_tdiv_qr_ui (q, r, n, d)
- mpz_t * q
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_tdiv_qr_ui (aTHX_ q, r, n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_tdiv_ui (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_tdiv_ui (aTHX_ n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_tdiv_q_2exp (q, n, b)
- mpz_t * q
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_tdiv_q_2exp(aTHX_ q, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_tdiv_r_2exp (r, n, b)
- mpz_t * r
- mpz_t * n
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_tdiv_r_2exp(aTHX_ r, n, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mod (r, n, d)
- mpz_t * r
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mod(aTHX_ r, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_mod_ui (r, n, d)
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_mod_ui (aTHX_ r, n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_divexact (dest, n, d)
- mpz_t * dest
- mpz_t * n
- mpz_t * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_divexact(aTHX_ dest, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_divexact_ui (dest, n, d)
- mpz_t * dest
- mpz_t * n
- SV * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_divexact_ui(aTHX_ dest, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmpz_divisible_p (n, d)
- mpz_t * n
- mpz_t * d
-
-SV *
-Rmpz_divisible_ui_p (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_divisible_ui_p (aTHX_ n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_divisible_2exp_p (n, b)
- mpz_t * n
- SV * b
-CODE:
- RETVAL = Rmpz_divisible_2exp_p (aTHX_ n, b);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_congruent_p (n, c, d)
- mpz_t * n
- mpz_t * c
- mpz_t * d
-CODE:
- RETVAL = Rmpz_congruent_p (aTHX_ n, c, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_congruent_ui_p (n, c, d)
- mpz_t * n
- SV * c
- SV * d
-CODE:
- RETVAL = Rmpz_congruent_ui_p (aTHX_ n, c, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_congruent_2exp_p (n, c, d)
- mpz_t * n
- mpz_t * c
- SV * d
-CODE:
- RETVAL = Rmpz_congruent_2exp_p (aTHX_ n, c, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_powm (dest, base, exp, mod)
- mpz_t * dest
- mpz_t * base
- mpz_t * exp
- mpz_t * mod
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_powm(aTHX_ dest, base, exp, mod);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_powm_ui (dest, base, exp, mod)
- mpz_t * dest
- mpz_t * base
- SV * exp
- mpz_t * mod
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_powm_ui(aTHX_ dest, base, exp, mod);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_pow_ui (dest, base, exp)
- mpz_t * dest
- mpz_t * base
- SV * exp
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_pow_ui(aTHX_ dest, base, exp);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_ui_pow_ui (dest, base, exp)
- mpz_t * dest
- SV * base
- SV * exp
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_ui_pow_ui(aTHX_ dest, base, exp);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_root (r, n, d)
- mpz_t * r
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_root (aTHX_ r, n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_sqrt (r, n)
- mpz_t * r
- mpz_t * n
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_sqrt(aTHX_ r, n);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_sqrtrem (root, rem, src)
- mpz_t * root
- mpz_t * rem
- mpz_t * src
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_sqrtrem(aTHX_ root, rem, src);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmpz_perfect_power_p (in)
- mpz_t * in
-
-int
-Rmpz_perfect_square_p (in)
- mpz_t * in
-
-SV *
-Rmpz_probab_prime_p (cand, reps)
- mpz_t * cand
- SV * reps
-CODE:
- RETVAL = Rmpz_probab_prime_p (aTHX_ cand, reps);
-OUTPUT: RETVAL
-
-void
-Rmpz_nextprime (prime, init)
- mpz_t * prime
- mpz_t * init
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_nextprime(aTHX_ prime, init);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_gcd (gcd, src1, src2)
- mpz_t * gcd
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_gcd(aTHX_ gcd, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_gcd_ui (gcd, n, d)
- mpz_t * gcd
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_gcd_ui (aTHX_ gcd, n, d);
-OUTPUT: RETVAL
-
-void
-Rmpz_gcdext (g, s, t, a, b)
- mpz_t * g
- mpz_t * s
- mpz_t * t
- mpz_t * a
- mpz_t * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_gcdext(aTHX_ g, s, t, a, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_lcm (lcm, src1, src2)
- mpz_t * lcm
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_lcm(aTHX_ lcm, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_lcm_ui (lcm, src1, src2)
- mpz_t * lcm
- mpz_t * src1
- SV * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_lcm_ui(aTHX_ lcm, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmpz_invert (inv, src1, src2)
- mpz_t * inv
- mpz_t * src1
- mpz_t * src2
-
-int
-Rmpz_jacobi (a, b)
- mpz_t * a
- mpz_t * b
-
-int
-Rmpz_legendre (a, b)
- mpz_t * a
- mpz_t * b
-
-int
-Rmpz_kronecker (a, b)
- mpz_t * a
- mpz_t * b
-
-SV *
-Rmpz_kronecker_si (a, b)
- mpz_t * a
- SV * b
-CODE:
- RETVAL = Rmpz_kronecker_si (aTHX_ a, b);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_kronecker_ui (a, b)
- mpz_t * a
- SV * b
-CODE:
- RETVAL = Rmpz_kronecker_ui (aTHX_ a, b);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_si_kronecker (a, b)
- SV * a
- mpz_t * b
-CODE:
- RETVAL = Rmpz_si_kronecker (aTHX_ a, b);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_ui_kronecker (a, b)
- SV * a
- mpz_t * b
-CODE:
- RETVAL = Rmpz_ui_kronecker (aTHX_ a, b);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_remove (rem, src1, src2)
- mpz_t * rem
- mpz_t * src1
- mpz_t * src2
-CODE:
- RETVAL = Rmpz_remove (aTHX_ rem, src1, src2);
-OUTPUT: RETVAL
-
-void
-Rmpz_fac_ui (fac, b)
- mpz_t * fac
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fac_ui(aTHX_ fac, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_2fac_ui (fac, b)
- mpz_t * fac
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_2fac_ui(aTHX_ fac, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_mfac_uiui (fac, b, c)
- mpz_t * fac
- SV * b
- SV * c
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_mfac_uiui(aTHX_ fac, b, c);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_primorial_ui (fac, b)
- mpz_t * fac
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_primorial_ui(aTHX_ fac, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_bin_ui (dest, n, d)
- mpz_t * dest
- mpz_t * n
- SV * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_bin_ui(aTHX_ dest, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_bin_uiui (dest, n, d)
- mpz_t * dest
- SV * n
- SV * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_bin_uiui(aTHX_ dest, n, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fib_ui (dest, b)
- mpz_t * dest
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fib_ui(aTHX_ dest, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_fib2_ui (fn, fnsub1, b)
- mpz_t * fn
- mpz_t * fnsub1
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_fib2_ui(aTHX_ fn, fnsub1, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_lucnum_ui (dest, b)
- mpz_t * dest
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_lucnum_ui(aTHX_ dest, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_lucnum2_ui (ln, lnsub1, b)
- mpz_t * ln
- mpz_t * lnsub1
- SV * b
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_lucnum2_ui(aTHX_ ln, lnsub1, b);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmpz_cmp (n, d)
- mpz_t * n
- mpz_t * d
-
-SV *
-Rmpz_cmp_d (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cmp_d (aTHX_ n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cmp_si (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cmp_si (aTHX_ n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cmp_ui (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cmp_ui (aTHX_ n, d);
-OUTPUT: RETVAL
-
-int
-Rmpz_cmpabs (n, d)
- mpz_t * n
- mpz_t * d
-
-SV *
-Rmpz_cmpabs_d (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cmpabs_d (aTHX_ n, d);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_cmpabs_ui (n, d)
- mpz_t * n
- SV * d
-CODE:
- RETVAL = Rmpz_cmpabs_ui (aTHX_ n, d);
-OUTPUT: RETVAL
-
-int
-Rmpz_sgn (n)
- mpz_t * n
-
-void
-Rmpz_and (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_and(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_ior (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_ior(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_xor (dest, src1, src2)
- mpz_t * dest
- mpz_t * src1
- mpz_t * src2
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_xor(aTHX_ dest, src1, src2);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_com (dest, src)
- mpz_t * dest
- mpz_t * src
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_com(aTHX_ dest, src);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmpz_popcount (in)
- mpz_t * in
-
-int
-Rmpz_hamdist (dest, src)
- mpz_t * dest
- mpz_t * src
-
-SV *
-Rmpz_scan0 (n, start_bit)
- mpz_t * n
- SV * start_bit
-CODE:
- RETVAL = Rmpz_scan0 (aTHX_ n, start_bit);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_scan1 (n, start_bit)
- mpz_t * n
- SV * start_bit
-CODE:
- RETVAL = Rmpz_scan1 (aTHX_ n, start_bit);
-OUTPUT: RETVAL
-
-void
-Rmpz_setbit (num, bit_index)
- mpz_t * num
- SV * bit_index
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_setbit(aTHX_ num, bit_index);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_clrbit (num, bit_index)
- mpz_t * num
- SV * bit_index
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_clrbit(aTHX_ num, bit_index);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_tstbit (num, bit_index)
- mpz_t * num
- SV * bit_index
-CODE:
- RETVAL = Rmpz_tstbit (aTHX_ num, bit_index);
-OUTPUT: RETVAL
-
-void
-Rmpz_import (rop, count, order, size, endian, nails, op)
- mpz_t * rop
- SV * count
- SV * order
- SV * size
- SV * endian
- SV * nails
- SV * op
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_import(aTHX_ rop, count, order, size, endian, nails, op);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rmpz_export (order, size, endian, nails, number)
- SV * order
- SV * size
- SV * endian
- SV * nails
- mpz_t * number
-CODE:
- RETVAL = Rmpz_export (aTHX_ order, size, endian, nails, number);
-OUTPUT: RETVAL
-
-int
-Rmpz_fits_ulong_p (in)
- mpz_t * in
-
-int
-Rmpz_fits_slong_p (in)
- mpz_t * in
-
-int
-Rmpz_fits_uint_p (in)
- mpz_t * in
-
-int
-Rmpz_fits_sint_p (in)
- mpz_t * in
-
-int
-Rmpz_fits_ushort_p (in)
- mpz_t * in
-
-int
-Rmpz_fits_sshort_p (in)
- mpz_t * in
-
-int
-Rmpz_odd_p (in)
- mpz_t * in
-
-int
-Rmpz_even_p (in)
- mpz_t * in
-
-SV *
-Rmpz_size (in)
- mpz_t * in
-CODE:
- RETVAL = Rmpz_size (aTHX_ in);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_sizeinbase (in, base)
- mpz_t * in
- SV * base
-CODE:
- RETVAL = Rmpz_sizeinbase (aTHX_ in, base);
-OUTPUT: RETVAL
-
-void
-Rsieve_gmp (x_arg, a, number)
- int x_arg
- int a
- mpz_t * number
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rsieve_gmp(aTHX_ x_arg, a, number);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-Rfermat_gmp (num, base)
- mpz_t * num
- SV * base
-CODE:
- RETVAL = Rfermat_gmp (aTHX_ num, base);
-OUTPUT: RETVAL
-
-SV *
-Rrm_gmp (num, base)
- mpz_t * num
- SV * base
-CODE:
- RETVAL = Rrm_gmp (aTHX_ num, base);
-OUTPUT: RETVAL
-
-SV *
-_Rmpz_out_str (p, base)
- mpz_t * p
- SV * base
-CODE:
- RETVAL = _Rmpz_out_str (aTHX_ p, base);
-OUTPUT: RETVAL
-
-SV *
-_Rmpz_out_strS (p, base, suff)
- mpz_t * p
- SV * base
- SV * suff
-CODE:
- RETVAL = _Rmpz_out_strS (aTHX_ p, base, suff);
-OUTPUT: RETVAL
-
-SV *
-_Rmpz_out_strP (pre, p, base)
- SV * pre
- mpz_t * p
- SV * base
-CODE:
- RETVAL = _Rmpz_out_strP (aTHX_ pre, p, base);
-OUTPUT: RETVAL
-
-SV *
-_Rmpz_out_strPS (pre, p, base, suff)
- SV * pre
- mpz_t * p
- SV * base
- SV * suff
-CODE:
- RETVAL = _Rmpz_out_strPS (aTHX_ pre, p, base, suff);
-OUTPUT: RETVAL
-
-SV *
-_TRmpz_out_str (stream, base, p)
- FILE * stream
- SV * base
- mpz_t * p
-CODE:
- RETVAL = _TRmpz_out_str (aTHX_ stream, base, p);
-OUTPUT: RETVAL
-
-SV *
-_TRmpz_out_strS (stream, base, p, suff)
- FILE * stream
- SV * base
- mpz_t * p
- SV * suff
-CODE:
- RETVAL = _TRmpz_out_strS (aTHX_ stream, base, p, suff);
-OUTPUT: RETVAL
-
-SV *
-_TRmpz_out_strP (pre, stream, base, p)
- SV * pre
- FILE * stream
- SV * base
- mpz_t * p
-CODE:
- RETVAL = _TRmpz_out_strP (aTHX_ pre, stream, base, p);
-OUTPUT: RETVAL
-
-SV *
-_TRmpz_out_strPS (pre, stream, base, p, suff)
- SV * pre
- FILE * stream
- SV * base
- mpz_t * p
- SV * suff
-CODE:
- RETVAL = _TRmpz_out_strPS (aTHX_ pre, stream, base, p, suff);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_inp_str (p, base)
- mpz_t * p
- SV * base
-CODE:
- RETVAL = Rmpz_inp_str (aTHX_ p, base);
-OUTPUT: RETVAL
-
-SV *
-TRmpz_inp_str (p, stream, base)
- mpz_t * p
- FILE * stream
- SV * base
-CODE:
- RETVAL = TRmpz_inp_str (aTHX_ p, stream, base);
-OUTPUT: RETVAL
-
-void
-eratosthenes (x_arg)
- SV * x_arg
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- eratosthenes(aTHX_ x_arg);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-trial_div_ul (num, x_arg)
- mpz_t * num
- SV * x_arg
-CODE:
- RETVAL = trial_div_ul (aTHX_ num, x_arg);
-OUTPUT: RETVAL
-
-void
-Rmpz_rootrem (root, rem, u, d)
- mpz_t * root
- mpz_t * rem
- mpz_t * u
- SV * d
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_rootrem(aTHX_ root, rem, u, d);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_combit (num, bitpos)
- mpz_t * num
- SV * bitpos
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_combit(aTHX_ num, bitpos);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-overload_mul (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_mul (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_add (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_add (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_sub (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_sub (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_div (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_div (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_mod (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_mod (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_string (p, second, third)
- mpz_t * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_string (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_copy (p, second, third)
- mpz_t * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_copy (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_abs (p, second, third)
- mpz_t * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_abs (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_lshift (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_lshift (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_rshift (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_rshift (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_pow (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_pow (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_sqrt (p, second, third)
- mpz_t * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_sqrt (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_and (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_and (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_ior (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_ior (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_xor (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_xor (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_com (p, second, third)
- mpz_t * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_com (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_gt (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_gt (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_gte (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_gte (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_lt (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_lt (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_lte (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_lte (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_spaceship (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_spaceship (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_equiv (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_equiv (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_not_equiv (a, b, third)
- mpz_t * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_not_equiv (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_not (a, second, third)
- mpz_t * a
- SV * second
- SV * third
-CODE:
- RETVAL = overload_not (aTHX_ a, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_xor_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_xor_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_ior_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_ior_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_and_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_and_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_pow_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_pow_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_rshift_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_rshift_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_lshift_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_lshift_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_inc (p, second, third)
- SV * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_inc (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_dec (p, second, third)
- SV * p
- SV * second
- SV * third
-CODE:
- RETVAL = overload_dec (aTHX_ p, second, third);
-OUTPUT: RETVAL
-
-SV *
-overload_mod_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_mod_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-get_refcnt (s)
- SV * s
-CODE:
- RETVAL = get_refcnt (aTHX_ s);
-OUTPUT: RETVAL
-
-SV *
-overload_div_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_div_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_sub_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_sub_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_add_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_add_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-overload_mul_eq (a, b, third)
- SV * a
- SV * b
- SV * third
-CODE:
- RETVAL = overload_mul_eq (aTHX_ a, b, third);
-OUTPUT: RETVAL
-
-SV *
-eratosthenes_string (x_arg)
- SV * x_arg
-CODE:
- RETVAL = eratosthenes_string (aTHX_ x_arg);
-OUTPUT: RETVAL
-
-SV *
-gmp_v ()
-CODE:
- RETVAL = gmp_v (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-wrap_gmp_printf (a, b)
- SV * a
- SV * b
-CODE:
- RETVAL = wrap_gmp_printf (aTHX_ a, b);
-OUTPUT: RETVAL
-
-SV *
-wrap_gmp_fprintf (stream, a, b)
- FILE * stream
- SV * a
- SV * b
-CODE:
- RETVAL = wrap_gmp_fprintf (aTHX_ stream, a, b);
-OUTPUT: RETVAL
-
-SV *
-wrap_gmp_sprintf (s, a, b, buflen)
- SV * s
- SV * a
- SV * b
- int buflen
-CODE:
- RETVAL = wrap_gmp_sprintf (aTHX_ s, a, b, buflen);
-OUTPUT: RETVAL
-
-SV *
-wrap_gmp_snprintf (s, bytes, a, b, buflen)
- SV * s
- SV * bytes
- SV * a
- SV * b
- int buflen
-CODE:
- RETVAL = wrap_gmp_snprintf (aTHX_ s, bytes, a, b, buflen);
-OUTPUT: RETVAL
-
-SV *
-_itsa (a)
- SV * a
-CODE:
- RETVAL = _itsa (aTHX_ a);
-OUTPUT: RETVAL
-
-void
-Rmpz_urandomb (p, ...)
- SV * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_urandomb(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_urandomm (x, ...)
- SV * x
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_urandomm(aTHX_ x);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rmpz_rrandomb (x, ...)
- SV * x
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_rrandomb(aTHX_ x);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-SV *
-rand_init (seed)
- SV * seed
-CODE:
- RETVAL = rand_init (aTHX_ seed);
-OUTPUT: RETVAL
-
-void
-rand_clear (p)
- SV * p
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- rand_clear(aTHX_ p);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-_has_longlong ()
-
-
-int
-_has_longdouble ()
-
-
-int
-_has_inttypes ()
-
-
-SV *
-Rmpz_inp_raw (a, stream)
- mpz_t * a
- FILE * stream
-CODE:
- RETVAL = Rmpz_inp_raw (aTHX_ a, stream);
-OUTPUT: RETVAL
-
-SV *
-Rmpz_out_raw (stream, a)
- FILE * stream
- mpz_t * a
-CODE:
- RETVAL = Rmpz_out_raw (aTHX_ stream, a);
-OUTPUT: RETVAL
-
-SV *
-___GNU_MP_VERSION ()
-CODE:
- RETVAL = ___GNU_MP_VERSION (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-___GNU_MP_VERSION_MINOR ()
-CODE:
- RETVAL = ___GNU_MP_VERSION_MINOR (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-___GNU_MP_VERSION_PATCHLEVEL ()
-CODE:
- RETVAL = ___GNU_MP_VERSION_PATCHLEVEL (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-___GNU_MP_RELEASE ()
-CODE:
- RETVAL = ___GNU_MP_RELEASE (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-___GMP_CC ()
-CODE:
- RETVAL = ___GMP_CC (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-___GMP_CFLAGS ()
-CODE:
- RETVAL = ___GMP_CFLAGS (aTHX);
-OUTPUT: RETVAL
-
-
-void
-Rmpz_powm_sec (dest, base, exp, mod)
- mpz_t * dest
- mpz_t * base
- mpz_t * exp
- mpz_t * mod
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rmpz_powm_sec(aTHX_ dest, base, exp, mod);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-_using_mpir ()
-
-
-SV *
-_Rmpz_NULL ()
-CODE:
- RETVAL = _Rmpz_NULL (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-_wrap_count ()
-CODE:
- RETVAL = _wrap_count (aTHX);
-OUTPUT: RETVAL
-
-
-void
-Rprbg_ms (outref, p, q, seed, bits_required)
- mpz_t * outref
- mpz_t * p
- mpz_t * q
- mpz_t * seed
- int bits_required
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rprbg_ms(aTHX_ outref, p, q, seed, bits_required);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-void
-Rprbg_bbs (outref, p, q, seed, bits_required)
- mpz_t * outref
- mpz_t * p
- mpz_t * q
- mpz_t * seed
- int bits_required
- PREINIT:
- I32* temp;
- PPCODE:
- temp = PL_markstack_ptr++;
- Rprbg_bbs(aTHX_ outref, p, q, seed, bits_required);
- if (PL_markstack_ptr != temp) {
- /* truly void, because dXSARGS not invoked */
- PL_markstack_ptr = temp;
- XSRETURN_EMPTY; /* return empty stack */
- }
- /* must have used dXSARGS; list context implied */
- return; /* assume stack size is correct */
-
-int
-Rmonobit (bitstream)
- mpz_t * bitstream
-
-int
-Rlong_run (bitstream)
- mpz_t * bitstream
-
-int
-Rruns (bitstream)
- mpz_t * bitstream
-
-int
-Rpoker (bitstream)
- mpz_t * bitstream
-
-SV *
-_get_xs_version ()
-CODE:
- RETVAL = _get_xs_version (aTHX);
-OUTPUT: RETVAL
-
-
-SV *
-query_eratosthenes_string (candidate, str)
- int candidate
- char * str
-CODE:
- RETVAL = query_eratosthenes_string (aTHX_ candidate, str);
-OUTPUT: RETVAL
-
+
+#ifdef __MINGW32__
+#ifndef __USE_MINGW_ANSI_STDIO
+#define __USE_MINGW_ANSI_STDIO 1
+#endif
+#endif
+
+#define PERL_NO_GET_CONTEXT 1
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gmp.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable:4700 4715 4716)
+#endif
+
+#if defined USE_64_BIT_INT
+#ifndef _MSC_VER
+#include <inttypes.h>
+#endif
+#endif
+
+#ifdef OLDPERL
+#define SvUOK SvIsUV
+#endif
+
+#ifndef Newx
+# define Newx(v,n,t) New(0,v,n,t)
+#endif
+
+#ifndef Newxz
+# define Newxz(v,n,t) Newz(0,v,n,t)
+#endif
+
+SV * Rmpz_init_set_str_nobless(pTHX_ SV * num, SV * base) {
+ mpz_t * mpz_t_obj;
+ unsigned long b = SvUV(base);
+ SV * obj_ref, * obj;
+
+ if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str_nobless is not in acceptable range");
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_create function");
+ if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
+ croak("First argument supplied to Rmpz_create_init_nobless is not a valid base %u integer", b);
+
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+
+}
+
+SV * Rmpz_init2_nobless(pTHX_ SV * bits) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init2 (*mpz_t_obj, SvUV(bits));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+
+}
+
+SV * Rmpz_init_nobless(pTHX) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init(*mpz_t_obj);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set_nobless(pTHX_ mpz_t * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init_set(*mpz_t_obj, *p);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set_ui_nobless(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init_set_ui(*mpz_t_obj, SvUV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set_si_nobless(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init_set_si(*mpz_t_obj, SvIV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+
+SV * Rmpz_init_set_d_nobless(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d_nobless function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ mpz_init_set_d(*mpz_t_obj, SvNV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init(pTHX) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set(pTHX_ mpz_t * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init_set(*mpz_t_obj, *p);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set_ui(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init_set_ui(*mpz_t_obj, SvUV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * Rmpz_init_set_si(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init_set_si(*mpz_t_obj, SvIV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+
+SV * Rmpz_init_set_d(pTHX_ SV * p) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init_set_d(*mpz_t_obj, SvNV(p));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * _Rmpz_init_set_ld(pTHX_ SV * p) {
+#ifdef USE_LONG_DOUBLE
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+ char buffer[50];
+ long double ld = (long double)SvNV(p) >= 0 ? floorl((long double)SvNV(p)) : ceill((long double)SvNV(p));
+
+ sprintf(buffer, "%.0Lf", ld);
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in _Rmpz_init_set_ld function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init_set_str(*mpz_t_obj, buffer, 10);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+#else
+ croak("_Rmpz_init_set_ld not implemented on this build of perl");
+#endif
+}
+
+
+SV * Rmpz_init_set_str(pTHX_ SV * num, SV * base) {
+ mpz_t * mpz_t_obj;
+ unsigned long b = SvUV(base);
+ SV * obj_ref, * obj;
+
+ if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str is not in acceptable range");
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_str function");
+ if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
+ croak("First argument supplied to Rmpz_init_set_str is not a valid base %u integer", b);
+
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+
+}
+
+SV * Rmpz_init2(pTHX_ SV * bits) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2 function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init2 (*mpz_t_obj, SvUV(bits));
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+
+}
+
+SV * Rmpz_get_str(pTHX_ mpz_t * p, SV * base) {
+ char * out;
+ SV * outsv;
+ int c = (int)SvIV(base), b = (int)SvIV(base);
+
+ if((b > -2 && b < 2) || b < -36 || b > 62) croak("Second argument supplied to Rmpz_get_str is not in acceptable range");
+
+ if(c < 0) c *= -1;
+
+ New(2, out, mpz_sizeinbase(*p, c) + 5, char);
+ if(out == NULL) croak("Failed to allocate memory in Rmpz_deref function");
+
+ mpz_get_str(out, b, *p);
+ outsv = newSVpv(out, 0);
+ Safefree(out);
+ return outsv;
+}
+
+void DESTROY(pTHX_ mpz_t * p) {
+/* printf("Destroying mpz "); */
+ mpz_clear(*p);
+ Safefree(p);
+/* printf("...destroyed\n"); */
+}
+
+void Rmpz_clear(pTHX_ mpz_t * p) {
+ mpz_clear(*p);
+ Safefree(p);
+}
+
+void Rmpz_clear_mpz(mpz_t * p) {
+ mpz_clear(*p);
+}
+
+void Rmpz_clear_ptr(pTHX_ mpz_t * p) {
+ Safefree(p);
+}
+
+void Rmpz_realloc2(pTHX_ mpz_t * integer, SV * bits){
+ mpz_realloc2(*integer, SvUV(bits));
+}
+
+void Rmpz_set(mpz_t * copy, mpz_t * original) {
+ mpz_set(*copy, *original);
+}
+
+void Rmpz_set_q(mpz_t * copy, mpq_t * original) {
+ mpz_set_q(*copy, *original);
+}
+
+void Rmpz_set_f(mpz_t * copy, mpf_t * original) {
+ mpz_set_f(*copy, *original);
+}
+
+void Rmpz_set_si(mpz_t * copy, long original) {
+ mpz_set_si(*copy, original);
+}
+
+void Rmpz_set_ui(mpz_t * copy, unsigned long original) {
+ mpz_set_ui(*copy, original);
+}
+
+void Rmpz_set_d(mpz_t * copy, double original) {
+ mpz_set_d(*copy, original);
+}
+
+void Rmpz_set_str(pTHX_ mpz_t * copy, SV * original, int base) {
+ if(base == 1 || base > 62) croak("Second argument supplied to Rmpz_set_str is not in acceptable range");
+ if(mpz_set_str(*copy, SvPV_nolen(original), base))
+ croak("Second argument supplied to Rmpz_set_str is not a valid base %u integer", base);
+}
+
+void Rmpz_swap(mpz_t * a, mpz_t * b) {
+ mpz_swap(*a, *b);
+}
+
+unsigned long Rmpz_get_ui(mpz_t * n) {
+ return mpz_get_ui(*n);
+}
+
+long Rmpz_get_si(mpz_t * n) {
+ return mpz_get_si(*n);
+}
+
+double Rmpz_get_d(mpz_t * n) {
+ return mpz_get_d(*n);
+}
+
+void Rmpz_get_d_2exp(pTHX_ mpz_t * n) {
+ dXSARGS;
+ double d;
+ long exp;
+
+ d = mpz_get_d_2exp(&exp, *n);
+
+ /* sp = mark; */ /* not needed */
+ EXTEND(SP, 2);
+ ST(0) = sv_2mortal(newSVnv(d));
+ ST(1) = sv_2mortal(newSVuv(exp));
+ /* PUTBACK; */ /* not needed */
+ XSRETURN(2);
+}
+
+SV * Rmpz_getlimbn(pTHX_ mpz_t * p, SV * n) {
+ return newSVuv(mpz_getlimbn(*p, SvUV(n)));
+}
+
+void Rmpz_add(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_add(*dest, *src1, *src2 );
+}
+
+void Rmpz_add_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
+ mpz_add_ui(*dest, *src, num);
+/* return sv_setref_pv(newSViv(0), Nullch, INT2PTR(mpz_t *, SvIV(SvRV(dest)))); */
+}
+
+void Rmpz_sub(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_sub(*dest, *src1, *src2 );
+}
+
+void Rmpz_sub_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
+ mpz_sub_ui(*dest, *src, num);
+}
+
+void Rmpz_ui_sub(mpz_t * dest, unsigned long num, mpz_t * src) {
+ mpz_ui_sub(*dest, num, *src);
+}
+
+void Rmpz_mul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_mul(*dest, *src1, *src2 );
+}
+
+void Rmpz_mul_si(mpz_t * dest, mpz_t * src, long num) {
+ mpz_mul_si(*dest, *src, num);
+}
+
+void Rmpz_mul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
+ mpz_mul_ui(*dest, *src, num);
+}
+
+void Rmpz_addmul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_addmul(*dest, *src1, *src2 );
+}
+
+void Rmpz_addmul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
+ mpz_addmul_ui(*dest, *src, num);
+}
+
+void Rmpz_submul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_submul(*dest, *src1, *src2 );
+}
+
+void Rmpz_submul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
+ mpz_submul_ui(*dest, *src, num);
+}
+
+void Rmpz_mul_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
+ mpz_mul_2exp(*dest, *src1, SvUV(b));
+}
+
+void Rmpz_div_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
+ mpz_div_2exp(*dest, *src1, SvUV(b));
+}
+
+void Rmpz_neg(mpz_t * dest, mpz_t * src) {
+ mpz_neg(*dest, *src );
+}
+
+void Rmpz_abs(mpz_t * dest, mpz_t * src) {
+ mpz_abs(*dest, *src );
+}
+
+void Rmpz_cdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
+ mpz_cdiv_q(*q, *n, *d);
+}
+
+void Rmpz_cdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
+ mpz_cdiv_r(*mod, *n, *d);
+}
+
+void Rmpz_cdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
+ mpz_cdiv_qr(*q, *r, *n, *d);
+}
+
+unsigned long Rmpz_cdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_cdiv_q_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_cdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_cdiv_r_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_cdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_cdiv_qr_ui(*q, *r, *n, d);
+}
+
+unsigned long Rmpz_cdiv_ui( mpz_t * n, unsigned long d) {
+ return mpz_cdiv_ui(*n, d);
+}
+
+void Rmpz_cdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
+ mpz_cdiv_q_2exp(*q, *n, (mp_bitcnt_t)SvUV(b));
+}
+
+void Rmpz_cdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
+ mpz_cdiv_r_2exp(*r, *n, (mp_bitcnt_t)SvUV(b));
+}
+
+void Rmpz_fdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
+ mpz_fdiv_q(*q, *n, *d);
+}
+
+void Rmpz_div( mpz_t * q, mpz_t * n, mpz_t * d) {
+ mpz_div(*q, *n, *d);
+}
+
+/* % mpz-t (modulus) operator */
+void Rmpz_fdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
+ mpz_fdiv_r(*mod, *n, *d);
+}
+
+void Rmpz_fdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
+ mpz_fdiv_qr(*q, *r, *n, *d);
+}
+
+void Rmpz_divmod( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
+ mpz_divmod(*q, *r, *n, *d);
+}
+
+unsigned long Rmpz_fdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_fdiv_q_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_div_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_div_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_fdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_fdiv_r_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_fdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_fdiv_qr_ui(*q, *r, *n, d);
+}
+
+unsigned long Rmpz_divmod_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_divmod_ui(*q, *r, *n, d);
+}
+
+/* % int (modulus) operator */
+unsigned long Rmpz_fdiv_ui( mpz_t * n, unsigned long d) {
+ return mpz_fdiv_ui(*n, d);
+}
+
+void Rmpz_fdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
+ mpz_fdiv_q_2exp(*q, *n, SvUV(b));
+}
+
+void Rmpz_fdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
+ mpz_fdiv_r_2exp(*r, *n, SvUV(b));
+}
+
+void Rmpz_mod_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
+ mpz_mod_2exp(*r, *n, SvUV(b));
+}
+
+void Rmpz_tdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
+ mpz_tdiv_q(*q, *n, *d);
+}
+
+/* % mpz-t (modulus) operator */
+void Rmpz_tdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
+ mpz_tdiv_r(*mod, *n, *d);
+}
+
+void Rmpz_tdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
+ mpz_tdiv_qr(*q, *r, *n, *d);
+}
+
+unsigned long Rmpz_tdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_tdiv_q_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_tdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
+ return mpz_tdiv_r_ui(*q, *n, d);
+}
+
+unsigned long Rmpz_tdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_tdiv_qr_ui(*q, *r, *n, d);
+}
+
+/* % int (modulus) operator */
+unsigned long Rmpz_tdiv_ui( mpz_t * n, unsigned long d) {
+ return mpz_tdiv_ui(*n, d);
+}
+
+void Rmpz_tdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
+ mpz_tdiv_q_2exp(*q, *n, SvUV(b));
+}
+
+void Rmpz_tdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
+ mpz_tdiv_r_2exp(*r, *n, SvUV(b));
+}
+
+void Rmpz_mod( mpz_t * r, mpz_t * n, mpz_t * d) {
+ mpz_mod(*r, *n, *d);
+}
+
+unsigned long Rmpz_mod_ui( mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_mod_ui(*r, *n, d);
+}
+
+void Rmpz_divexact(mpz_t * dest, mpz_t * n, mpz_t * d) {
+ mpz_divexact(*dest, *n, *d );
+}
+
+void Rmpz_divexact_ui(mpz_t * dest, mpz_t * n, unsigned long d) {
+ mpz_divexact_ui(*dest, *n, d);
+}
+
+int Rmpz_divisible_p(mpz_t * n, mpz_t * d) {
+ return mpz_divisible_p(*n, *d);
+}
+
+int Rmpz_divisible_ui_p(mpz_t * n, unsigned long d) {
+ return mpz_divisible_ui_p(*n, d);
+}
+
+int Rmpz_divisible_2exp_p(pTHX_ mpz_t * n, SV * b) {
+ return mpz_divisible_2exp_p(*n, SvUV(b));
+}
+
+int Rmpz_congruent_p(mpz_t * n, mpz_t * c, mpz_t * d) {
+ return mpz_congruent_p(*n, *c, *d);
+}
+
+int Rmpz_congruent_ui_p(mpz_t * n, unsigned long c, unsigned long d) {
+ return mpz_congruent_ui_p(*n, c, d);
+}
+
+SV * Rmpz_congruent_2exp_p(pTHX_ mpz_t * n, mpz_t * c, SV * d) {
+ return newSViv(mpz_congruent_2exp_p(*n, *c, SvUV(d)));
+}
+
+void Rmpz_powm(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
+ mpz_powm(*dest, *base, *exp, *mod);
+}
+
+void Rmpz_powm_ui(mpz_t * dest, mpz_t * base, unsigned long exp, mpz_t * mod) {
+ mpz_powm_ui(*dest, *base, exp, *mod);
+}
+
+void Rmpz_pow_ui(mpz_t * dest, mpz_t * base, unsigned long exp) {
+ mpz_pow_ui(*dest, *base, exp);
+}
+
+void Rmpz_ui_pow_ui(mpz_t * dest, unsigned long base, unsigned long exp) {
+ mpz_ui_pow_ui(*dest, base, exp);
+}
+
+int Rmpz_root(mpz_t * r, mpz_t * n, unsigned long d) {
+ return mpz_root(*r, *n, d);
+}
+
+void Rmpz_sqrt(mpz_t * r, mpz_t * n) {
+ mpz_sqrt(*r, *n);
+}
+
+void Rmpz_sqrtrem(mpz_t * root, mpz_t * rem, mpz_t * src) {
+ mpz_sqrtrem(*root, *rem, *src);
+}
+
+int Rmpz_perfect_power_p(mpz_t * in) {
+ return mpz_perfect_power_p(*in);
+}
+
+int Rmpz_perfect_square_p(mpz_t * in) {
+ return mpz_perfect_square_p(*in);
+}
+
+int Rmpz_probab_prime_p(pTHX_ mpz_t * cand, SV * reps) {
+ return mpz_probab_prime_p(*cand, (int)SvIV(reps));
+}
+
+void Rmpz_nextprime(mpz_t * prime, mpz_t * init) {
+ mpz_nextprime(*prime, *init);
+}
+
+void Rmpz_gcd(mpz_t * gcd, mpz_t * src1, mpz_t * src2) {
+ mpz_gcd(*gcd, *src1, *src2);
+}
+
+/* First arg can be either (the unblessed) $Math::GMPz::NULL or a
+ * (blessed) Math::GMPz object.
+ */
+unsigned long Rmpz_gcd_ui(mpz_t * gcd, mpz_t * n, unsigned long d) {
+ return mpz_gcd_ui(*gcd, *n, d);
+}
+
+void Rmpz_gcdext(mpz_t * g, mpz_t * s, mpz_t * t, mpz_t * a, mpz_t * b) {
+ mpz_gcdext(*g, *s, *t, *a, *b);
+}
+
+void Rmpz_lcm(mpz_t * lcm, mpz_t * src1, mpz_t * src2) {
+ mpz_lcm(*lcm, *src1, *src2);
+}
+
+void Rmpz_lcm_ui(mpz_t * lcm, mpz_t * src1, unsigned long src2) {
+ mpz_lcm_ui(*lcm, *src1, src2);
+}
+
+int Rmpz_invert(mpz_t * inv, mpz_t * src1, mpz_t * src2) {
+ return mpz_invert(*inv, *src1, *src2);
+}
+
+int Rmpz_jacobi(mpz_t * a, mpz_t * b) {
+ return mpz_jacobi(*a, *b);
+}
+
+int Rmpz_legendre(mpz_t * a, mpz_t * b) {
+ return mpz_legendre(*a, *b);
+}
+
+int Rmpz_kronecker(mpz_t * a, mpz_t * b) {
+ return mpz_kronecker(*a, *b);
+}
+
+int Rmpz_kronecker_si(mpz_t * a, long b) {
+ return mpz_kronecker_si(*a, b);
+}
+
+int Rmpz_kronecker_ui(mpz_t * a, unsigned long b) {
+ return mpz_kronecker_ui(*a, b);
+}
+
+int Rmpz_si_kronecker(long a, mpz_t * b) {
+ return mpz_si_kronecker(a, *b);
+}
+
+int Rmpz_ui_kronecker(unsigned long a, mpz_t * b) {
+ return mpz_ui_kronecker(a, *b);
+}
+
+SV * Rmpz_remove(pTHX_ mpz_t * rem, mpz_t * src1, mpz_t * src2) {
+ return newSVuv(mpz_remove(*rem, *src1, *src2));
+}
+
+void Rmpz_fac_ui(mpz_t * fac, unsigned long b) {
+ mpz_fac_ui(*fac, b);
+}
+
+#if __GNU_MP_VERSION > 5 || (__GNU_MP_VERSION == 5 && __GNU_MP_VERSION_MINOR >= 1)
+
+void Rmpz_2fac_ui(mpz_t * fac, unsigned long b) {
+ mpz_2fac_ui(*fac, b);
+}
+
+void Rmpz_mfac_uiui(mpz_t * fac, unsigned long b, unsigned long c) {
+ mpz_mfac_uiui(*fac, b, c);
+}
+
+void Rmpz_primorial_ui(mpz_t * fac, unsigned long b) {
+ mpz_primorial_ui(*fac, b);
+}
+
+#else
+
+void Rmpz_2fac_ui(mpz_t * fac, unsigned long b) {
+ croak("Rmpz_2fac_ui not implemented - gmp-5.1.0 (or later) is needed");
+}
+
+void Rmpz_mfac_uiui(mpz_t * fac, unsigned long b, unsigned long c) {
+ croak("Rmpz_mfac_uiui not implemented - gmp-5.1.0 (or later) is needed");
+}
+
+void Rmpz_primorial_ui(mpz_t * fac, unsigned long b) {
+ croak("Rmpz_primorial_ui not implemented - gmp-5.1.0 (or later) is needed");
+}
+
+#endif
+
+void Rmpz_bin_ui(mpz_t * dest, mpz_t * n, unsigned long d) {
+ mpz_bin_ui(*dest, *n, d);
+}
+
+void Rmpz_bin_si(mpz_t * dest, mpz_t * n, long d) {
+ signed long int t = d;
+ if(t >= 0) mpz_bin_ui(*dest, *n, t);
+ else {
+ if(mpz_sgn(*n) >= 0 || mpz_cmp_si(*n, t) < 0)
+ mpz_set_ui(*dest, 0);
+ else
+ mpz_bin_ui(*dest, *n, mpz_get_si(*n) - t);
+ }
+}
+
+void Rmpz_bin_uiui(mpz_t * dest, unsigned long n, unsigned long d) {
+ mpz_bin_uiui(*dest, n, d);
+}
+
+void Rmpz_fib_ui(mpz_t * dest, unsigned long b) {
+ mpz_fib_ui(*dest, b);
+}
+
+void Rmpz_fib2_ui(mpz_t * fn, mpz_t * fnsub1, unsigned long b) {
+ mpz_fib2_ui(*fn, *fnsub1, b);
+}
+
+void Rmpz_lucnum_ui(mpz_t * dest, unsigned long b) {
+ mpz_lucnum_ui(*dest, b);
+}
+
+void Rmpz_lucnum2_ui(mpz_t * ln, mpz_t * lnsub1, unsigned long b) {
+ mpz_lucnum2_ui(*ln, *lnsub1, b);
+}
+
+int Rmpz_cmp(mpz_t * n, mpz_t * d) {
+ return mpz_cmp(*n, *d );
+}
+
+int Rmpz_cmp_d(mpz_t * n, double d) {
+ return mpz_cmp_d(*n, d);
+}
+
+int Rmpz_cmp_si(mpz_t * n, long d) {
+ return mpz_cmp_si(*n, d);
+}
+
+int Rmpz_cmp_ui(mpz_t * n, unsigned long d) {
+ return mpz_cmp_ui(*n, d);
+}
+
+int Rmpz_cmpabs(mpz_t * n, mpz_t * d) {
+ return mpz_cmpabs(*n, *d );
+}
+
+int Rmpz_cmpabs_d(mpz_t * n, double d) {
+ return mpz_cmpabs_d(*n, d);
+}
+
+int Rmpz_cmpabs_ui(mpz_t * n, unsigned long d) {
+ return mpz_cmpabs_ui(*n, d);
+}
+
+int Rmpz_sgn(mpz_t * n) {
+ return mpz_sgn(*n);
+}
+
+void Rmpz_and(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_and(*dest, *src1, *src2 );
+}
+
+void Rmpz_ior(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_ior(*dest, *src1, *src2 );
+}
+
+void Rmpz_xor(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
+ mpz_xor(*dest, *src1, *src2 );
+}
+
+void Rmpz_com(mpz_t * dest, mpz_t * src) {
+ mpz_com(*dest, *src );
+}
+
+int Rmpz_popcount(mpz_t * in) {
+ return mpz_popcount(*in);
+}
+
+int Rmpz_hamdist(mpz_t * dest, mpz_t * src) {
+ return mpz_hamdist(*dest, *src );
+}
+
+SV * Rmpz_scan0(pTHX_ mpz_t * n, SV * start_bit) {
+ return newSVuv(mpz_scan0(*n, (mp_bitcnt_t)SvUV(start_bit)));
+}
+
+SV * Rmpz_scan1(pTHX_ mpz_t * n, SV * start_bit) {
+ return newSVuv(mpz_scan1(*n, (mp_bitcnt_t)SvUV(start_bit)));
+}
+
+void Rmpz_setbit(pTHX_ mpz_t * num, SV * bit_index) {
+ mpz_setbit(*num, (mp_bitcnt_t)SvUV(bit_index));
+}
+
+void Rmpz_clrbit(pTHX_ mpz_t * num, SV * bit_index) {
+ mpz_clrbit(*num, (mp_bitcnt_t)SvUV(bit_index));
+}
+
+SV * Rmpz_tstbit(pTHX_ mpz_t * num, SV * bit_index) {
+ return newSViv(mpz_tstbit(*num, (mp_bitcnt_t)SvUV(bit_index)));
+}
+
+/* Turn a binary string into an mpz_t */
+void Rmpz_import(pTHX_ mpz_t * rop, SV * count, SV * order, SV * size, SV * endian, SV * nails, SV * op){
+ mpz_import(*rop, SvUV(count), SvIV(order), SvIV(size), SvIV(endian), SvUV(nails), SvPV_nolen(op));
+}
+
+/* Return an mpz_t to a binary string */
+SV * Rmpz_export(pTHX_ SV * order, SV * size, SV * endian, SV * nails, mpz_t * number) {
+ SV * outsv;
+ char * out;
+ size_t * cptr, count;
+
+ cptr = &count;
+ count = mpz_sizeinbase(*number, 2);
+
+ Newz(1, out, count / 8 + 7, char);
+ if(out == NULL) croak("Failed to allocate memory in Rmpz_export function");
+
+ mpz_export(out, cptr, SvIV(order), SvIV(size), SvIV(endian), SvIV(nails), *number);
+ outsv = newSVpv(out, count);
+ Safefree(out);
+ return outsv;
+}
+
+int Rmpz_fits_ulong_p(mpz_t * in) {
+ return mpz_fits_ulong_p(*in);
+}
+
+int Rmpz_fits_slong_p(mpz_t * in) {
+ return mpz_fits_slong_p(*in);
+}
+
+int Rmpz_fits_uint_p(mpz_t * in) {
+ return mpz_fits_uint_p(*in);
+}
+
+int Rmpz_fits_sint_p(mpz_t * in) {
+ return mpz_fits_sint_p(*in);
+}
+
+int Rmpz_fits_ushort_p(mpz_t * in) {
+ return mpz_fits_ushort_p(*in);
+}
+
+int Rmpz_fits_sshort_p(mpz_t * in) {
+ return mpz_fits_sshort_p(*in);
+}
+
+int Rmpz_odd_p(mpz_t * in) {
+ return mpz_odd_p(*in);
+}
+
+int Rmpz_even_p(mpz_t * in) {
+ return mpz_even_p(*in);
+}
+
+SV * Rmpz_size(pTHX_ mpz_t * in) {
+ return newSVuv(mpz_size(*in));
+}
+
+SV * Rmpz_sizeinbase(pTHX_ mpz_t * in, int base) {
+ if(base < 2 || base > 62) croak("Rmpz_sizeinbase handles only bases in the range 2..62");
+ return newSVuv(mpz_sizeinbase(*in, base));
+}
+
+void Rsieve_gmp(pTHX_ int x_arg, int a, mpz_t *number) {
+dXSARGS;
+unsigned short *v, *addon, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
+unsigned long init, leap, abits, asize, i, size, b, imax, k, x = x_arg;
+
+if(sizeof(short) != 2) croak("The sieve_gmp function is unsuitable for this architecture.\nContact the author and he may do something about it.");
+if(a & 1) croak("max_add must be even in sieve_gmp function");
+if(x & 1) croak("max_prime must be even in sieve_gmp function");
+
+if(!mpz_tstbit(*number, 0)) croak("candidate must be odd in sieve_gmp function");
+
+abits = (a / 2) + 1;
+
+if(!(abits % 16)) asize = abits / 16;
+else asize = (abits / 16) + 1;
+
+Newz(1, addon, asize, unsigned short);
+if(addon == NULL) croak("1: Unable to allocate memory in sieve_gmp function");
+
+for(i = 0; i < asize; ++i) addon[i] = 65535;
+
+imax = sqrt(x - 1) / 2;
+
+b = (x + 1) / 2;
+
+if(!(b % 16)) size = b / 16;
+else size = (b / 16) + 1;
+
+Newz(2, v, size, unsigned short);
+if(v == NULL) croak("2: Unable to allocate memory in sieve_gmp function");
+
+for(i = 1; i < size; ++i) v[i] = 65535;
+v[0] = 65534;
+
+for(i = 0; i <= imax; ++i) {
+
+ if(v[i / 16] & (1 << (i % 16))) {
+ leap = (2 * i) + 1;
+ k = 2 * i * (i + 1);
+ while(k < b) {
+ v[k / 16] &= set[k % 16];
+ k += leap;
+ }
+ }
+}
+
+size = 0;
+sp = mark;
+
+for(i = 0; i < b; ++i) {
+ if(v[i / 16] & (1 << (i % 16))) {
+ leap = 2 * i + 1;
+ init = mpz_fdiv_ui(*number, leap);
+ if(init) {
+ if(init & 1) init = (leap - init) / 2;
+ else init = leap - (init / 2);
+ }
+ while(init < abits) {
+ addon[init / 16] &= set[init % 16];
+ init += leap;
+ }
+ }
+ }
+
+Safefree(v);
+
+for(i = 0; i < abits; ++i) {
+ if(addon[i / 16] & (1 << (i % 16))) {
+ XPUSHs(sv_2mortal(newSViv(2 * i)));
+ ++size;
+ }
+ }
+
+Safefree(addon);
+
+PUTBACK;
+XSRETURN(size);
+
+}
+
+SV * Rfermat_gmp(pTHX_ mpz_t * num, int base){
+ mpz_t b, num_less_1;
+
+ mpz_init_set_ui(b, base);
+ mpz_init_set(num_less_1, *num);
+ mpz_sub_ui(num_less_1, num_less_1, 1);
+ mpz_powm(b, b, num_less_1, *num);
+
+ if(!mpz_cmp_si(b, 1)) {
+ mpz_clear(b);
+ mpz_clear(num_less_1);
+ return newSViv(1);
+ }
+
+ mpz_clear(b);
+ mpz_clear(num_less_1);
+ return newSViv(0);
+}
+
+SV * Rrm_gmp(pTHX_ mpz_t * num, int base){
+ mpz_t c_less, r, y, bb;
+ unsigned long i, s = 0, b = base;
+
+ mpz_init(c_less);
+ mpz_init(r);
+ mpz_init(y);
+
+ mpz_sub_ui(c_less, *num, 1);
+ mpz_set(r, c_less);
+ mpz_init_set_ui(bb, b);
+
+ while(mpz_even_p(r)) {
+ mpz_tdiv_q_2exp(r, r, 1);
+ ++s;
+ }
+
+ mpz_powm(y, bb, r, *num);
+ mpz_clear(r);
+ mpz_clear(bb);
+ if(mpz_cmp_ui(y, 1) && mpz_cmp(y, c_less)) {
+ for(i = 0; i < s; ++i) {
+ mpz_powm_ui(y, y, 2, *num);
+ if(!mpz_cmp_ui(y, 1)) {
+ mpz_clear(c_less);
+ mpz_clear(y);
+ return 0;
+ }
+ if(!mpz_cmp(y, c_less)) break;
+ }
+ if(mpz_cmp(y, c_less)) {
+ mpz_clear(c_less);
+ mpz_clear(y);
+ return newSViv(0);
+ }
+ }
+
+ mpz_clear(c_less);
+ mpz_clear(y);
+ return newSVuv(1);
+}
+
+SV * _Rmpz_out_str(pTHX_ mpz_t * p, int base) {
+ unsigned long ret;
+ if((base > -2 && base < 2) || base < -36 || base > 62)
+ croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ ret = mpz_out_str(NULL, base, *p);
+ fflush(stdout);
+ return newSVuv(ret);
+}
+
+SV * _Rmpz_out_strS(pTHX_ mpz_t * p, SV * base, SV * suff) {
+ unsigned long ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ ret = mpz_out_str(NULL, SvUV(base), *p);
+ printf("%s", SvPV_nolen(suff));
+ fflush(stdout);
+ return newSVuv(ret);
+}
+
+SV * _Rmpz_out_strP(pTHX_ SV * pre, mpz_t * p, SV * base) {
+ unsigned long ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ printf("%s", SvPV_nolen(pre));
+ ret = mpz_out_str(NULL, SvUV(base), *p);
+ fflush(stdout);
+ return newSVuv(ret);
+}
+
+SV * _Rmpz_out_strPS(pTHX_ SV * pre, mpz_t * p, SV * base, SV * suff) {
+ unsigned long ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ printf("%s", SvPV_nolen(pre));
+ ret = mpz_out_str(NULL, SvUV(base), *p);
+ printf("%s", SvPV_nolen(suff));
+ fflush(stdout);
+ return newSVuv(ret);
+}
+
+SV * _TRmpz_out_str(pTHX_ FILE * stream, SV * base, mpz_t * p) {
+ size_t ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ ret = mpz_out_str(stream, (int)SvIV(base), *p);
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * _TRmpz_out_strS(pTHX_ FILE * stream, SV * base, mpz_t * p, SV * suff) {
+ size_t ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ ret = mpz_out_str(stream, (int)SvIV(base), *p);
+ fflush(stream);
+ fprintf(stream, "%s", SvPV_nolen(suff));
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * _TRmpz_out_strP(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p) {
+ size_t ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ fprintf(stream, "%s", SvPV_nolen(pre));
+ fflush(stream);
+ ret = mpz_out_str(stream, (int)SvIV(base), *p);
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * _TRmpz_out_strPS(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p, SV * suff) {
+ size_t ret;
+ if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
+ croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
+ fprintf(stream, "%s", SvPV_nolen(pre));
+ fflush(stream);
+ ret = mpz_out_str(stream, (int)SvIV(base), *p);
+ fflush(stream);
+ fprintf(stream, "%s", SvPV_nolen(suff));
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * Rmpz_inp_str(pTHX_ mpz_t * p, int base) {
+ size_t ret;
+ if(base == 1 || base > 62)
+ croak("2nd argument supplied to Rmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
+ ret = mpz_inp_str(*p, NULL, base);
+ /* fflush(stdin); */
+ return newSVuv(ret);
+}
+
+SV * TRmpz_inp_str(pTHX_ mpz_t * p, FILE * stream, int base) {
+ size_t ret;
+ if(base == 1 || base > 62)
+ croak("4th argument supplied to TRmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
+ ret = mpz_inp_str(*p, stream, base);
+ /* fflush(stream); */
+ return newSVuv(ret);
+}
+
+void eratosthenes(pTHX_ SV * x_arg) {
+dXSARGS;
+
+unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
+unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
+
+if(x & 1) croak("max_num argument must be even in eratosthenes function");
+
+imax = sqrt(x - 1) / 2;
+
+b = (x + 1) / 2;
+
+if(!(b % 16)) size = b / 16;
+else size = (b / 16) + 1;
+
+Newz(2, v, size, unsigned short);
+if(v == NULL) croak("2: Unable to allocate memory in eratosthenes function");
+
+for(i = 1; i < size; ++i) v[i] = 65535;
+v[0] = 65534;
+
+for(i = 0; i <= imax; ++i) {
+
+ if(v[i / 16] & (1 << (i % 16))) {
+ leap = (2 * i) + 1;
+ k = 2 * i * (i + 1);
+ while(k < b) {
+ v[k / 16] &= set[k % 16];
+ k += leap;
+ }
+ }
+}
+
+size = 1;
+sp = mark;
+XPUSHs(sv_2mortal(newSVuv(2)));
+
+for(i = 0; i < b; ++i) {
+ if(v[i / 16] & (1 << (i % 16))) {
+ XPUSHs(sv_2mortal(newSVuv(2 * i + 1)));
+ ++size;
+ }
+ }
+
+Safefree(v);
+
+PUTBACK;
+XSRETURN(size);
+
+}
+
+
+SV * trial_div_ul(pTHX_ mpz_t * num, SV * x_arg) {
+
+ unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
+ unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
+
+ if(x & 1) croak("Second argument supplied to trial_div_ul must be even");
+
+ imax = sqrt(x - 1) / 2;
+
+ b = (x + 1) / 2;
+
+ if(!(b % 16)) size = b / 16;
+ else size = (b / 16) + 1;
+
+ Newz(2, v, size, unsigned short);
+ if(v == NULL) croak("2: Unable to allocate memory in trial_div_ul function");
+
+ for(i = 1; i < size; ++i) v[i] = 65535;
+ v[0] = 65534;
+
+ for(i = 0; i <= imax; ++i) {
+
+ if(v[i / 16] & (1 << (i % 16))) {
+ leap = (2 * i) + 1;
+ k = 2 * i * (i + 1);
+ while(k < b) {
+ v[k / 16] &= set[k % 16];
+ k += leap;
+ }
+ }
+ }
+
+ if(mpz_divisible_ui_p(*num, 2)) {
+ Safefree(v);
+ return newSViv(2);
+ }
+
+ for(i = 0; i < b; ++i) {
+ if(v[i / 16] & (1 << (i % 16))) {
+ if(mpz_divisible_ui_p(*num, 2 * i + 1)) {
+ Safefree(v);
+ return newSViv(2 * i + 1);
+ }
+ }
+ }
+
+ Safefree(v);
+
+ return newSViv(1);
+}
+
+/* Next 2 functions became available with GMP-4.2 */
+
+void Rmpz_rootrem(mpz_t * root, mpz_t * rem, mpz_t * u, unsigned long d) {
+ mpz_rootrem(*root, *rem, *u, d);
+}
+
+void Rmpz_combit(pTHX_ mpz_t * num, SV * bitpos) {
+ mpz_combit(*num, (mp_bitcnt_t)SvUV(bitpos));
+}
+
+/* Finish typemapping - typemap 1st arg only */
+
+SV * overload_mul(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+ const char *h;
+
+ if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
+
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mul function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ }
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_mul");
+ mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+
+ if(SvUOK(b)) {
+ mpz_mul_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ mpz_mul_si(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_mul");
+ mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ if(strEQ(h, "Math::MPFR")) {
+ dSP;
+ SV * ret;
+ int count;
+
+ ENTER;
+
+ PUSHMARK(SP);
+ XPUSHs(b);
+ XPUSHs(a);
+ XPUSHs(sv_2mortal(newSViv(1)));
+ PUTBACK;
+
+ count = call_pv("Math::MPFR::overload_mul", G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak("Error in Math::GMPz::overload_mul callback to Math::MPFR::overload_mul\n");
+
+ ret = POPs;
+
+ /* Avoid "Attempt to free unreferenced scalar" warning */
+ SvREFCNT_inc(ret);
+ LEAVE;
+ return ret;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_mul");
+}
+
+SV * overload_add(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+ const char *h;
+
+ if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
+
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_add function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ }
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_add");
+ mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return obj_ref;
+ }
+ mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_add");
+ mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ if(strEQ(h, "Math::MPFR")) {
+ dSP;
+ SV * ret;
+ int count;
+
+ ENTER;
+
+ PUSHMARK(SP);
+ XPUSHs(b);
+ XPUSHs(a);
+ XPUSHs(sv_2mortal(newSViv(1)));
+ PUTBACK;
+
+ count = call_pv("Math::MPFR::overload_add", G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak("Error in Math::GMPz::overload_add callback to Math::MPFR::overload_add\n");
+
+ ret = POPs;
+
+ /* Avoid "Attempt to free unreferenced scalar" warning */
+ SvREFCNT_inc(ret);
+ LEAVE;
+ return ret;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_add function");
+
+}
+
+SV * overload_sub(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+ const char *h;
+
+ if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
+
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sub function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ }
+
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_sub");
+ if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ if(third == &PL_sv_yes) {
+ mpz_ui_sub(*mpz_t_obj, SvUV(b), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return obj_ref;
+ }
+ mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ if(third == &PL_sv_yes) {
+ mpz_ui_sub(*mpz_t_obj, SvIV(b), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return obj_ref;
+ }
+ mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return obj_ref;
+ }
+ mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ if(third == &PL_sv_yes) mpz_neg(*mpz_t_obj, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_sub");
+ if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+ if(sv_isobject(b)) {
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ if(strEQ(h, "Math::MPFR")) {
+ dSP;
+ SV * ret;
+ int count;
+
+ ENTER;
+
+ PUSHMARK(SP);
+ XPUSHs(b);
+ XPUSHs(a);
+ XPUSHs(sv_2mortal(&PL_sv_yes));
+ PUTBACK;
+
+ count = call_pv("Math::MPFR::overload_sub", G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak("Error in Math::GMPz::overload_sub callback to Math::MPFR::overload_sub\n");
+
+ ret = POPs;
+
+ /* Avoid "Attempt to free unreferenced scalar" warning */
+ SvREFCNT_inc(ret);
+ LEAVE;
+ return ret;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_sub function");
+
+}
+
+SV * overload_div(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+ const char *h;
+
+ if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
+
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ if(!sv_isobject(b) || strNE(h, "Math::MPFR")) {
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_div function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ }
+
+
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_div");
+ if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ if(third == &PL_sv_yes) {
+ mpz_set_ui(*mpz_t_obj, SvUV(b));
+ mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return obj_ref;
+ }
+ mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ if(third == &PL_sv_yes) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return obj_ref;
+ }
+ mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return obj_ref;
+ }
+ if(third == &PL_sv_yes) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return obj_ref;
+ }
+ mpz_tdiv_q_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ mpz_neg(*mpz_t_obj, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_div");
+ if(third == &PL_sv_yes) mpz_tdiv_q(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ else mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ if(strEQ(h, "Math::MPFR")) {
+ dSP;
+ SV * ret;
+ int count;
+
+ ENTER;
+
+ PUSHMARK(SP);
+ XPUSHs(b);
+ XPUSHs(a);
+ XPUSHs(sv_2mortal(&PL_sv_yes));
+ PUTBACK;
+
+ count = call_pv("Math::MPFR::overload_div", G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak("Error in Math::GMPz::overload_div callback to Math::MPFR::overload_div\n");
+
+ ret = POPs;
+
+ /* Avoid "Attempt to free unreferenced scalar" warning */
+ SvREFCNT_inc(ret);
+ LEAVE;
+ return ret;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_div function");
+
+}
+
+SV * overload_mod (pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t *mpz_t_obj;
+ SV * obj_ref, * obj;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mod function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_mod");
+ if(third == &PL_sv_yes) {
+ mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
+ return obj_ref;
+ }
+ mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ if(third == &PL_sv_yes) {
+ mpz_set_ui(*mpz_t_obj, SvUV(b));
+ mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
+ return obj_ref;
+ }
+ mpz_mod_ui(*mpz_t_obj, *a, SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ if(third == &PL_sv_yes) {
+ mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
+ return obj_ref;
+ }
+ mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) {
+ mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
+ return obj_ref;
+ }
+ mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak(" Invalid string supplied to Math::GMPz::overload_mod");
+ if(third == &PL_sv_yes) {
+ mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
+ return obj_ref;
+ }
+ mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_mod(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_mod function");
+}
+
+SV * overload_string(pTHX_ mpz_t * p, SV * second, SV * third) {
+ char * out;
+ SV * outsv;
+
+ New(2, out, mpz_sizeinbase(*p, 10) + 3, char);
+ if(out == NULL) croak("Failed to allocate memory in overload_string function");
+
+ mpz_get_str(out, 10, *p);
+ outsv = newSVpv(out, 0);
+ Safefree(out);
+ return outsv;
+}
+
+SV * overload_copy(pTHX_ mpz_t * p, SV * second, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_copy function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+
+ mpz_init_set(*mpz_t_obj, *p);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * overload_abs(pTHX_ mpz_t * p, SV * second, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_abs function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ mpz_abs(*mpz_t_obj, *p);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * overload_lshift(pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_lshift function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ if(SvUOK(b)) {
+ mpz_mul_2exp(*mpz_t_obj, *a, SvUV(b));
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_lshift");
+ mpz_mul_2exp(*mpz_t_obj, *a, SvUV(b));
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_lshift");
+}
+
+SV * overload_rshift(pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_rshift function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ if(SvUOK(b)) {
+ mpz_tdiv_q_2exp(*mpz_t_obj, *a, SvUV(b));
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_rshift");
+ mpz_tdiv_q_2exp(*mpz_t_obj, *a, SvUV(b));
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_rshift");
+}
+
+SV * overload_pow(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ if(third == &PL_sv_yes)
+ croak("Invalid third argument (&PL_sv_yes) supplied to Math::GMPz::overload_pow function");
+
+ if(!sv_isobject(b)) {
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_pow function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ }
+
+ if(SvUOK(b)) {
+ mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))) , SvUV(b));
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_pow");
+ mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::MPFR")) {
+ dSP;
+ SV * ret;
+ int count;
+
+ ENTER;
+
+ PUSHMARK(SP);
+ XPUSHs(b);
+ XPUSHs(a);
+ XPUSHs(sv_2mortal(&PL_sv_yes));
+ PUTBACK;
+
+ count = call_pv("Math::MPFR::overload_pow", G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak("Error in Math::GMPq:overload_pow callback to Math::MPFR::overload_pow\n");
+
+ ret = POPs;
+
+ /* Avoid "Attempt to free unreferenced scalar" warning */
+ SvREFCNT_inc(ret);
+ LEAVE;
+ return ret;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_pow. It takes only signed/unsigned long or Math::MPFR object as exponent");
+}
+
+SV * overload_sqrt(pTHX_ mpz_t * p, SV * second, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sqrt function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ if(mpz_cmp_ui(*p, 0) < 0) croak("Negative value supplied as argument to overload_sqrt");
+ mpz_sqrt(*mpz_t_obj, *p);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * overload_and(pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_and function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_and");
+ mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_set_ui(*mpz_t_obj, SvUV(b));
+ mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#endif
+
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+ mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_and");
+ mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_and(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_and");
+}
+
+SV * overload_ior(pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_ior function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_ior");
+ mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_set_ui(*mpz_t_obj, SvUV(b));
+ mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_ior");
+ mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_ior(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_ior");
+}
+
+SV * overload_xor(pTHX_ mpz_t * a, SV * b, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_xor function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_xor");
+ mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_set_ui(*mpz_t_obj, SvUV(b));
+ mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvIOK(b)) {
+ mpz_set_si(*mpz_t_obj, SvIV(b));
+ mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_set_str(*mpz_t_obj, buffer, 10);
+#else
+ mpz_set_d(*mpz_t_obj, SvNV(b));
+#endif
+ mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_xor");
+ mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
+ return obj_ref;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_xor(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return obj_ref;
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_xor");
+}
+
+SV * overload_com(pTHX_ mpz_t * p, SV * second, SV * third) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ New(1, mpz_t_obj, 1, mpz_t);
+ if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_com function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, "Math::GMPz");
+ mpz_init(*mpz_t_obj);
+
+ mpz_com(*mpz_t_obj, *p);
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * overload_gt(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_gt");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_gt");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret > 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_gt");
+}
+
+SV * overload_gte(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_gte");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_gte");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret >= 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_gte");
+}
+
+SV * overload_lt(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_lt");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_lt");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret < 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_lt");
+}
+
+SV * overload_lte(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_lte");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_lte");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret <= 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_lte");
+}
+
+SV * overload_spaceship(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_spaceship");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ return newSViv(ret);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ return newSViv(ret);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ return newSViv(ret);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ return newSViv(ret);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_spaceship");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ return newSViv(ret);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return newSViv(ret);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_spaceship");
+}
+
+SV * overload_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_equiv");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_equiv");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret == 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_equiv");
+}
+
+SV * overload_not_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
+ int ret;
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_not_equiv");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+#else
+ if(SvUOK(b)) {
+ ret = mpz_cmp_ui(*a, SvUV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvIOK(b)) {
+ ret = mpz_cmp_si(*a, SvIV(b));
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+#else
+ ret = mpz_cmp_d(*a, SvNV(b));
+#endif
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0))
+ croak("Invalid string supplied to Math::GMPz::overload_not_equiv");
+ ret = mpz_cmp(*a, t);
+ mpz_clear(t);
+ if(third == &PL_sv_yes) ret *= -1;
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ if(ret != 0) return newSViv(1);
+ return newSViv(0);
+ }
+ }
+
+ croak("Invalid argument supplied to Math::GMPz::overload_not_equiv");
+}
+
+SV * overload_not(pTHX_ mpz_t * a, SV * second, SV * third) {
+ if(mpz_cmp_ui(*a, 0)) return newSViv(0);
+ return newSViv(1);
+}
+
+/* Finish typemapping */
+
+SV * overload_xor_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_xor_eq");
+ }
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_init_set_ui(t, SvUV(b));
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ mpz_init_set_si(t, SvIV(b));
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_xor_eq");
+ }
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_xor(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_xor_eq");
+}
+
+SV * overload_ior_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_ior_eq");
+ }
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_init_set_ui(t, SvUV(b));
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ mpz_init_set_si(t, SvIV(b));
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_ior_eq");
+ }
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_ior(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_ior_eq");
+}
+
+SV * overload_and_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_and_eq");
+ }
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_init_set_ui(t, SvUV(b));
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ mpz_init_set_si(t, SvIV(b));
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_and_eq");
+ }
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_and(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_and_eq");
+}
+
+SV * overload_pow_eq(pTHX_ SV * a, SV * b, SV * third) {
+ SvREFCNT_inc(a);
+
+ if(SvUOK(b)) {
+ mpz_pow_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_pow_eq");
+ mpz_pow_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_pow_eq");
+}
+
+SV * overload_rshift_eq(pTHX_ SV * a, SV * b, SV * third) {
+
+ SvREFCNT_inc(a);
+
+ if(SvUOK(b)) {
+ mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
+ mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
+}
+
+SV * overload_lshift_eq(pTHX_ SV * a, SV * b, SV * third) {
+
+ SvREFCNT_inc(a);
+
+ if(SvUOK(b)) {
+ mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
+ mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
+}
+
+SV * overload_inc(pTHX_ SV * p, SV * second, SV * third) {
+ SvREFCNT_inc(p);
+ mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(p)))), *(INT2PTR(mpz_t *, SvIV(SvRV(p)))), 1);
+ return p;
+}
+
+SV * overload_dec(pTHX_ SV * p, SV * second, SV * third) {
+ SvREFCNT_inc(p);
+ mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(p)))), *(INT2PTR(mpz_t *, SvIV(SvRV(p)))), 1);
+ return p;
+}
+
+SV * overload_mod_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_mod_eq");
+ }
+ mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_mod_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) > 0) {
+ mpz_mod_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+ mpz_init_set_si(t, SvNV(b));
+ mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_mod_eq");
+ }
+ mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_mod(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_mod_eq");
+}
+
+SV * get_refcnt(pTHX_ SV * s) {
+ return newSVuv(SvREFCNT(s));
+}
+
+SV * overload_div_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_div_eq");
+ }
+ mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+ mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ mpz_neg(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))));
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_div_eq");
+ }
+ mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_div_eq function");
+
+}
+
+SV * overload_sub_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_sub_eq");
+ }
+ mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+ mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_sub_eq");
+ }
+ mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_sub(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_sub_eq function");
+
+}
+
+SV * overload_add_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_add_eq");
+ }
+ mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ if(SvIV(b) >= 0) {
+ mpz_add_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+ mpz_sub_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b) * -1);
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak("Invalid string supplied to Math::GMPz::overload_add_eq");
+ }
+ mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_add(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_add_eq function");
+
+}
+
+SV * overload_mul_eq(pTHX_ SV * a, SV * b, SV * third) {
+ mpz_t t;
+#ifdef USE_LONG_DOUBLE
+ char buffer[50];
+#endif
+
+ SvREFCNT_inc(a);
+
+#ifdef USE_64_BIT_INT
+ if(SvIOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak(" Invalid string supplied to Math::GMPz::overload_mul_eq");
+ }
+ mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+#else
+ if(SvUOK(b)) {
+ mpz_mul_ui(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvUV(b));
+ return a;
+ }
+
+ if(SvIOK(b)) {
+ mpz_mul_si(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), SvIV(b));
+ return a;
+ }
+#endif
+
+ if(SvNOK(b)) {
+#ifdef USE_LONG_DOUBLE
+ long double ld = (long double)SvNV(b) >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
+ sprintf(buffer, "%.0Lf", ld);
+ mpz_init_set_str(t, buffer, 10);
+#else
+ mpz_init_set_d(t, SvNV(b));
+#endif
+ mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(SvPOK(b)) {
+ if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
+ SvREFCNT_dec(a);
+ croak(" Invalid string supplied to Math::GMPz::overload_mul_eq");
+ }
+ mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), t);
+ mpz_clear(t);
+ return a;
+ }
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz")) {
+ mpz_mul(*(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(a)))), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ return a;
+ }
+ }
+
+ SvREFCNT_dec(a);
+ croak("Invalid argument supplied to Math::GMPz::overload_mul_eq");
+}
+
+SV * eratosthenes_string(pTHX_ SV * x_arg) {
+
+unsigned char *v, set[8] = {254,253,251,247,239,223,191,127};
+unsigned long leap, i, size, b, imax, k, x = (unsigned long)SvUV(x_arg);
+SV * ret;
+
+if(x & 1) croak("max_num argument must be even in eratosthenes_string");
+
+imax = sqrt(x - 1) / 2;
+
+b = (x + 1) / 2;
+
+if(!(b % 8)) size = b / 8;
+else size = (b / 8) + 1;
+
+ret = NEWSV(0, size);
+
+for(i = 1; i < size; ++i) SvPVX(ret)[i] = 255;
+SvPVX(ret)[0] = 254;
+
+for(i = 0; i <= imax; ++i) {
+
+ if(SvPVX(ret)[i / 8] & (1 << (i % 8))) {
+ leap = (2 * i) + 1;
+ k = 2 * i * (i + 1);
+ while(k < b) {
+ SvPVX(ret)[k / 8] &= set[k % 8];
+ k += leap;
+ }
+ }
+}
+
+SvPOK_on(ret);
+SvCUR_set(ret, size);
+*SvEND(ret) = 0;
+
+return ret;
+
+}
+
+SV * gmp_v(pTHX) {
+#if __GNU_MP_VERSION >= 4
+ return newSVpv(gmp_version, 0);
+#else
+ warn("From Math::GMPz::gmp_v(aTHX): 'gmp_version' is not implemented - returning '0'");
+ return newSVpv("0", 0);
+#endif
+}
+
+SV * wrap_gmp_printf(pTHX_ SV * a, SV * b) {
+ int ret;
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz") ||
+ strEQ(h, "Math::GMP") ||
+ strEQ(h, "GMP::Mpz")) {
+ ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+ if(strEQ(h, "Math::GMPq") ||
+ strEQ(h, "GMP::Mpq")) {
+ ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+ if(strEQ(h, "Math::GMPf") ||
+ strEQ(h, "GMP::Mpf")) {
+ ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised object supplied as argument to Rmpz_printf");
+ }
+
+ if(SvUOK(b)) {
+ ret = gmp_printf(SvPV_nolen(a), SvUV(b));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+ if(SvIOK(b)) {
+ ret = gmp_printf(SvPV_nolen(a), SvIV(b));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+ if(SvNOK(b)) {
+ ret = gmp_printf(SvPV_nolen(a), SvNV(b));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+ if(SvPOK(b)) {
+ ret = gmp_printf(SvPV_nolen(a), SvPV_nolen(b));
+ fflush(stdout);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised type supplied as argument to Rmpz_printf");
+}
+
+SV * wrap_gmp_fprintf(pTHX_ FILE * stream, SV * a, SV * b) {
+ int ret;
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz") ||
+ strEQ(h, "Math::GMP") ||
+ strEQ(h, "GMP::Mpz")) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ fflush(stream);
+ return newSViv(ret);
+ }
+ if(strEQ(h, "Math::GMPq") ||
+ strEQ(h, "GMP::Mpq")) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
+ fflush(stream);
+ return newSViv(ret);
+ }
+ if(strEQ(h, "Math::GMPf") ||
+ strEQ(h, "GMP::Mpf")) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
+ fflush(stream);
+ return newSViv(ret);
+ }
+
+ else croak("Unrecognised object supplied as argument to Rmpz_fprintf");
+ }
+
+ if(SvUOK(b)) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), SvUV(b));
+ fflush(stream);
+ return newSViv(ret);
+ }
+ if(SvIOK(b)) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), SvIV(b));
+ fflush(stream);
+ return newSViv(ret);
+ }
+ if(SvNOK(b)) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), SvNV(b));
+ fflush(stream);
+ return newSViv(ret);
+ }
+ if(SvPOK(b)) {
+ ret = gmp_fprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
+ fflush(stream);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised type supplied as argument to Rmpz_fprintf");
+}
+
+SV * wrap_gmp_sprintf(pTHX_ SV * s, SV * a, SV * b, int buflen) {
+ int ret;
+ char *stream;
+
+ Newx(stream, buflen, char);
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz") ||
+ strEQ(h, "Math::GMP") ||
+ strEQ(h, "GMP::Mpz")) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(strEQ(h, "Math::GMPq") ||
+ strEQ(h, "GMP::Mpq")) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(strEQ(h, "Math::GMPf") ||
+ strEQ(h, "GMP::Mpf")) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised object supplied as argument to Rmpz_sprintf");
+ }
+
+ if(SvUOK(b)) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), SvUV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvIOK(b)) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), SvIV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvNOK(b)) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), SvNV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvPOK(b)) {
+ ret = gmp_sprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised type supplied as argument to Rmpz_sprintf");
+}
+
+SV * wrap_gmp_snprintf(pTHX_ SV * s, SV * bytes, SV * a, SV * b, int buflen) {
+ int ret;
+ char * stream;
+
+ Newx(stream, buflen, char);
+
+ if(sv_isobject(b)) {
+ const char *h = HvNAME(SvSTASH(SvRV(b)));
+ if(strEQ(h, "Math::GMPz") ||
+ strEQ(h, "Math::GMP") ||
+ strEQ(h, "GMP::Mpz")) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(strEQ(h, "Math::GMPq") ||
+ strEQ(h, "GMP::Mpq")) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(strEQ(h, "Math::GMPf") ||
+ strEQ(h, "GMP::Mpf")) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIV(SvRV(b)))));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised object supplied as argument to Rmpz_snprintf");
+ }
+
+ if(SvUOK(b)) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvUV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvIOK(b)) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvIV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvNOK(b)) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvNV(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ if(SvPOK(b)) {
+ ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvPV_nolen(b));
+ sv_setpv(s, stream);
+ Safefree(stream);
+ return newSViv(ret);
+ }
+
+ croak("Unrecognised type supplied as argument to Rmpz_snprintf");
+}
+
+SV * _itsa(pTHX_ SV * a) {
+ if(SvUOK(a)) return newSVuv(1);
+ if(SvIOK(a)) return newSVuv(2);
+ if(SvNOK(a)) return newSVuv(3);
+ if(SvPOK(a)) return newSVuv(4);
+ if(sv_isobject(a)) {
+ const char *h = HvNAME(SvSTASH(SvRV(a)));
+ if(strEQ(h, "Math::GMPz")) return newSVuv(8);
+ if(strEQ(h, "Math::GMP")) return newSVuv(9);
+ }
+ return newSVuv(0);
+}
+
+void Rmpz_urandomb(pTHX_ SV * p, ...) {
+ dXSARGS;
+ unsigned long q, i, thingies;
+
+ thingies = items;
+ q = SvUV(ST(thingies - 1));
+
+ if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomb function");
+
+ for(i = 0; i < q; ++i) {
+ mpz_urandomb(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
+ }
+
+ XSRETURN(0);
+}
+
+void Rmpz_urandomm(pTHX_ SV * x, ...){
+ dXSARGS;
+ unsigned long q, i, thingies;
+
+ thingies = items;
+ q = SvUV(ST(thingies - 1));
+
+ if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomm function");
+
+ for(i = 0; i < q; ++i) {
+ mpz_urandomm(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), *(INT2PTR(mpz_t *, SvIV(SvRV(ST(thingies - 2))))));
+ }
+
+ XSRETURN(0);
+}
+
+void Rmpz_rrandomb(pTHX_ SV * x, ...) {
+ dXSARGS;
+ unsigned long q, i, thingies;
+
+ thingies = items;
+ q = SvUV(ST(thingies - 1));
+
+ if((q + 3) != thingies) croak ("Wrong args supplied to mpz_rrandomb function");
+
+ for(i = 0; i < q; ++i) {
+ mpz_rrandomb(*(INT2PTR(mpz_t *, SvIV(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIV(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
+ }
+
+ XSRETURN(0);
+}
+
+SV * rand_init(pTHX_ SV * seed) {
+ gmp_randstate_t * state;
+ SV * obj_ref, * obj;
+
+ New(1, state, 1, gmp_randstate_t);
+ if(state == NULL) croak("Failed to allocate memory in rand_init function");
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+ gmp_randinit_default(*state);
+ gmp_randseed(*state, *(INT2PTR(mpz_t *, SvIV(SvRV(seed)))));
+ sv_setiv(obj, INT2PTR(IV, state));
+ SvREADONLY_on(obj);
+ return obj_ref;
+ }
+
+void rand_clear(pTHX_ SV * p) {
+ gmp_randclear(*(INT2PTR(gmp_randstate_t *, SvIV(SvRV(p)))));
+ Safefree(INT2PTR(gmp_randstate_t *, SvIV(SvRV(p))));
+ }
+
+int _has_longlong(void) {
+#ifdef USE_64_BIT_INT
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int _has_longdouble(void) {
+#ifdef USE_LONG_DOUBLE
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/* Has inttypes.h been included ? */
+int _has_inttypes(void) {
+#ifdef _MSC_VER
+return 0;
+#else
+#if defined USE_64_BIT_INT
+return 1;
+#else
+return 0;
+#endif
+#endif
+}
+
+SV * Rmpz_inp_raw(pTHX_ mpz_t * a, FILE * stream) {
+ size_t ret = mpz_inp_raw(*a, stream);
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * Rmpz_out_raw(pTHX_ FILE * stream, mpz_t * a) {
+ size_t ret = mpz_out_raw(stream, *a);
+ fflush(stream);
+ return newSVuv(ret);
+}
+
+SV * ___GNU_MP_VERSION(pTHX) {
+ return newSVuv(__GNU_MP_VERSION);
+}
+
+SV * ___GNU_MP_VERSION_MINOR(pTHX) {
+ return newSVuv(__GNU_MP_VERSION_MINOR);
+}
+
+SV * ___GNU_MP_VERSION_PATCHLEVEL(pTHX) {
+ return newSVuv(__GNU_MP_VERSION_PATCHLEVEL);
+}
+
+SV * ___GNU_MP_RELEASE(pTHX) {
+#if defined(__GNU_MP_RELEASE)
+ return newSVuv(__GNU_MP_RELEASE);
+#else
+ return &PL_sv_undef;
+#endif
+}
+
+SV * ___GMP_CC(pTHX) {
+#ifdef __GMP_CC
+ char * ret = __GMP_CC;
+ return newSVpv(ret, 0);
+#else
+ return &PL_sv_undef;
+#endif
+}
+
+SV * ___GMP_CFLAGS(pTHX) {
+#ifdef __GMP_CFLAGS
+ char * ret = __GMP_CFLAGS;
+ return newSVpv(ret, 0);
+#else
+ return &PL_sv_undef;
+#endif
+}
+
+#if __GNU_MP_VERSION >= 5
+#ifndef __MPIR_VERSION
+void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
+ mpz_powm_sec(*dest, *base, *exp, *mod);
+}
+#else
+void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
+ croak("Rmpz_powm_sec not implemented by the mpir library");
+}
+#endif
+#else
+void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
+ croak("Rmpz_powm_sec not implemented - gmp-5 or later needed, this is gmp-%d", __GNU_MP_VERSION);
+}
+#endif
+
+int _using_mpir(void) {
+#ifdef __MPIR_VERSION
+return 1;
+#else
+return 0;
+#endif
+}
+
+SV * _Rmpz_NULL(pTHX) {
+ mpz_t * mpz_t_obj;
+ SV * obj_ref, * obj;
+
+ mpz_t_obj = NULL;
+ obj_ref = newSV(0);
+ obj = newSVrv(obj_ref, NULL);
+
+ sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
+ SvREADONLY_on(obj);
+ return obj_ref;
+}
+
+SV * _wrap_count(pTHX) {
+ return newSVuv(PL_sv_count);
+}
+
+void Rprbg_ms(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
+ mpz_t n, phi, pless1, qless1, mod, keep;
+ unsigned long e, k, bign, r, its, i, r_shift, check;
+ double kdoub;
+ gmp_randstate_t state;
+
+ mpz_init(n);
+ mpz_init(phi);
+ mpz_init(pless1);
+ mpz_init(qless1);
+
+ mpz_sub_ui(qless1, *q, 1);
+ mpz_sub_ui(pless1, *p, 1);
+
+ mpz_mul(n, *p, *q);
+
+ mpz_mul(phi, pless1, qless1);
+ mpz_clear(pless1);
+ mpz_clear(qless1);
+
+ bign = mpz_sizeinbase(n, 2);
+ e = bign / 80;
+
+ while(1) {
+ if(e < 1) croak("You need to choose larger primes P and Q. The product of P-1 and Q-1 needs to be at least an 80-bit number");
+ if(mpz_gcd_ui(NULL, phi, e) == 1) break;
+ --e;
+ if(e < 3) croak("The chosen primes are unsuitable in prbg_ms() function");
+ }
+
+ mpz_clear(phi);
+
+ kdoub = (double) 2 / (double) e;
+ kdoub = (double) 1 - kdoub;
+ kdoub *= (double) bign;
+ k = kdoub;
+ r = bign - k;
+
+ gmp_randinit_default(state);
+ gmp_randseed(state, *seed);
+ mpz_urandomb(*seed, state, r);
+ gmp_randclear(state);
+
+ r_shift = bits_required % k;
+
+ if(r_shift) its = (bits_required / k) + 1;
+ else its = bits_required / k;
+
+ mpz_init(mod);
+ mpz_init(keep);
+ mpz_set_ui(*outref, 0);
+ mpz_ui_pow_ui(mod, 2, k);
+
+ for(i = 0; i < its; ++i) {
+ mpz_powm_ui(*seed, *seed, e, n);
+ mpz_mod(keep, *seed, mod);
+ mpz_mul_2exp(*outref, *outref, k);
+ mpz_add(*outref, *outref, keep);
+ mpz_fdiv_q_2exp(*seed, *seed, k);
+ if(!i) check = k - mpz_sizeinbase(keep, 2);
+ }
+ mpz_clear(n);
+ mpz_clear(keep);
+ mpz_clear(mod);
+
+ if(r_shift) mpz_fdiv_q_2exp(*outref, *outref, k - r_shift);
+
+ if(check + mpz_sizeinbase(*outref, 2) != bits_required)
+ croak("Bug in csprng() function");
+
+}
+
+void Rprbg_bbs(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
+ mpz_t n, gcd, one;
+ unsigned long i, k;
+ gmp_randstate_t state;
+
+ if(mpz_fdiv_ui(*p, 4) != 3) croak ("First prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
+ if(mpz_fdiv_ui(*q, 4) != 3) croak ("Second prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
+ mpz_init(n);
+
+ mpz_mul(n, *p, *q);
+
+ mpz_init(gcd);
+ gmp_randinit_default(state);
+ gmp_randseed(state, *seed);
+ mpz_urandomm(*seed, state, n);
+ gmp_randclear(state);
+
+ while(1) {
+ if(mpz_cmp_ui(*seed, 100) < 0)croak("Blum-Blum-Shub seed is ridiculously small. How did this happen ?");
+ mpz_gcd(gcd, *seed, n);
+ if(!mpz_cmp_ui(gcd, 1)) break;
+ mpz_sub_ui(*seed, *seed, 1);
+ }
+
+ mpz_powm_ui(*seed, *seed, 2, n);
+
+ mpz_init_set_ui(*outref, 0);
+ mpz_init_set_ui(one, 1);
+
+ for(i = 0; i < bits_required; ++i) {
+ mpz_powm_ui(*seed, *seed, 2, n);
+ k = mpz_tstbit(*seed, 0);
+ if(k) {
+ mpz_mul_2exp(gcd, one, i);
+ mpz_add(*outref, gcd, *outref);
+ }
+ }
+
+ mpz_clear(n);
+ mpz_clear(gcd);
+ mpz_clear(one);
+
+}
+
+int Rmonobit(mpz_t * bitstream) {
+ unsigned long len, i, count = 0;
+
+ len = mpz_sizeinbase(*bitstream, 2);
+
+ if(len > 20000) croak("Wrong size random sequence for monobit test");
+ if(len < 19967) {
+ warn("More than 33 leading zeroes in Rmonobit test\n");
+ return 0;
+ }
+
+ count = mpz_popcount(*bitstream);
+
+ if(count > 9654 && count < 10346) return 1;
+ return 0;
+
+}
+
+int Rlong_run(mpz_t * bitstream) {
+ unsigned long i, el, init = 0, count = 0, len, t;
+
+ len = mpz_sizeinbase(*bitstream, 2);
+
+ if(len > 20000) croak("Wrong size random sequence for Rlong_run test");
+ if(len < 19967) {
+ warn("More than 33 leading zeroes in long_run test\n");
+ return 0;
+ }
+
+ el = mpz_tstbit(*bitstream, 0);
+
+ for(i = 0; i < len; ++i) {
+ t = mpz_tstbit(*bitstream, i);
+ if(t == el) ++count;
+ else {
+ el = t;
+ if(count > init) init = count;
+ count = 1;
+ }
+ }
+
+ if(init < 34 && count < 34) return 1;
+ return 0;
+
+}
+
+int Rruns(mpz_t * bitstream) {
+ int b[6] = {0,0,0,0,0,0}, g[6] = {0,0,0,0,0,0},
+ len, count = 1, i, t, diff;
+
+ len = mpz_sizeinbase(*bitstream, 2);
+ diff = 20000 - len;
+
+ if(len > 20000) croak("Wrong size random sequence for monobit test");
+ if(len < 19967) {
+ warn("More than 33 leading zeroes in runs test\n");
+ return 0;
+ }
+
+ --len;
+
+ for(i = 0; i < len; ++i) {
+ t = mpz_tstbit(*bitstream, i);
+ if(t == mpz_tstbit(*bitstream, i + 1)) ++ count;
+ else {
+ if(t) {
+ if(count >= 6) ++b[5];
+ else ++b[count - 1];
+ }
+ else {
+ if(count >= 6) ++g[5];
+ else ++g[count - 1];
+ }
+ count = 1;
+ }
+ }
+
+ if(count >= 6) {
+ if(mpz_tstbit(*bitstream, len)) {
+ ++b[5];
+ if(diff >= 6) {
+ ++g[5];
+ }
+ else {
+ if(diff) ++g[diff - 1];
+ }
+ }
+ else ++g[5];
+ }
+ else {
+ if(mpz_tstbit(*bitstream, len)) {
+ ++b[count - 1];
+ if(diff >= 6) {
+ ++g[5];
+ }
+ else {
+ if(diff) ++ g[diff - 1];
+ }
+ }
+ else {
+ count += diff;
+ count >= 6 ? ++g[5] : ++g[count - 1];
+ }
+ }
+
+
+ if (
+ b[0] <= 2267 || g[0] <= 2267 ||
+ b[0] >= 2733 || g[0] >= 2733 ||
+ b[1] <= 1079 || g[1] <= 1079 ||
+ b[1] >= 1421 || g[1] >= 1421 ||
+ b[2] <= 502 || g[2] <= 502 ||
+ b[2] >= 748 || g[2] >= 748 ||
+ b[3] <= 223 || g[3] <= 223 ||
+ b[3] >= 402 || g[3] >= 402 ||
+ b[4] <= 90 || g[4] <= 90 ||
+ b[4] >= 223 || g[4] >= 223 ||
+ b[5] <= 90 || g[5] <= 90 ||
+ b[5] >= 223 || g[5] >= 223
+ ) return 0;
+
+ return 1;
+
+}
+
+int Rpoker (mpz_t * bitstream) {
+ int counts[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ len, i, st, diff;
+ double n = 0;
+
+ len = mpz_sizeinbase(*bitstream, 2);
+
+ if(len > 20000) croak("Wrong size random sequence for poker test");
+ if(len < 19967) {
+ warn("More than 33 leading zeroes in poker test\n");
+ return 0;
+ }
+
+/* pad with trailing zeroes (if necessary) to achieve length of 20000 bits. */
+ diff = 20000 - len;
+ if(diff) mpz_mul_2exp(*bitstream, *bitstream, diff);
+ if(mpz_sizeinbase(*bitstream, 2) != 20000) croak("Bug in bit sequence manipulation in poker() function");
+
+ for(i = 0; i < 20000; i += 4) {
+ st = mpz_tstbit(*bitstream, i) +
+ (mpz_tstbit(*bitstream, i + 1) * 2) +
+ (mpz_tstbit(*bitstream, i + 2) * 4) +
+ (mpz_tstbit(*bitstream, i + 3) * 8);
+ ++counts[st];
+ }
+
+
+ for(i = 0; i < 16; ++i) n += counts[i] * counts[i];
+
+ n /= 5000;
+ n *= 16;
+ n -= 5000;
+
+ if(n > 1.03 && n < 57.4) return 1;
+
+ return 0;
+}
+
+SV * _get_xs_version(pTHX) {
+ return newSVpv(XS_VERSION, 0);
+}
+
+SV * query_eratosthenes_string(pTHX_ int candidate, char * str) {
+ int cand = candidate - 1;
+ if(cand == 1) return newSVuv(1);
+ if(cand & 1 || cand <= 0) return newSVuv(0);
+ if(str[cand / 16] & 1 << (cand / 2) % 8)
+ return newSVuv(1);
+ return newSVuv(0);
+}
+
+MODULE = Math::GMPz PACKAGE = Math::GMPz
+
+PROTOTYPES: DISABLE
+
+
+SV *
+Rmpz_init_set_str_nobless (num, base)
+ SV * num
+ SV * base
+CODE:
+ RETVAL = Rmpz_init_set_str_nobless (aTHX_ num, base);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init2_nobless (bits)
+ SV * bits
+CODE:
+ RETVAL = Rmpz_init2_nobless (aTHX_ bits);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_nobless ()
+CODE:
+ RETVAL = Rmpz_init_nobless (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+Rmpz_init_set_nobless (p)
+ mpz_t * p
+CODE:
+ RETVAL = Rmpz_init_set_nobless (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_ui_nobless (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_ui_nobless (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_si_nobless (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_si_nobless (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_d_nobless (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_d_nobless (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init ()
+CODE:
+ RETVAL = Rmpz_init (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+Rmpz_init_set (p)
+ mpz_t * p
+CODE:
+ RETVAL = Rmpz_init_set (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_ui (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_ui (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_si (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_si (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_d (p)
+ SV * p
+CODE:
+ RETVAL = Rmpz_init_set_d (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+_Rmpz_init_set_ld (p)
+ SV * p
+CODE:
+ RETVAL = _Rmpz_init_set_ld (aTHX_ p);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init_set_str (num, base)
+ SV * num
+ SV * base
+CODE:
+ RETVAL = Rmpz_init_set_str (aTHX_ num, base);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_init2 (bits)
+ SV * bits
+CODE:
+ RETVAL = Rmpz_init2 (aTHX_ bits);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_get_str (p, base)
+ mpz_t * p
+ SV * base
+CODE:
+ RETVAL = Rmpz_get_str (aTHX_ p, base);
+OUTPUT: RETVAL
+
+void
+DESTROY (p)
+ mpz_t * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ DESTROY(aTHX_ p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_clear (p)
+ mpz_t * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_clear(aTHX_ p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_clear_mpz (p)
+ mpz_t * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_clear_mpz(p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_clear_ptr (p)
+ mpz_t * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_clear_ptr(aTHX_ p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_realloc2 (integer, bits)
+ mpz_t * integer
+ SV * bits
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_realloc2(aTHX_ integer, bits);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set (copy, original)
+ mpz_t * copy
+ mpz_t * original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_q (copy, original)
+ mpz_t * copy
+ mpq_t * original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_q(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_f (copy, original)
+ mpz_t * copy
+ mpf_t * original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_f(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_si (copy, original)
+ mpz_t * copy
+ long original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_si(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_ui (copy, original)
+ mpz_t * copy
+ unsigned long original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_ui(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_d (copy, original)
+ mpz_t * copy
+ double original
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_d(copy, original);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_set_str (copy, original, base)
+ mpz_t * copy
+ SV * original
+ int base
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_set_str(aTHX_ copy, original, base);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_swap (a, b)
+ mpz_t * a
+ mpz_t * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_swap(a, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_get_ui (n)
+ mpz_t * n
+
+long
+Rmpz_get_si (n)
+ mpz_t * n
+
+double
+Rmpz_get_d (n)
+ mpz_t * n
+
+void
+Rmpz_get_d_2exp (n)
+ mpz_t * n
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_get_d_2exp(aTHX_ n);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+Rmpz_getlimbn (p, n)
+ mpz_t * p
+ SV * n
+CODE:
+ RETVAL = Rmpz_getlimbn (aTHX_ p, n);
+OUTPUT: RETVAL
+
+void
+Rmpz_add (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_add(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_add_ui (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ unsigned long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_add_ui(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_sub (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_sub(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_sub_ui (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ unsigned long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_sub_ui(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_ui_sub (dest, num, src)
+ mpz_t * dest
+ unsigned long num
+ mpz_t * src
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_ui_sub(dest, num, src);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mul (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mul(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mul_si (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mul_si(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mul_ui (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ unsigned long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mul_ui(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_addmul (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_addmul(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_addmul_ui (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ unsigned long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_addmul_ui(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_submul (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_submul(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_submul_ui (dest, src, num)
+ mpz_t * dest
+ mpz_t * src
+ unsigned long num
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_submul_ui(dest, src, num);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mul_2exp (dest, src1, b)
+ mpz_t * dest
+ mpz_t * src1
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mul_2exp(aTHX_ dest, src1, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_div_2exp (dest, src1, b)
+ mpz_t * dest
+ mpz_t * src1
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_div_2exp(aTHX_ dest, src1, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_neg (dest, src)
+ mpz_t * dest
+ mpz_t * src
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_neg(dest, src);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_abs (dest, src)
+ mpz_t * dest
+ mpz_t * src
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_abs(dest, src);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_cdiv_q (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_cdiv_q(q, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_cdiv_r (mod, n, d)
+ mpz_t * mod
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_cdiv_r(mod, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_cdiv_qr (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_cdiv_qr(q, r, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_cdiv_q_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_cdiv_r_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_cdiv_qr_ui (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_cdiv_ui (n, d)
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_cdiv_q_2exp (q, n, b)
+ mpz_t * q
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_cdiv_q_2exp(aTHX_ q, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_cdiv_r_2exp (r, n, b)
+ mpz_t * r
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_cdiv_r_2exp(aTHX_ r, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fdiv_q (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fdiv_q(q, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_div (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_div(q, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fdiv_r (mod, n, d)
+ mpz_t * mod
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fdiv_r(mod, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fdiv_qr (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fdiv_qr(q, r, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_divmod (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_divmod(q, r, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_fdiv_q_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_div_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_fdiv_r_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_fdiv_qr_ui (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_divmod_ui (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_fdiv_ui (n, d)
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_fdiv_q_2exp (q, n, b)
+ mpz_t * q
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fdiv_q_2exp(aTHX_ q, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fdiv_r_2exp (r, n, b)
+ mpz_t * r
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fdiv_r_2exp(aTHX_ r, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mod_2exp (r, n, b)
+ mpz_t * r
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mod_2exp(aTHX_ r, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_tdiv_q (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_tdiv_q(q, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_tdiv_r (mod, n, d)
+ mpz_t * mod
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_tdiv_r(mod, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_tdiv_qr (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_tdiv_qr(q, r, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_tdiv_q_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_tdiv_r_ui (q, n, d)
+ mpz_t * q
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_tdiv_qr_ui (q, r, n, d)
+ mpz_t * q
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+unsigned long
+Rmpz_tdiv_ui (n, d)
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_tdiv_q_2exp (q, n, b)
+ mpz_t * q
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_tdiv_q_2exp(aTHX_ q, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_tdiv_r_2exp (r, n, b)
+ mpz_t * r
+ mpz_t * n
+ SV * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_tdiv_r_2exp(aTHX_ r, n, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mod (r, n, d)
+ mpz_t * r
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mod(r, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_mod_ui (r, n, d)
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_divexact (dest, n, d)
+ mpz_t * dest
+ mpz_t * n
+ mpz_t * d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_divexact(dest, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_divexact_ui (dest, n, d)
+ mpz_t * dest
+ mpz_t * n
+ unsigned long d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_divexact_ui(dest, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_divisible_p (n, d)
+ mpz_t * n
+ mpz_t * d
+
+int
+Rmpz_divisible_ui_p (n, d)
+ mpz_t * n
+ unsigned long d
+
+int
+Rmpz_divisible_2exp_p (n, b)
+ mpz_t * n
+ SV * b
+CODE:
+ RETVAL = Rmpz_divisible_2exp_p (aTHX_ n, b);
+OUTPUT: RETVAL
+
+int
+Rmpz_congruent_p (n, c, d)
+ mpz_t * n
+ mpz_t * c
+ mpz_t * d
+
+int
+Rmpz_congruent_ui_p (n, c, d)
+ mpz_t * n
+ unsigned long c
+ unsigned long d
+
+SV *
+Rmpz_congruent_2exp_p (n, c, d)
+ mpz_t * n
+ mpz_t * c
+ SV * d
+CODE:
+ RETVAL = Rmpz_congruent_2exp_p (aTHX_ n, c, d);
+OUTPUT: RETVAL
+
+void
+Rmpz_powm (dest, base, exp, mod)
+ mpz_t * dest
+ mpz_t * base
+ mpz_t * exp
+ mpz_t * mod
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_powm(dest, base, exp, mod);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_powm_ui (dest, base, exp, mod)
+ mpz_t * dest
+ mpz_t * base
+ unsigned long exp
+ mpz_t * mod
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_powm_ui(dest, base, exp, mod);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_pow_ui (dest, base, exp)
+ mpz_t * dest
+ mpz_t * base
+ unsigned long exp
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_pow_ui(dest, base, exp);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_ui_pow_ui (dest, base, exp)
+ mpz_t * dest
+ unsigned long base
+ unsigned long exp
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_ui_pow_ui(dest, base, exp);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_root (r, n, d)
+ mpz_t * r
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_sqrt (r, n)
+ mpz_t * r
+ mpz_t * n
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_sqrt(r, n);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_sqrtrem (root, rem, src)
+ mpz_t * root
+ mpz_t * rem
+ mpz_t * src
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_sqrtrem(root, rem, src);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_perfect_power_p (in)
+ mpz_t * in
+
+int
+Rmpz_perfect_square_p (in)
+ mpz_t * in
+
+int
+Rmpz_probab_prime_p (cand, reps)
+ mpz_t * cand
+ SV * reps
+CODE:
+ RETVAL = Rmpz_probab_prime_p (aTHX_ cand, reps);
+OUTPUT: RETVAL
+
+void
+Rmpz_nextprime (prime, init)
+ mpz_t * prime
+ mpz_t * init
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_nextprime(prime, init);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_gcd (gcd, src1, src2)
+ mpz_t * gcd
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_gcd(gcd, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+unsigned long
+Rmpz_gcd_ui (gcd, n, d)
+ mpz_t * gcd
+ mpz_t * n
+ unsigned long d
+
+void
+Rmpz_gcdext (g, s, t, a, b)
+ mpz_t * g
+ mpz_t * s
+ mpz_t * t
+ mpz_t * a
+ mpz_t * b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_gcdext(g, s, t, a, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_lcm (lcm, src1, src2)
+ mpz_t * lcm
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_lcm(lcm, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_lcm_ui (lcm, src1, src2)
+ mpz_t * lcm
+ mpz_t * src1
+ unsigned long src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_lcm_ui(lcm, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_invert (inv, src1, src2)
+ mpz_t * inv
+ mpz_t * src1
+ mpz_t * src2
+
+int
+Rmpz_jacobi (a, b)
+ mpz_t * a
+ mpz_t * b
+
+int
+Rmpz_legendre (a, b)
+ mpz_t * a
+ mpz_t * b
+
+int
+Rmpz_kronecker (a, b)
+ mpz_t * a
+ mpz_t * b
+
+int
+Rmpz_kronecker_si (a, b)
+ mpz_t * a
+ long b
+
+int
+Rmpz_kronecker_ui (a, b)
+ mpz_t * a
+ unsigned long b
+
+int
+Rmpz_si_kronecker (a, b)
+ long a
+ mpz_t * b
+
+int
+Rmpz_ui_kronecker (a, b)
+ unsigned long a
+ mpz_t * b
+
+SV *
+Rmpz_remove (rem, src1, src2)
+ mpz_t * rem
+ mpz_t * src1
+ mpz_t * src2
+CODE:
+ RETVAL = Rmpz_remove (aTHX_ rem, src1, src2);
+OUTPUT: RETVAL
+
+void
+Rmpz_fac_ui (fac, b)
+ mpz_t * fac
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fac_ui(fac, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_2fac_ui (fac, b)
+ mpz_t * fac
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_2fac_ui(fac, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_mfac_uiui (fac, b, c)
+ mpz_t * fac
+ unsigned long b
+ unsigned long c
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_mfac_uiui(fac, b, c);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_primorial_ui (fac, b)
+ mpz_t * fac
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_primorial_ui(fac, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_bin_ui (dest, n, d)
+ mpz_t * dest
+ mpz_t * n
+ unsigned long d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_bin_ui(dest, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_bin_si (dest, n, d)
+ mpz_t * dest
+ mpz_t * n
+ long d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_bin_si(dest, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_bin_uiui (dest, n, d)
+ mpz_t * dest
+ unsigned long n
+ unsigned long d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_bin_uiui(dest, n, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fib_ui (dest, b)
+ mpz_t * dest
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fib_ui(dest, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_fib2_ui (fn, fnsub1, b)
+ mpz_t * fn
+ mpz_t * fnsub1
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_fib2_ui(fn, fnsub1, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_lucnum_ui (dest, b)
+ mpz_t * dest
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_lucnum_ui(dest, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_lucnum2_ui (ln, lnsub1, b)
+ mpz_t * ln
+ mpz_t * lnsub1
+ unsigned long b
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_lucnum2_ui(ln, lnsub1, b);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_cmp (n, d)
+ mpz_t * n
+ mpz_t * d
+
+int
+Rmpz_cmp_d (n, d)
+ mpz_t * n
+ double d
+
+int
+Rmpz_cmp_si (n, d)
+ mpz_t * n
+ long d
+
+int
+Rmpz_cmp_ui (n, d)
+ mpz_t * n
+ unsigned long d
+
+int
+Rmpz_cmpabs (n, d)
+ mpz_t * n
+ mpz_t * d
+
+int
+Rmpz_cmpabs_d (n, d)
+ mpz_t * n
+ double d
+
+int
+Rmpz_cmpabs_ui (n, d)
+ mpz_t * n
+ unsigned long d
+
+int
+Rmpz_sgn (n)
+ mpz_t * n
+
+void
+Rmpz_and (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_and(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_ior (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_ior(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_xor (dest, src1, src2)
+ mpz_t * dest
+ mpz_t * src1
+ mpz_t * src2
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_xor(dest, src1, src2);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_com (dest, src)
+ mpz_t * dest
+ mpz_t * src
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_com(dest, src);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmpz_popcount (in)
+ mpz_t * in
+
+int
+Rmpz_hamdist (dest, src)
+ mpz_t * dest
+ mpz_t * src
+
+SV *
+Rmpz_scan0 (n, start_bit)
+ mpz_t * n
+ SV * start_bit
+CODE:
+ RETVAL = Rmpz_scan0 (aTHX_ n, start_bit);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_scan1 (n, start_bit)
+ mpz_t * n
+ SV * start_bit
+CODE:
+ RETVAL = Rmpz_scan1 (aTHX_ n, start_bit);
+OUTPUT: RETVAL
+
+void
+Rmpz_setbit (num, bit_index)
+ mpz_t * num
+ SV * bit_index
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_setbit(aTHX_ num, bit_index);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_clrbit (num, bit_index)
+ mpz_t * num
+ SV * bit_index
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_clrbit(aTHX_ num, bit_index);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+Rmpz_tstbit (num, bit_index)
+ mpz_t * num
+ SV * bit_index
+CODE:
+ RETVAL = Rmpz_tstbit (aTHX_ num, bit_index);
+OUTPUT: RETVAL
+
+void
+Rmpz_import (rop, count, order, size, endian, nails, op)
+ mpz_t * rop
+ SV * count
+ SV * order
+ SV * size
+ SV * endian
+ SV * nails
+ SV * op
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_import(aTHX_ rop, count, order, size, endian, nails, op);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+Rmpz_export (order, size, endian, nails, number)
+ SV * order
+ SV * size
+ SV * endian
+ SV * nails
+ mpz_t * number
+CODE:
+ RETVAL = Rmpz_export (aTHX_ order, size, endian, nails, number);
+OUTPUT: RETVAL
+
+int
+Rmpz_fits_ulong_p (in)
+ mpz_t * in
+
+int
+Rmpz_fits_slong_p (in)
+ mpz_t * in
+
+int
+Rmpz_fits_uint_p (in)
+ mpz_t * in
+
+int
+Rmpz_fits_sint_p (in)
+ mpz_t * in
+
+int
+Rmpz_fits_ushort_p (in)
+ mpz_t * in
+
+int
+Rmpz_fits_sshort_p (in)
+ mpz_t * in
+
+int
+Rmpz_odd_p (in)
+ mpz_t * in
+
+int
+Rmpz_even_p (in)
+ mpz_t * in
+
+SV *
+Rmpz_size (in)
+ mpz_t * in
+CODE:
+ RETVAL = Rmpz_size (aTHX_ in);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_sizeinbase (in, base)
+ mpz_t * in
+ int base
+CODE:
+ RETVAL = Rmpz_sizeinbase (aTHX_ in, base);
+OUTPUT: RETVAL
+
+void
+Rsieve_gmp (x_arg, a, number)
+ int x_arg
+ int a
+ mpz_t * number
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rsieve_gmp(aTHX_ x_arg, a, number);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+Rfermat_gmp (num, base)
+ mpz_t * num
+ int base
+CODE:
+ RETVAL = Rfermat_gmp (aTHX_ num, base);
+OUTPUT: RETVAL
+
+SV *
+Rrm_gmp (num, base)
+ mpz_t * num
+ int base
+CODE:
+ RETVAL = Rrm_gmp (aTHX_ num, base);
+OUTPUT: RETVAL
+
+SV *
+_Rmpz_out_str (p, base)
+ mpz_t * p
+ int base
+CODE:
+ RETVAL = _Rmpz_out_str (aTHX_ p, base);
+OUTPUT: RETVAL
+
+SV *
+_Rmpz_out_strS (p, base, suff)
+ mpz_t * p
+ SV * base
+ SV * suff
+CODE:
+ RETVAL = _Rmpz_out_strS (aTHX_ p, base, suff);
+OUTPUT: RETVAL
+
+SV *
+_Rmpz_out_strP (pre, p, base)
+ SV * pre
+ mpz_t * p
+ SV * base
+CODE:
+ RETVAL = _Rmpz_out_strP (aTHX_ pre, p, base);
+OUTPUT: RETVAL
+
+SV *
+_Rmpz_out_strPS (pre, p, base, suff)
+ SV * pre
+ mpz_t * p
+ SV * base
+ SV * suff
+CODE:
+ RETVAL = _Rmpz_out_strPS (aTHX_ pre, p, base, suff);
+OUTPUT: RETVAL
+
+SV *
+_TRmpz_out_str (stream, base, p)
+ FILE * stream
+ SV * base
+ mpz_t * p
+CODE:
+ RETVAL = _TRmpz_out_str (aTHX_ stream, base, p);
+OUTPUT: RETVAL
+
+SV *
+_TRmpz_out_strS (stream, base, p, suff)
+ FILE * stream
+ SV * base
+ mpz_t * p
+ SV * suff
+CODE:
+ RETVAL = _TRmpz_out_strS (aTHX_ stream, base, p, suff);
+OUTPUT: RETVAL
+
+SV *
+_TRmpz_out_strP (pre, stream, base, p)
+ SV * pre
+ FILE * stream
+ SV * base
+ mpz_t * p
+CODE:
+ RETVAL = _TRmpz_out_strP (aTHX_ pre, stream, base, p);
+OUTPUT: RETVAL
+
+SV *
+_TRmpz_out_strPS (pre, stream, base, p, suff)
+ SV * pre
+ FILE * stream
+ SV * base
+ mpz_t * p
+ SV * suff
+CODE:
+ RETVAL = _TRmpz_out_strPS (aTHX_ pre, stream, base, p, suff);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_inp_str (p, base)
+ mpz_t * p
+ int base
+CODE:
+ RETVAL = Rmpz_inp_str (aTHX_ p, base);
+OUTPUT: RETVAL
+
+SV *
+TRmpz_inp_str (p, stream, base)
+ mpz_t * p
+ FILE * stream
+ int base
+CODE:
+ RETVAL = TRmpz_inp_str (aTHX_ p, stream, base);
+OUTPUT: RETVAL
+
+void
+eratosthenes (x_arg)
+ SV * x_arg
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ eratosthenes(aTHX_ x_arg);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+trial_div_ul (num, x_arg)
+ mpz_t * num
+ SV * x_arg
+CODE:
+ RETVAL = trial_div_ul (aTHX_ num, x_arg);
+OUTPUT: RETVAL
+
+void
+Rmpz_rootrem (root, rem, u, d)
+ mpz_t * root
+ mpz_t * rem
+ mpz_t * u
+ unsigned long d
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_rootrem(root, rem, u, d);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_combit (num, bitpos)
+ mpz_t * num
+ SV * bitpos
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_combit(aTHX_ num, bitpos);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+overload_mul (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_mul (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_add (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_add (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_sub (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_sub (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_div (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_div (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_mod (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_mod (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_string (p, second, third)
+ mpz_t * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_string (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_copy (p, second, third)
+ mpz_t * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_copy (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_abs (p, second, third)
+ mpz_t * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_abs (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_lshift (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_lshift (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_rshift (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_rshift (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_pow (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_pow (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_sqrt (p, second, third)
+ mpz_t * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_sqrt (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_and (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_and (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_ior (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_ior (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_xor (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_xor (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_com (p, second, third)
+ mpz_t * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_com (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_gt (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_gt (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_gte (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_gte (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_lt (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_lt (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_lte (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_lte (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_spaceship (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_spaceship (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_equiv (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_equiv (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_not_equiv (a, b, third)
+ mpz_t * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_not_equiv (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_not (a, second, third)
+ mpz_t * a
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_not (aTHX_ a, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_xor_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_xor_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_ior_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_ior_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_and_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_and_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_pow_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_pow_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_rshift_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_rshift_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_lshift_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_lshift_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_inc (p, second, third)
+ SV * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_inc (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_dec (p, second, third)
+ SV * p
+ SV * second
+ SV * third
+CODE:
+ RETVAL = overload_dec (aTHX_ p, second, third);
+OUTPUT: RETVAL
+
+SV *
+overload_mod_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_mod_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+get_refcnt (s)
+ SV * s
+CODE:
+ RETVAL = get_refcnt (aTHX_ s);
+OUTPUT: RETVAL
+
+SV *
+overload_div_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_div_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_sub_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_sub_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_add_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_add_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+overload_mul_eq (a, b, third)
+ SV * a
+ SV * b
+ SV * third
+CODE:
+ RETVAL = overload_mul_eq (aTHX_ a, b, third);
+OUTPUT: RETVAL
+
+SV *
+eratosthenes_string (x_arg)
+ SV * x_arg
+CODE:
+ RETVAL = eratosthenes_string (aTHX_ x_arg);
+OUTPUT: RETVAL
+
+SV *
+gmp_v ()
+CODE:
+ RETVAL = gmp_v (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+wrap_gmp_printf (a, b)
+ SV * a
+ SV * b
+CODE:
+ RETVAL = wrap_gmp_printf (aTHX_ a, b);
+OUTPUT: RETVAL
+
+SV *
+wrap_gmp_fprintf (stream, a, b)
+ FILE * stream
+ SV * a
+ SV * b
+CODE:
+ RETVAL = wrap_gmp_fprintf (aTHX_ stream, a, b);
+OUTPUT: RETVAL
+
+SV *
+wrap_gmp_sprintf (s, a, b, buflen)
+ SV * s
+ SV * a
+ SV * b
+ int buflen
+CODE:
+ RETVAL = wrap_gmp_sprintf (aTHX_ s, a, b, buflen);
+OUTPUT: RETVAL
+
+SV *
+wrap_gmp_snprintf (s, bytes, a, b, buflen)
+ SV * s
+ SV * bytes
+ SV * a
+ SV * b
+ int buflen
+CODE:
+ RETVAL = wrap_gmp_snprintf (aTHX_ s, bytes, a, b, buflen);
+OUTPUT: RETVAL
+
+SV *
+_itsa (a)
+ SV * a
+CODE:
+ RETVAL = _itsa (aTHX_ a);
+OUTPUT: RETVAL
+
+void
+Rmpz_urandomb (p, ...)
+ SV * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_urandomb(aTHX_ p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_urandomm (x, ...)
+ SV * x
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_urandomm(aTHX_ x);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rmpz_rrandomb (x, ...)
+ SV * x
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_rrandomb(aTHX_ x);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+SV *
+rand_init (seed)
+ SV * seed
+CODE:
+ RETVAL = rand_init (aTHX_ seed);
+OUTPUT: RETVAL
+
+void
+rand_clear (p)
+ SV * p
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ rand_clear(aTHX_ p);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+_has_longlong ()
+
+
+int
+_has_longdouble ()
+
+
+int
+_has_inttypes ()
+
+
+SV *
+Rmpz_inp_raw (a, stream)
+ mpz_t * a
+ FILE * stream
+CODE:
+ RETVAL = Rmpz_inp_raw (aTHX_ a, stream);
+OUTPUT: RETVAL
+
+SV *
+Rmpz_out_raw (stream, a)
+ FILE * stream
+ mpz_t * a
+CODE:
+ RETVAL = Rmpz_out_raw (aTHX_ stream, a);
+OUTPUT: RETVAL
+
+SV *
+___GNU_MP_VERSION ()
+CODE:
+ RETVAL = ___GNU_MP_VERSION (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+___GNU_MP_VERSION_MINOR ()
+CODE:
+ RETVAL = ___GNU_MP_VERSION_MINOR (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+___GNU_MP_VERSION_PATCHLEVEL ()
+CODE:
+ RETVAL = ___GNU_MP_VERSION_PATCHLEVEL (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+___GNU_MP_RELEASE ()
+CODE:
+ RETVAL = ___GNU_MP_RELEASE (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+___GMP_CC ()
+CODE:
+ RETVAL = ___GMP_CC (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+___GMP_CFLAGS ()
+CODE:
+ RETVAL = ___GMP_CFLAGS (aTHX);
+OUTPUT: RETVAL
+
+
+void
+Rmpz_powm_sec (dest, base, exp, mod)
+ mpz_t * dest
+ mpz_t * base
+ mpz_t * exp
+ mpz_t * mod
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rmpz_powm_sec(dest, base, exp, mod);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+_using_mpir ()
+
+
+SV *
+_Rmpz_NULL ()
+CODE:
+ RETVAL = _Rmpz_NULL (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+_wrap_count ()
+CODE:
+ RETVAL = _wrap_count (aTHX);
+OUTPUT: RETVAL
+
+
+void
+Rprbg_ms (outref, p, q, seed, bits_required)
+ mpz_t * outref
+ mpz_t * p
+ mpz_t * q
+ mpz_t * seed
+ int bits_required
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rprbg_ms(aTHX_ outref, p, q, seed, bits_required);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+void
+Rprbg_bbs (outref, p, q, seed, bits_required)
+ mpz_t * outref
+ mpz_t * p
+ mpz_t * q
+ mpz_t * seed
+ int bits_required
+ PREINIT:
+ I32* temp;
+ PPCODE:
+ temp = PL_markstack_ptr++;
+ Rprbg_bbs(aTHX_ outref, p, q, seed, bits_required);
+ if (PL_markstack_ptr != temp) {
+ /* truly void, because dXSARGS not invoked */
+ PL_markstack_ptr = temp;
+ XSRETURN_EMPTY; /* return empty stack */
+ }
+ /* must have used dXSARGS; list context implied */
+ return; /* assume stack size is correct */
+
+int
+Rmonobit (bitstream)
+ mpz_t * bitstream
+
+int
+Rlong_run (bitstream)
+ mpz_t * bitstream
+
+int
+Rruns (bitstream)
+ mpz_t * bitstream
+
+int
+Rpoker (bitstream)
+ mpz_t * bitstream
+
+SV *
+_get_xs_version ()
+CODE:
+ RETVAL = _get_xs_version (aTHX);
+OUTPUT: RETVAL
+
+
+SV *
+query_eratosthenes_string (candidate, str)
+ int candidate
+ char * str
+CODE:
+ RETVAL = query_eratosthenes_string (aTHX_ candidate, str);
+OUTPUT: RETVAL
+