From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/mpz/2fac_ui.c | 100 ++++++ gmp-6.3.0/mpz/Makefile | 702 ++++++++++++++++++++++++++++++++++++++++++ gmp-6.3.0/mpz/Makefile.am | 68 +++++ gmp-6.3.0/mpz/Makefile.in | 702 ++++++++++++++++++++++++++++++++++++++++++ gmp-6.3.0/mpz/abs.c | 54 ++++ gmp-6.3.0/mpz/add.c | 33 ++ gmp-6.3.0/mpz/add_ui.c | 33 ++ gmp-6.3.0/mpz/and.c | 222 ++++++++++++++ gmp-6.3.0/mpz/aors.h | 129 ++++++++ gmp-6.3.0/mpz/aors_ui.h | 125 ++++++++ gmp-6.3.0/mpz/aorsmul.c | 179 +++++++++++ gmp-6.3.0/mpz/aorsmul_i.c | 254 ++++++++++++++++ gmp-6.3.0/mpz/array_init.c | 49 +++ gmp-6.3.0/mpz/bin_ui.c | 459 ++++++++++++++++++++++++++++ gmp-6.3.0/mpz/bin_uiui.c | 707 +++++++++++++++++++++++++++++++++++++++++++ gmp-6.3.0/mpz/cdiv_q.c | 52 ++++ gmp-6.3.0/mpz/cdiv_q_ui.c | 102 +++++++ gmp-6.3.0/mpz/cdiv_qr.c | 64 ++++ gmp-6.3.0/mpz/cdiv_qr_ui.c | 118 ++++++++ gmp-6.3.0/mpz/cdiv_r.c | 60 ++++ gmp-6.3.0/mpz/cdiv_r_ui.c | 109 +++++++ gmp-6.3.0/mpz/cdiv_ui.c | 102 +++++++ gmp-6.3.0/mpz/cfdiv_q_2exp.c | 111 +++++++ gmp-6.3.0/mpz/cfdiv_r_2exp.c | 159 ++++++++++ gmp-6.3.0/mpz/clear.c | 40 +++ gmp-6.3.0/mpz/clears.c | 50 +++ gmp-6.3.0/mpz/clrbit.c | 115 +++++++ gmp-6.3.0/mpz/cmp.c | 53 ++++ gmp-6.3.0/mpz/cmp_d.c | 144 +++++++++ gmp-6.3.0/mpz/cmp_si.c | 69 +++++ gmp-6.3.0/mpz/cmp_ui.c | 77 +++++ gmp-6.3.0/mpz/cmpabs.c | 53 ++++ gmp-6.3.0/mpz/cmpabs_d.c | 129 ++++++++ gmp-6.3.0/mpz/cmpabs_ui.c | 76 +++++ gmp-6.3.0/mpz/com.c | 87 ++++++ gmp-6.3.0/mpz/combit.c | 103 +++++++ gmp-6.3.0/mpz/cong.c | 182 +++++++++++ gmp-6.3.0/mpz/cong_2exp.c | 149 +++++++++ gmp-6.3.0/mpz/cong_ui.c | 115 +++++++ gmp-6.3.0/mpz/dive_ui.c | 68 +++++ gmp-6.3.0/mpz/divegcd.c | 156 ++++++++++ gmp-6.3.0/mpz/divexact.c | 89 ++++++ gmp-6.3.0/mpz/divis.c | 43 +++ gmp-6.3.0/mpz/divis_2exp.c | 60 ++++ gmp-6.3.0/mpz/divis_ui.c | 80 +++++ gmp-6.3.0/mpz/dump.c | 48 +++ gmp-6.3.0/mpz/export.c | 189 ++++++++++++ gmp-6.3.0/mpz/fac_ui.c | 122 ++++++++ gmp-6.3.0/mpz/fdiv_q.c | 52 ++++ gmp-6.3.0/mpz/fdiv_q_ui.c | 100 ++++++ gmp-6.3.0/mpz/fdiv_qr.c | 64 ++++ gmp-6.3.0/mpz/fdiv_qr_ui.c | 116 +++++++ gmp-6.3.0/mpz/fdiv_r.c | 59 ++++ gmp-6.3.0/mpz/fdiv_r_ui.c | 107 +++++++ gmp-6.3.0/mpz/fdiv_ui.c | 100 ++++++ gmp-6.3.0/mpz/fib2_ui.c | 58 ++++ gmp-6.3.0/mpz/fib_ui.c | 158 ++++++++++ gmp-6.3.0/mpz/fits_s.h | 60 ++++ gmp-6.3.0/mpz/fits_sint.c | 36 +++ gmp-6.3.0/mpz/fits_slong.c | 36 +++ gmp-6.3.0/mpz/fits_sshort.c | 36 +++ gmp-6.3.0/mpz/fits_uint.c | 33 ++ gmp-6.3.0/mpz/fits_ulong.c | 33 ++ gmp-6.3.0/mpz/fits_ushort.c | 33 ++ gmp-6.3.0/mpz/gcd.c | 164 ++++++++++ gmp-6.3.0/mpz/gcd_ui.c | 92 ++++++ gmp-6.3.0/mpz/gcdext.c | 135 +++++++++ gmp-6.3.0/mpz/get_d.c | 43 +++ gmp-6.3.0/mpz/get_d_2exp.c | 53 ++++ gmp-6.3.0/mpz/get_si.c | 52 ++++ gmp-6.3.0/mpz/get_str.c | 115 +++++++ gmp-6.3.0/mpz/get_ui.c | 33 ++ gmp-6.3.0/mpz/getlimbn.c | 33 ++ gmp-6.3.0/mpz/hamdist.c | 174 +++++++++++ gmp-6.3.0/mpz/import.c | 166 ++++++++++ gmp-6.3.0/mpz/init.c | 41 +++ gmp-6.3.0/mpz/init2.c | 50 +++ gmp-6.3.0/mpz/inits.c | 53 ++++ gmp-6.3.0/mpz/inp_raw.c | 172 +++++++++++ gmp-6.3.0/mpz/inp_str.c | 173 +++++++++++ gmp-6.3.0/mpz/invert.c | 72 +++++ gmp-6.3.0/mpz/ior.c | 184 +++++++++++ gmp-6.3.0/mpz/iset.c | 52 ++++ gmp-6.3.0/mpz/iset_d.c | 43 +++ gmp-6.3.0/mpz/iset_si.c | 58 ++++ gmp-6.3.0/mpz/iset_str.c | 47 +++ gmp-6.3.0/mpz/iset_ui.c | 58 ++++ gmp-6.3.0/mpz/jacobi.c | 210 +++++++++++++ gmp-6.3.0/mpz/kronsz.c | 137 +++++++++ gmp-6.3.0/mpz/kronuz.c | 129 ++++++++ gmp-6.3.0/mpz/kronzs.c | 92 ++++++ gmp-6.3.0/mpz/kronzu.c | 88 ++++++ gmp-6.3.0/mpz/lcm.c | 87 ++++++ gmp-6.3.0/mpz/lcm_ui.c | 78 +++++ gmp-6.3.0/mpz/limbs_finish.c | 39 +++ gmp-6.3.0/mpz/limbs_modify.c | 38 +++ gmp-6.3.0/mpz/limbs_read.c | 37 +++ gmp-6.3.0/mpz/limbs_write.c | 38 +++ gmp-6.3.0/mpz/lucmod.c | 127 ++++++++ gmp-6.3.0/mpz/lucnum2_ui.c | 94 ++++++ gmp-6.3.0/mpz/lucnum_ui.c | 208 +++++++++++++ gmp-6.3.0/mpz/mfac_uiui.c | 140 +++++++++ gmp-6.3.0/mpz/millerrabin.c | 216 +++++++++++++ gmp-6.3.0/mpz/mod.c | 67 ++++ gmp-6.3.0/mpz/mul.c | 159 ++++++++++ gmp-6.3.0/mpz/mul_2exp.c | 72 +++++ gmp-6.3.0/mpz/mul_i.h | 106 +++++++ gmp-6.3.0/mpz/mul_si.c | 34 +++ gmp-6.3.0/mpz/mul_ui.c | 34 +++ gmp-6.3.0/mpz/n_pow_ui.c | 532 ++++++++++++++++++++++++++++++++ gmp-6.3.0/mpz/neg.c | 56 ++++ gmp-6.3.0/mpz/nextprime.c | 291 ++++++++++++++++++ gmp-6.3.0/mpz/oddfac_1.c | 435 ++++++++++++++++++++++++++ gmp-6.3.0/mpz/out_raw.c | 172 +++++++++++ gmp-6.3.0/mpz/out_str.c | 108 +++++++ gmp-6.3.0/mpz/perfpow.c | 38 +++ gmp-6.3.0/mpz/perfsqr.c | 34 +++ gmp-6.3.0/mpz/popcount.c | 34 +++ gmp-6.3.0/mpz/pow_ui.c | 52 ++++ gmp-6.3.0/mpz/powm.c | 282 +++++++++++++++++ gmp-6.3.0/mpz/powm_sec.c | 102 +++++++ gmp-6.3.0/mpz/powm_ui.c | 281 +++++++++++++++++ gmp-6.3.0/mpz/pprime_p.c | 166 ++++++++++ gmp-6.3.0/mpz/primorial_ui.c | 131 ++++++++ gmp-6.3.0/mpz/prodlimbs.c | 108 +++++++ gmp-6.3.0/mpz/random.c | 39 +++ gmp-6.3.0/mpz/random2.c | 51 ++++ gmp-6.3.0/mpz/realloc.c | 70 +++++ gmp-6.3.0/mpz/realloc2.c | 63 ++++ gmp-6.3.0/mpz/remove.c | 146 +++++++++ gmp-6.3.0/mpz/roinit_n.c | 43 +++ gmp-6.3.0/mpz/root.c | 90 ++++++ gmp-6.3.0/mpz/rootrem.c | 100 ++++++ gmp-6.3.0/mpz/rrandomb.c | 102 +++++++ gmp-6.3.0/mpz/scan0.c | 129 ++++++++ gmp-6.3.0/mpz/scan1.c | 123 ++++++++ gmp-6.3.0/mpz/set.c | 49 +++ gmp-6.3.0/mpz/set_d.c | 113 +++++++ gmp-6.3.0/mpz/set_f.c | 71 +++++ gmp-6.3.0/mpz/set_q.c | 34 +++ gmp-6.3.0/mpz/set_si.c | 55 ++++ gmp-6.3.0/mpz/set_str.c | 144 +++++++++ gmp-6.3.0/mpz/set_ui.c | 52 ++++ gmp-6.3.0/mpz/setbit.c | 104 +++++++ gmp-6.3.0/mpz/size.c | 34 +++ gmp-6.3.0/mpz/sizeinbase.c | 42 +++ gmp-6.3.0/mpz/sqrt.c | 76 +++++ gmp-6.3.0/mpz/sqrtrem.c | 85 ++++++ gmp-6.3.0/mpz/stronglucas.c | 214 +++++++++++++ gmp-6.3.0/mpz/sub.c | 33 ++ gmp-6.3.0/mpz/sub_ui.c | 33 ++ gmp-6.3.0/mpz/swap.c | 39 +++ gmp-6.3.0/mpz/tdiv_q.c | 87 ++++++ gmp-6.3.0/mpz/tdiv_q_2exp.c | 67 ++++ gmp-6.3.0/mpz/tdiv_q_ui.c | 83 +++++ gmp-6.3.0/mpz/tdiv_qr.c | 111 +++++++ gmp-6.3.0/mpz/tdiv_qr_ui.c | 100 ++++++ gmp-6.3.0/mpz/tdiv_r.c | 102 +++++++ gmp-6.3.0/mpz/tdiv_r_2exp.c | 76 +++++ gmp-6.3.0/mpz/tdiv_r_ui.c | 96 ++++++ gmp-6.3.0/mpz/tdiv_ui.c | 84 +++++ gmp-6.3.0/mpz/tstbit.c | 80 +++++ gmp-6.3.0/mpz/ui_pow_ui.c | 58 ++++ gmp-6.3.0/mpz/ui_sub.c | 90 ++++++ gmp-6.3.0/mpz/urandomb.c | 47 +++ gmp-6.3.0/mpz/urandomm.c | 98 ++++++ gmp-6.3.0/mpz/xor.c | 146 +++++++++ 167 files changed, 18645 insertions(+) create mode 100644 gmp-6.3.0/mpz/2fac_ui.c create mode 100644 gmp-6.3.0/mpz/Makefile create mode 100644 gmp-6.3.0/mpz/Makefile.am create mode 100644 gmp-6.3.0/mpz/Makefile.in create mode 100644 gmp-6.3.0/mpz/abs.c create mode 100644 gmp-6.3.0/mpz/add.c create mode 100644 gmp-6.3.0/mpz/add_ui.c create mode 100644 gmp-6.3.0/mpz/and.c create mode 100644 gmp-6.3.0/mpz/aors.h create mode 100644 gmp-6.3.0/mpz/aors_ui.h create mode 100644 gmp-6.3.0/mpz/aorsmul.c create mode 100644 gmp-6.3.0/mpz/aorsmul_i.c create mode 100644 gmp-6.3.0/mpz/array_init.c create mode 100644 gmp-6.3.0/mpz/bin_ui.c create mode 100644 gmp-6.3.0/mpz/bin_uiui.c create mode 100644 gmp-6.3.0/mpz/cdiv_q.c create mode 100644 gmp-6.3.0/mpz/cdiv_q_ui.c create mode 100644 gmp-6.3.0/mpz/cdiv_qr.c create mode 100644 gmp-6.3.0/mpz/cdiv_qr_ui.c create mode 100644 gmp-6.3.0/mpz/cdiv_r.c create mode 100644 gmp-6.3.0/mpz/cdiv_r_ui.c create mode 100644 gmp-6.3.0/mpz/cdiv_ui.c create mode 100644 gmp-6.3.0/mpz/cfdiv_q_2exp.c create mode 100644 gmp-6.3.0/mpz/cfdiv_r_2exp.c create mode 100644 gmp-6.3.0/mpz/clear.c create mode 100644 gmp-6.3.0/mpz/clears.c create mode 100644 gmp-6.3.0/mpz/clrbit.c create mode 100644 gmp-6.3.0/mpz/cmp.c create mode 100644 gmp-6.3.0/mpz/cmp_d.c create mode 100644 gmp-6.3.0/mpz/cmp_si.c create mode 100644 gmp-6.3.0/mpz/cmp_ui.c create mode 100644 gmp-6.3.0/mpz/cmpabs.c create mode 100644 gmp-6.3.0/mpz/cmpabs_d.c create mode 100644 gmp-6.3.0/mpz/cmpabs_ui.c create mode 100644 gmp-6.3.0/mpz/com.c create mode 100644 gmp-6.3.0/mpz/combit.c create mode 100644 gmp-6.3.0/mpz/cong.c create mode 100644 gmp-6.3.0/mpz/cong_2exp.c create mode 100644 gmp-6.3.0/mpz/cong_ui.c create mode 100644 gmp-6.3.0/mpz/dive_ui.c create mode 100644 gmp-6.3.0/mpz/divegcd.c create mode 100644 gmp-6.3.0/mpz/divexact.c create mode 100644 gmp-6.3.0/mpz/divis.c create mode 100644 gmp-6.3.0/mpz/divis_2exp.c create mode 100644 gmp-6.3.0/mpz/divis_ui.c create mode 100644 gmp-6.3.0/mpz/dump.c create mode 100644 gmp-6.3.0/mpz/export.c create mode 100644 gmp-6.3.0/mpz/fac_ui.c create mode 100644 gmp-6.3.0/mpz/fdiv_q.c create mode 100644 gmp-6.3.0/mpz/fdiv_q_ui.c create mode 100644 gmp-6.3.0/mpz/fdiv_qr.c create mode 100644 gmp-6.3.0/mpz/fdiv_qr_ui.c create mode 100644 gmp-6.3.0/mpz/fdiv_r.c create mode 100644 gmp-6.3.0/mpz/fdiv_r_ui.c create mode 100644 gmp-6.3.0/mpz/fdiv_ui.c create mode 100644 gmp-6.3.0/mpz/fib2_ui.c create mode 100644 gmp-6.3.0/mpz/fib_ui.c create mode 100644 gmp-6.3.0/mpz/fits_s.h create mode 100644 gmp-6.3.0/mpz/fits_sint.c create mode 100644 gmp-6.3.0/mpz/fits_slong.c create mode 100644 gmp-6.3.0/mpz/fits_sshort.c create mode 100644 gmp-6.3.0/mpz/fits_uint.c create mode 100644 gmp-6.3.0/mpz/fits_ulong.c create mode 100644 gmp-6.3.0/mpz/fits_ushort.c create mode 100644 gmp-6.3.0/mpz/gcd.c create mode 100644 gmp-6.3.0/mpz/gcd_ui.c create mode 100644 gmp-6.3.0/mpz/gcdext.c create mode 100644 gmp-6.3.0/mpz/get_d.c create mode 100644 gmp-6.3.0/mpz/get_d_2exp.c create mode 100644 gmp-6.3.0/mpz/get_si.c create mode 100644 gmp-6.3.0/mpz/get_str.c create mode 100644 gmp-6.3.0/mpz/get_ui.c create mode 100644 gmp-6.3.0/mpz/getlimbn.c create mode 100644 gmp-6.3.0/mpz/hamdist.c create mode 100644 gmp-6.3.0/mpz/import.c create mode 100644 gmp-6.3.0/mpz/init.c create mode 100644 gmp-6.3.0/mpz/init2.c create mode 100644 gmp-6.3.0/mpz/inits.c create mode 100644 gmp-6.3.0/mpz/inp_raw.c create mode 100644 gmp-6.3.0/mpz/inp_str.c create mode 100644 gmp-6.3.0/mpz/invert.c create mode 100644 gmp-6.3.0/mpz/ior.c create mode 100644 gmp-6.3.0/mpz/iset.c create mode 100644 gmp-6.3.0/mpz/iset_d.c create mode 100644 gmp-6.3.0/mpz/iset_si.c create mode 100644 gmp-6.3.0/mpz/iset_str.c create mode 100644 gmp-6.3.0/mpz/iset_ui.c create mode 100644 gmp-6.3.0/mpz/jacobi.c create mode 100644 gmp-6.3.0/mpz/kronsz.c create mode 100644 gmp-6.3.0/mpz/kronuz.c create mode 100644 gmp-6.3.0/mpz/kronzs.c create mode 100644 gmp-6.3.0/mpz/kronzu.c create mode 100644 gmp-6.3.0/mpz/lcm.c create mode 100644 gmp-6.3.0/mpz/lcm_ui.c create mode 100644 gmp-6.3.0/mpz/limbs_finish.c create mode 100644 gmp-6.3.0/mpz/limbs_modify.c create mode 100644 gmp-6.3.0/mpz/limbs_read.c create mode 100644 gmp-6.3.0/mpz/limbs_write.c create mode 100644 gmp-6.3.0/mpz/lucmod.c create mode 100644 gmp-6.3.0/mpz/lucnum2_ui.c create mode 100644 gmp-6.3.0/mpz/lucnum_ui.c create mode 100644 gmp-6.3.0/mpz/mfac_uiui.c create mode 100644 gmp-6.3.0/mpz/millerrabin.c create mode 100644 gmp-6.3.0/mpz/mod.c create mode 100644 gmp-6.3.0/mpz/mul.c create mode 100644 gmp-6.3.0/mpz/mul_2exp.c create mode 100644 gmp-6.3.0/mpz/mul_i.h create mode 100644 gmp-6.3.0/mpz/mul_si.c create mode 100644 gmp-6.3.0/mpz/mul_ui.c create mode 100644 gmp-6.3.0/mpz/n_pow_ui.c create mode 100644 gmp-6.3.0/mpz/neg.c create mode 100644 gmp-6.3.0/mpz/nextprime.c create mode 100644 gmp-6.3.0/mpz/oddfac_1.c create mode 100644 gmp-6.3.0/mpz/out_raw.c create mode 100644 gmp-6.3.0/mpz/out_str.c create mode 100644 gmp-6.3.0/mpz/perfpow.c create mode 100644 gmp-6.3.0/mpz/perfsqr.c create mode 100644 gmp-6.3.0/mpz/popcount.c create mode 100644 gmp-6.3.0/mpz/pow_ui.c create mode 100644 gmp-6.3.0/mpz/powm.c create mode 100644 gmp-6.3.0/mpz/powm_sec.c create mode 100644 gmp-6.3.0/mpz/powm_ui.c create mode 100644 gmp-6.3.0/mpz/pprime_p.c create mode 100644 gmp-6.3.0/mpz/primorial_ui.c create mode 100644 gmp-6.3.0/mpz/prodlimbs.c create mode 100644 gmp-6.3.0/mpz/random.c create mode 100644 gmp-6.3.0/mpz/random2.c create mode 100644 gmp-6.3.0/mpz/realloc.c create mode 100644 gmp-6.3.0/mpz/realloc2.c create mode 100644 gmp-6.3.0/mpz/remove.c create mode 100644 gmp-6.3.0/mpz/roinit_n.c create mode 100644 gmp-6.3.0/mpz/root.c create mode 100644 gmp-6.3.0/mpz/rootrem.c create mode 100644 gmp-6.3.0/mpz/rrandomb.c create mode 100644 gmp-6.3.0/mpz/scan0.c create mode 100644 gmp-6.3.0/mpz/scan1.c create mode 100644 gmp-6.3.0/mpz/set.c create mode 100644 gmp-6.3.0/mpz/set_d.c create mode 100644 gmp-6.3.0/mpz/set_f.c create mode 100644 gmp-6.3.0/mpz/set_q.c create mode 100644 gmp-6.3.0/mpz/set_si.c create mode 100644 gmp-6.3.0/mpz/set_str.c create mode 100644 gmp-6.3.0/mpz/set_ui.c create mode 100644 gmp-6.3.0/mpz/setbit.c create mode 100644 gmp-6.3.0/mpz/size.c create mode 100644 gmp-6.3.0/mpz/sizeinbase.c create mode 100644 gmp-6.3.0/mpz/sqrt.c create mode 100644 gmp-6.3.0/mpz/sqrtrem.c create mode 100644 gmp-6.3.0/mpz/stronglucas.c create mode 100644 gmp-6.3.0/mpz/sub.c create mode 100644 gmp-6.3.0/mpz/sub_ui.c create mode 100644 gmp-6.3.0/mpz/swap.c create mode 100644 gmp-6.3.0/mpz/tdiv_q.c create mode 100644 gmp-6.3.0/mpz/tdiv_q_2exp.c create mode 100644 gmp-6.3.0/mpz/tdiv_q_ui.c create mode 100644 gmp-6.3.0/mpz/tdiv_qr.c create mode 100644 gmp-6.3.0/mpz/tdiv_qr_ui.c create mode 100644 gmp-6.3.0/mpz/tdiv_r.c create mode 100644 gmp-6.3.0/mpz/tdiv_r_2exp.c create mode 100644 gmp-6.3.0/mpz/tdiv_r_ui.c create mode 100644 gmp-6.3.0/mpz/tdiv_ui.c create mode 100644 gmp-6.3.0/mpz/tstbit.c create mode 100644 gmp-6.3.0/mpz/ui_pow_ui.c create mode 100644 gmp-6.3.0/mpz/ui_sub.c create mode 100644 gmp-6.3.0/mpz/urandomb.c create mode 100644 gmp-6.3.0/mpz/urandomm.c create mode 100644 gmp-6.3.0/mpz/xor.c (limited to 'gmp-6.3.0/mpz') diff --git a/gmp-6.3.0/mpz/2fac_ui.c b/gmp-6.3.0/mpz/2fac_ui.c new file mode 100644 index 0000000..141a0a7 --- /dev/null +++ b/gmp-6.3.0/mpz/2fac_ui.c @@ -0,0 +1,100 @@ +/* mpz_2fac_ui(RESULT, N) -- Set RESULT to N!!. + +Contributed to the GNU project by Marco Bodrato. + +Copyright 2012, 2015, 2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +#define FAC_2DSC_THRESHOLD ((FAC_DSC_THRESHOLD << 1) | (FAC_DSC_THRESHOLD & 1)) +#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_2DSC_THRESHOLD-1)+1)) + +/* Computes n!!, the 2-multi-factorial of n. (aka double-factorial or semi-factorial) + WARNING: it assumes that n fits in a limb! + */ +void +mpz_2fac_ui (mpz_ptr x, unsigned long n) +{ + ASSERT (n <= GMP_NUMB_MAX); + + if ((n & 1) == 0) { /* n is even, n = 2k, (2k)!! = k! 2^k */ + mp_limb_t count; + + if ((n <= TABLE_LIMIT_2N_MINUS_POPC_2N) & (n != 0)) + count = __gmp_fac2cnt_table[n / 2 - 1]; + else + { + popc_limb (count, n); /* popc(n) == popc(k) */ + count = n - count; /* n - popc(n) == k + k - popc(k) */ + } + mpz_oddfac_1 (x, n >> 1, 0); + mpz_mul_2exp (x, x, count); + } else { /* n is odd */ + if (n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT) { + MPZ_NEWALLOC (x, 1)[0] = __gmp_odd2fac_table[n >> 1]; + SIZ (x) = 1; + } else if (BELOW_THRESHOLD (n, FAC_2DSC_THRESHOLD)) { /* odd basecase, */ + mp_limb_t *factors, prod, max_prod; + mp_size_t j; + TMP_SDECL; + + /* FIXME: we might alloc a fixed amount 1+FAC_2DSC_THRESHOLD/FACTORS_PER_LIMB */ + TMP_SMARK; + factors = TMP_SALLOC_LIMBS (1 + n / (2 * FACTORS_PER_LIMB)); + + factors[0] = ODD_DOUBLEFACTORIAL_TABLE_MAX; + j = 1; + prod = n; + + max_prod = GMP_NUMB_MAX / FAC_2DSC_THRESHOLD; + while ((n -= 2) > ODD_DOUBLEFACTORIAL_TABLE_LIMIT) + FACTOR_LIST_STORE (n, prod, max_prod, factors, j); + + factors[j++] = prod; + mpz_prodlimbs (x, factors, j); + + TMP_SFREE; + } else { /* for the asymptotically fast odd case, let oddfac do the job. */ + mpz_oddfac_1 (x, n, 1); + } + } +} + +#undef FACTORS_PER_LIMB +#undef FACTOR_LIST_STORE +#undef FAC_2DSC_THRESHOLD diff --git a/gmp-6.3.0/mpz/Makefile b/gmp-6.3.0/mpz/Makefile new file mode 100644 index 0000000..4c4cb67 --- /dev/null +++ b/gmp-6.3.0/mpz/Makefile @@ -0,0 +1,702 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# mpz/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +# Copyright 1996, 1998-2003, 2012 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library. +# +# The GNU MP Library is free software; you can redistribute it and/or modify +# it under the terms of either: +# +# * the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# or +# +# * the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# or both in parallel, as here. +# +# The GNU MP Library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received copies of the GNU General Public License and the +# GNU Lesser General Public License along with the GNU MP Library. If not, +# see https://www.gnu.org/licenses/. + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/gmp +pkgincludedir = $(includedir)/gmp +pkglibdir = $(libdir)/gmp +pkglibexecdir = $(libexecdir)/gmp +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = pentiumm-pc-linux-gnu +host_triplet = pentiumm-pc-linux-gnu +subdir = mpz +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libmpz_la_LIBADD = +am_libmpz_la_OBJECTS = 2fac_ui.lo add.lo add_ui.lo abs.lo aorsmul.lo \ + aorsmul_i.lo and.lo array_init.lo bin_ui.lo bin_uiui.lo \ + cdiv_q.lo cdiv_q_ui.lo cdiv_qr.lo cdiv_qr_ui.lo cdiv_r.lo \ + cdiv_r_ui.lo cdiv_ui.lo cfdiv_q_2exp.lo cfdiv_r_2exp.lo \ + clear.lo clears.lo clrbit.lo cmp.lo cmp_d.lo cmp_si.lo \ + cmp_ui.lo cmpabs.lo cmpabs_d.lo cmpabs_ui.lo com.lo combit.lo \ + cong.lo cong_2exp.lo cong_ui.lo divexact.lo divegcd.lo \ + dive_ui.lo divis.lo divis_ui.lo divis_2exp.lo dump.lo \ + export.lo fac_ui.lo fdiv_q.lo fdiv_q_ui.lo fdiv_qr.lo \ + fdiv_qr_ui.lo fdiv_r.lo fdiv_r_ui.lo fdiv_ui.lo fib_ui.lo \ + fib2_ui.lo fits_sint.lo fits_slong.lo fits_sshort.lo \ + fits_uint.lo fits_ulong.lo fits_ushort.lo gcd.lo gcd_ui.lo \ + gcdext.lo get_d.lo get_d_2exp.lo get_si.lo get_str.lo \ + get_ui.lo getlimbn.lo hamdist.lo import.lo init.lo init2.lo \ + inits.lo inp_raw.lo inp_str.lo invert.lo ior.lo iset.lo \ + iset_d.lo iset_si.lo iset_str.lo iset_ui.lo jacobi.lo \ + kronsz.lo kronuz.lo kronzs.lo kronzu.lo lcm.lo lcm_ui.lo \ + limbs_read.lo limbs_write.lo limbs_modify.lo limbs_finish.lo \ + lucnum_ui.lo lucnum2_ui.lo lucmod.lo mfac_uiui.lo \ + millerrabin.lo mod.lo mul.lo mul_2exp.lo mul_si.lo mul_ui.lo \ + n_pow_ui.lo neg.lo nextprime.lo oddfac_1.lo out_raw.lo \ + out_str.lo perfpow.lo perfsqr.lo popcount.lo pow_ui.lo powm.lo \ + powm_sec.lo powm_ui.lo pprime_p.lo prodlimbs.lo \ + primorial_ui.lo random.lo random2.lo realloc.lo realloc2.lo \ + remove.lo roinit_n.lo root.lo rootrem.lo rrandomb.lo scan0.lo \ + scan1.lo set.lo set_d.lo set_f.lo set_q.lo set_si.lo \ + set_str.lo set_ui.lo setbit.lo size.lo sizeinbase.lo sqrt.lo \ + sqrtrem.lo stronglucas.lo sub.lo sub_ui.lo swap.lo tdiv_ui.lo \ + tdiv_q.lo tdiv_q_2exp.lo tdiv_q_ui.lo tdiv_qr.lo tdiv_qr_ui.lo \ + tdiv_r.lo tdiv_r_2exp.lo tdiv_r_ui.lo tstbit.lo ui_pow_ui.lo \ + ui_sub.lo urandomb.lo urandomm.lo xor.lo +libmpz_la_OBJECTS = $(am_libmpz_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libmpz_la_SOURCES) +DIST_SOURCES = $(libmpz_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABI = 32 +ACLOCAL = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/missing aclocal-1.15 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 1 +AR = ar +AS = as +ASMFLAGS = -Wa,--noexecstack +AUTOCONF = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/missing autoconf +AUTOHEADER = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/missing autoheader +AUTOMAKE = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/missing automake-1.15 +AWK = gawk +CALLING_CONVENTIONS_OBJS = x86call.lo x86check$U.lo +CC = gcc +CCAS = gcc -c +CC_FOR_BUILD = gcc +CFLAGS = -m32 -O2 -pedantic -fomit-frame-pointer -mtune=pentium3 -march=pentium3 +CPP = gcc -E +CPPFLAGS = +CPP_FOR_BUILD = gcc -E +CXX = +CXXCPP = +CXXFLAGS = +CYGPATH_W = echo +DEFN_LONG_LONG_LIMB = /* #undef _LONG_LONG_LIMB */ +DEFS = -DHAVE_CONFIG_H +DLLTOOL = dlltool +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /usr/bin/grep -E +EXEEXT = +EXEEXT_FOR_BUILD = +FGREP = /usr/bin/grep -F +GMP_LDFLAGS = +GMP_LIMB_BITS = 32 +GMP_NAIL_BITS = 0 +GREP = /usr/bin/grep +HAVE_CLOCK_01 = 1 +HAVE_CPUTIME_01 = 0 +HAVE_GETRUSAGE_01 = 1 +HAVE_GETTIMEOFDAY_01 = 1 +HAVE_HOST_CPU_FAMILY_power = 0 +HAVE_HOST_CPU_FAMILY_powerpc = 0 +HAVE_SIGACTION_01 = 1 +HAVE_SIGALTSTACK_01 = 1 +HAVE_SIGSTACK_01 = 1 +HAVE_STACK_T_01 = 1 +HAVE_SYS_RESOURCE_H_01 = 1 +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LD = /usr/bin/ld +LDFLAGS = +LEX = flex +LEXLIB = -lfl +LEX_OUTPUT_ROOT = lex.yy +LIBCURSES = -lncurses +LIBGMPXX_LDFLAGS = +LIBGMP_DLL = 0 +LIBGMP_LDFLAGS = +LIBM = -lm +LIBM_FOR_BUILD = -lm +LIBOBJS = +LIBREADLINE = -lreadline +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +LT_SYS_LIBRARY_PATH = +M4 = m4 +MAINT = # +MAKEINFO = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/missing makeinfo +MANIFEST_TOOL = : +MKDIR_P = /usr/bin/mkdir -p +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = gmp +PACKAGE_BUGREPORT = gmp-bugs@gmplib.org (see https://gmplib.org/manual/Reporting-Bugs.html) +PACKAGE_NAME = GNU MP +PACKAGE_STRING = GNU MP 6.3.0 +PACKAGE_TARNAME = gmp +PACKAGE_URL = http://www.gnu.org/software/gmp/ +PACKAGE_VERSION = 6.3.0 +PATH_SEPARATOR = : +RANLIB = ranlib +SED = /usr/bin/sed +SET_MAKE = +SHELL = /bin/sh +SPEED_CYCLECOUNTER_OBJ = pentium.lo +STRIP = strip +TAL_OBJECT = tal-reent.lo +TUNE_LIBS = +TUNE_SQR_OBJ = +U_FOR_BUILD = +VERSION = 6.3.0 +WITH_READLINE_01 = 1 +YACC = bison -y +YFLAGS = +abs_builddir = /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/mpz +abs_srcdir = /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/mpz +abs_top_builddir = /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0 +abs_top_srcdir = /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0 +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_CXX = +ac_ct_DUMPBIN = +am__leading_dot = . +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = ${exec_prefix}/bin +build = pentiumm-pc-linux-gnu +build_alias = +build_cpu = pentiumm +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +gmp_srclinks = mpn/add.c mpn/add_1.c mpn/add_n.asm mpn/sub.c mpn/sub_1.c mpn/sub_n.asm mpn/cnd_add_n.asm mpn/cnd_sub_n.asm mpn/cnd_swap.c mpn/neg.c mpn/com.c mpn/mul_1.asm mpn/addmul_1.asm mpn/submul_1.asm mpn/add_err1_n.c mpn/add_err2_n.c mpn/add_err3_n.c mpn/sub_err1_n.c mpn/sub_err2_n.c mpn/sub_err3_n.c mpn/lshift.asm mpn/rshift.asm mpn/dive_1.asm mpn/diveby3.c mpn/divis.c mpn/divrem.c mpn/divrem_1.asm mpn/divrem_2.asm mpn/fib2_ui.c mpn/fib2m.c mpn/mod_1.c mpn/mod_34lsub1.asm mpn/mode1o.asm mpn/pre_mod_1.c mpn/dump.c mpn/mod_1_1.asm mpn/mod_1_2.c mpn/mod_1_3.c mpn/mod_1_4.asm mpn/lshiftc.c mpn/mul.c mpn/mul_fft.c mpn/mul_n.c mpn/sqr.c mpn/mul_basecase.asm mpn/sqr_basecase.asm mpn/nussbaumer_mul.c mpn/mulmid_basecase.c mpn/toom42_mulmid.c mpn/mulmid_n.c mpn/mulmid.c mpn/random.c mpn/random2.c mpn/pow_1.c mpn/rootrem.c mpn/sqrtrem.c mpn/sizeinbase.c mpn/get_str.c mpn/set_str.c mpn/compute_powtab.c mpn/scan0.c mpn/scan1.c mpn/popcount.asm mpn/hamdist.asm mpn/cmp.c mpn/zero_p.c mpn/perfsqr.c mpn/perfpow.c mpn/strongfibo.c mpn/gcd_11.asm mpn/gcd_22.c mpn/gcd_1.c mpn/gcd.c mpn/gcdext_1.c mpn/gcdext.c mpn/gcd_subdiv_step.c mpn/gcdext_lehmer.c mpn/div_q.c mpn/tdiv_qr.c mpn/jacbase.c mpn/jacobi_2.c mpn/jacobi.c mpn/get_d.c mpn/matrix22_mul.c mpn/matrix22_mul1_inverse_vector.c mpn/hgcd_matrix.c mpn/hgcd2.c mpn/hgcd_step.c mpn/hgcd_reduce.c mpn/hgcd.c mpn/hgcd_appr.c mpn/hgcd2_jacobi.c mpn/hgcd_jacobi.c mpn/mullo_n.c mpn/mullo_basecase.c mpn/sqrlo.c mpn/sqrlo_basecase.c mpn/toom22_mul.c mpn/toom32_mul.c mpn/toom42_mul.c mpn/toom52_mul.c mpn/toom62_mul.c mpn/toom33_mul.c mpn/toom43_mul.c mpn/toom53_mul.c mpn/toom54_mul.c mpn/toom63_mul.c mpn/toom44_mul.c mpn/toom6h_mul.c mpn/toom6_sqr.c mpn/toom8h_mul.c mpn/toom8_sqr.c mpn/toom_couple_handling.c mpn/toom2_sqr.c mpn/toom3_sqr.c mpn/toom4_sqr.c mpn/toom_eval_dgr3_pm1.c mpn/toom_eval_dgr3_pm2.c mpn/toom_eval_pm1.c mpn/toom_eval_pm2.c mpn/toom_eval_pm2exp.c mpn/toom_eval_pm2rexp.c mpn/toom_interpolate_5pts.c mpn/toom_interpolate_6pts.c mpn/toom_interpolate_7pts.c mpn/toom_interpolate_8pts.c mpn/toom_interpolate_12pts.c mpn/toom_interpolate_16pts.c mpn/invertappr.c mpn/invert.c mpn/binvert.c mpn/mulmod_bnm1.c mpn/sqrmod_bnm1.c mpn/mulmod_bknp1.c mpn/div_qr_1.c mpn/div_qr_1n_pi1.c mpn/div_qr_2.c mpn/div_qr_2n_pi1.c mpn/div_qr_2u_pi1.c mpn/sbpi1_div_q.c mpn/sbpi1_div_qr.c mpn/sbpi1_divappr_q.c mpn/dcpi1_div_q.c mpn/dcpi1_div_qr.c mpn/dcpi1_divappr_q.c mpn/mu_div_qr.c mpn/mu_divappr_q.c mpn/mu_div_q.c mpn/bdiv_q_1.asm mpn/sbpi1_bdiv_q.c mpn/sbpi1_bdiv_qr.c mpn/sbpi1_bdiv_r.c mpn/dcpi1_bdiv_q.c mpn/dcpi1_bdiv_qr.c mpn/mu_bdiv_q.c mpn/mu_bdiv_qr.c mpn/bdiv_q.c mpn/bdiv_qr.c mpn/broot.c mpn/brootinv.c mpn/bsqrt.c mpn/bsqrtinv.c mpn/divexact.c mpn/bdiv_dbm1c.asm mpn/redc_1.c mpn/redc_2.c mpn/redc_n.c mpn/powm.c mpn/powlo.c mpn/sec_powm.c mpn/sec_mul.c mpn/sec_sqr.c mpn/sec_div_qr.c mpn/sec_div_r.c mpn/sec_pi1_div_qr.c mpn/sec_pi1_div_r.c mpn/sec_add_1.c mpn/sec_sub_1.c mpn/sec_invert.c mpn/trialdiv.c mpn/remove.c mpn/and_n.c mpn/andn_n.c mpn/nand_n.c mpn/ior_n.c mpn/iorn_n.c mpn/nior_n.c mpn/xor_n.c mpn/xnor_n.c mpn/copyi.asm mpn/copyd.asm mpn/zero.c mpn/sec_tabselect.asm mpn/comb_tables.c mpn/umul.asm mpn/udiv.asm mpn/add_n_sub_n.c gmp-mparam.h +host = pentiumm-pc-linux-gnu +host_alias = +host_cpu = pentiumm +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +mpn_objects = add$U.lo add_1$U.lo add_n.lo sub$U.lo sub_1$U.lo sub_n.lo cnd_add_n.lo cnd_sub_n.lo cnd_swap$U.lo neg$U.lo com$U.lo mul_1.lo addmul_1.lo submul_1.lo add_err1_n$U.lo add_err2_n$U.lo add_err3_n$U.lo sub_err1_n$U.lo sub_err2_n$U.lo sub_err3_n$U.lo lshift.lo rshift.lo dive_1.lo diveby3$U.lo divis$U.lo divrem$U.lo divrem_1.lo divrem_2.lo fib2_ui$U.lo fib2m$U.lo mod_1$U.lo mod_34lsub1.lo mode1o.lo pre_mod_1$U.lo dump$U.lo mod_1_1.lo mod_1_2$U.lo mod_1_3$U.lo mod_1_4.lo lshiftc$U.lo mul$U.lo mul_fft$U.lo mul_n$U.lo sqr$U.lo mul_basecase.lo sqr_basecase.lo nussbaumer_mul$U.lo mulmid_basecase$U.lo toom42_mulmid$U.lo mulmid_n$U.lo mulmid$U.lo random$U.lo random2$U.lo pow_1$U.lo rootrem$U.lo sqrtrem$U.lo sizeinbase$U.lo get_str$U.lo set_str$U.lo compute_powtab$U.lo scan0$U.lo scan1$U.lo popcount.lo hamdist.lo cmp$U.lo zero_p$U.lo perfsqr$U.lo perfpow$U.lo strongfibo$U.lo gcd_11.lo gcd_22$U.lo gcd_1$U.lo gcd$U.lo gcdext_1$U.lo gcdext$U.lo gcd_subdiv_step$U.lo gcdext_lehmer$U.lo div_q$U.lo tdiv_qr$U.lo jacbase$U.lo jacobi_2$U.lo jacobi$U.lo get_d$U.lo matrix22_mul$U.lo matrix22_mul1_inverse_vector$U.lo hgcd_matrix$U.lo hgcd2$U.lo hgcd_step$U.lo hgcd_reduce$U.lo hgcd$U.lo hgcd_appr$U.lo hgcd2_jacobi$U.lo hgcd_jacobi$U.lo mullo_n$U.lo mullo_basecase$U.lo sqrlo$U.lo sqrlo_basecase$U.lo toom22_mul$U.lo toom32_mul$U.lo toom42_mul$U.lo toom52_mul$U.lo toom62_mul$U.lo toom33_mul$U.lo toom43_mul$U.lo toom53_mul$U.lo toom54_mul$U.lo toom63_mul$U.lo toom44_mul$U.lo toom6h_mul$U.lo toom6_sqr$U.lo toom8h_mul$U.lo toom8_sqr$U.lo toom_couple_handling$U.lo toom2_sqr$U.lo toom3_sqr$U.lo toom4_sqr$U.lo toom_eval_dgr3_pm1$U.lo toom_eval_dgr3_pm2$U.lo toom_eval_pm1$U.lo toom_eval_pm2$U.lo toom_eval_pm2exp$U.lo toom_eval_pm2rexp$U.lo toom_interpolate_5pts$U.lo toom_interpolate_6pts$U.lo toom_interpolate_7pts$U.lo toom_interpolate_8pts$U.lo toom_interpolate_12pts$U.lo toom_interpolate_16pts$U.lo invertappr$U.lo invert$U.lo binvert$U.lo mulmod_bnm1$U.lo sqrmod_bnm1$U.lo mulmod_bknp1$U.lo div_qr_1$U.lo div_qr_1n_pi1$U.lo div_qr_2$U.lo div_qr_2n_pi1$U.lo div_qr_2u_pi1$U.lo sbpi1_div_q$U.lo sbpi1_div_qr$U.lo sbpi1_divappr_q$U.lo dcpi1_div_q$U.lo dcpi1_div_qr$U.lo dcpi1_divappr_q$U.lo mu_div_qr$U.lo mu_divappr_q$U.lo mu_div_q$U.lo bdiv_q_1.lo sbpi1_bdiv_q$U.lo sbpi1_bdiv_qr$U.lo sbpi1_bdiv_r$U.lo dcpi1_bdiv_q$U.lo dcpi1_bdiv_qr$U.lo mu_bdiv_q$U.lo mu_bdiv_qr$U.lo bdiv_q$U.lo bdiv_qr$U.lo broot$U.lo brootinv$U.lo bsqrt$U.lo bsqrtinv$U.lo divexact$U.lo bdiv_dbm1c.lo redc_1$U.lo redc_2$U.lo redc_n$U.lo powm$U.lo powlo$U.lo sec_powm$U.lo sec_mul$U.lo sec_sqr$U.lo sec_div_qr$U.lo sec_div_r$U.lo sec_pi1_div_qr$U.lo sec_pi1_div_r$U.lo sec_add_1$U.lo sec_sub_1$U.lo sec_invert$U.lo trialdiv$U.lo remove$U.lo and_n$U.lo andn_n$U.lo nand_n$U.lo ior_n$U.lo iorn_n$U.lo nior_n$U.lo xor_n$U.lo xnor_n$U.lo copyi.lo copyd.lo zero$U.lo sec_tabselect.lo comb_tables$U.lo umul.lo udiv.lo add_n_sub_n$U.lo +mpn_objs_in_libgmp = mpn/add$U.lo mpn/add_1$U.lo mpn/add_n.lo mpn/sub$U.lo mpn/sub_1$U.lo mpn/sub_n.lo mpn/cnd_add_n.lo mpn/cnd_sub_n.lo mpn/cnd_swap$U.lo mpn/neg$U.lo mpn/com$U.lo mpn/mul_1.lo mpn/addmul_1.lo mpn/submul_1.lo mpn/add_err1_n$U.lo mpn/add_err2_n$U.lo mpn/add_err3_n$U.lo mpn/sub_err1_n$U.lo mpn/sub_err2_n$U.lo mpn/sub_err3_n$U.lo mpn/lshift.lo mpn/rshift.lo mpn/dive_1.lo mpn/diveby3$U.lo mpn/divis$U.lo mpn/divrem$U.lo mpn/divrem_1.lo mpn/divrem_2.lo mpn/fib2_ui$U.lo mpn/fib2m$U.lo mpn/mod_1$U.lo mpn/mod_34lsub1.lo mpn/mode1o.lo mpn/pre_mod_1$U.lo mpn/dump$U.lo mpn/mod_1_1.lo mpn/mod_1_2$U.lo mpn/mod_1_3$U.lo mpn/mod_1_4.lo mpn/lshiftc$U.lo mpn/mul$U.lo mpn/mul_fft$U.lo mpn/mul_n$U.lo mpn/sqr$U.lo mpn/mul_basecase.lo mpn/sqr_basecase.lo mpn/nussbaumer_mul$U.lo mpn/mulmid_basecase$U.lo mpn/toom42_mulmid$U.lo mpn/mulmid_n$U.lo mpn/mulmid$U.lo mpn/random$U.lo mpn/random2$U.lo mpn/pow_1$U.lo mpn/rootrem$U.lo mpn/sqrtrem$U.lo mpn/sizeinbase$U.lo mpn/get_str$U.lo mpn/set_str$U.lo mpn/compute_powtab$U.lo mpn/scan0$U.lo mpn/scan1$U.lo mpn/popcount.lo mpn/hamdist.lo mpn/cmp$U.lo mpn/zero_p$U.lo mpn/perfsqr$U.lo mpn/perfpow$U.lo mpn/strongfibo$U.lo mpn/gcd_11.lo mpn/gcd_22$U.lo mpn/gcd_1$U.lo mpn/gcd$U.lo mpn/gcdext_1$U.lo mpn/gcdext$U.lo mpn/gcd_subdiv_step$U.lo mpn/gcdext_lehmer$U.lo mpn/div_q$U.lo mpn/tdiv_qr$U.lo mpn/jacbase$U.lo mpn/jacobi_2$U.lo mpn/jacobi$U.lo mpn/get_d$U.lo mpn/matrix22_mul$U.lo mpn/matrix22_mul1_inverse_vector$U.lo mpn/hgcd_matrix$U.lo mpn/hgcd2$U.lo mpn/hgcd_step$U.lo mpn/hgcd_reduce$U.lo mpn/hgcd$U.lo mpn/hgcd_appr$U.lo mpn/hgcd2_jacobi$U.lo mpn/hgcd_jacobi$U.lo mpn/mullo_n$U.lo mpn/mullo_basecase$U.lo mpn/sqrlo$U.lo mpn/sqrlo_basecase$U.lo mpn/toom22_mul$U.lo mpn/toom32_mul$U.lo mpn/toom42_mul$U.lo mpn/toom52_mul$U.lo mpn/toom62_mul$U.lo mpn/toom33_mul$U.lo mpn/toom43_mul$U.lo mpn/toom53_mul$U.lo mpn/toom54_mul$U.lo mpn/toom63_mul$U.lo mpn/toom44_mul$U.lo mpn/toom6h_mul$U.lo mpn/toom6_sqr$U.lo mpn/toom8h_mul$U.lo mpn/toom8_sqr$U.lo mpn/toom_couple_handling$U.lo mpn/toom2_sqr$U.lo mpn/toom3_sqr$U.lo mpn/toom4_sqr$U.lo mpn/toom_eval_dgr3_pm1$U.lo mpn/toom_eval_dgr3_pm2$U.lo mpn/toom_eval_pm1$U.lo mpn/toom_eval_pm2$U.lo mpn/toom_eval_pm2exp$U.lo mpn/toom_eval_pm2rexp$U.lo mpn/toom_interpolate_5pts$U.lo mpn/toom_interpolate_6pts$U.lo mpn/toom_interpolate_7pts$U.lo mpn/toom_interpolate_8pts$U.lo mpn/toom_interpolate_12pts$U.lo mpn/toom_interpolate_16pts$U.lo mpn/invertappr$U.lo mpn/invert$U.lo mpn/binvert$U.lo mpn/mulmod_bnm1$U.lo mpn/sqrmod_bnm1$U.lo mpn/mulmod_bknp1$U.lo mpn/div_qr_1$U.lo mpn/div_qr_1n_pi1$U.lo mpn/div_qr_2$U.lo mpn/div_qr_2n_pi1$U.lo mpn/div_qr_2u_pi1$U.lo mpn/sbpi1_div_q$U.lo mpn/sbpi1_div_qr$U.lo mpn/sbpi1_divappr_q$U.lo mpn/dcpi1_div_q$U.lo mpn/dcpi1_div_qr$U.lo mpn/dcpi1_divappr_q$U.lo mpn/mu_div_qr$U.lo mpn/mu_divappr_q$U.lo mpn/mu_div_q$U.lo mpn/bdiv_q_1.lo mpn/sbpi1_bdiv_q$U.lo mpn/sbpi1_bdiv_qr$U.lo mpn/sbpi1_bdiv_r$U.lo mpn/dcpi1_bdiv_q$U.lo mpn/dcpi1_bdiv_qr$U.lo mpn/mu_bdiv_q$U.lo mpn/mu_bdiv_qr$U.lo mpn/bdiv_q$U.lo mpn/bdiv_qr$U.lo mpn/broot$U.lo mpn/brootinv$U.lo mpn/bsqrt$U.lo mpn/bsqrtinv$U.lo mpn/divexact$U.lo mpn/bdiv_dbm1c.lo mpn/redc_1$U.lo mpn/redc_2$U.lo mpn/redc_n$U.lo mpn/powm$U.lo mpn/powlo$U.lo mpn/sec_powm$U.lo mpn/sec_mul$U.lo mpn/sec_sqr$U.lo mpn/sec_div_qr$U.lo mpn/sec_div_r$U.lo mpn/sec_pi1_div_qr$U.lo mpn/sec_pi1_div_r$U.lo mpn/sec_add_1$U.lo mpn/sec_sub_1$U.lo mpn/sec_invert$U.lo mpn/trialdiv$U.lo mpn/remove$U.lo mpn/and_n$U.lo mpn/andn_n$U.lo mpn/nand_n$U.lo mpn/ior_n$U.lo mpn/iorn_n$U.lo mpn/nior_n$U.lo mpn/xor_n$U.lo mpn/xnor_n$U.lo mpn/copyi.lo mpn/copyd.lo mpn/zero$U.lo mpn/sec_tabselect.lo mpn/comb_tables$U.lo mpn/umul.lo mpn/udiv.lo mpn/add_n_sub_n$U.lo +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /home/dnw/Code/ERA-calc/c-src/gmp-6.3.0/bin +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../ +top_builddir = .. +top_srcdir = .. +AM_CPPFLAGS = -D__GMP_WITHIN_GMP -I$(top_srcdir) +noinst_LTLIBRARIES = libmpz.la +libmpz_la_SOURCES = aors.h aors_ui.h fits_s.h mul_i.h \ + 2fac_ui.c \ + add.c add_ui.c abs.c aorsmul.c aorsmul_i.c and.c array_init.c \ + bin_ui.c bin_uiui.c cdiv_q.c \ + cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \ + cfdiv_q_2exp.c cfdiv_r_2exp.c \ + clear.c clears.c clrbit.c \ + cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c \ + com.c combit.c \ + cong.c cong_2exp.c cong_ui.c \ + divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c \ + dump.c export.c fac_ui.c fdiv_q.c fdiv_q_ui.c \ + fdiv_qr.c fdiv_qr_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c \ + fib_ui.c fib2_ui.c \ + fits_sint.c fits_slong.c fits_sshort.c \ + fits_uint.c fits_ulong.c fits_ushort.c \ + gcd.c gcd_ui.c gcdext.c get_d.c get_d_2exp.c get_si.c \ + get_str.c get_ui.c getlimbn.c hamdist.c \ + import.c init.c init2.c inits.c inp_raw.c inp_str.c \ + invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c \ + jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \ + lcm.c lcm_ui.c limbs_read.c limbs_write.c limbs_modify.c limbs_finish.c \ + lucnum_ui.c lucnum2_ui.c lucmod.c mfac_uiui.c millerrabin.c \ + mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \ + oddfac_1.c \ + out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \ + powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \ + realloc.c realloc2.c remove.c roinit_n.c root.c rootrem.c rrandomb.c \ + scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \ + set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c stronglucas.c \ + sub.c sub_ui.c \ + swap.c tdiv_ui.c tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c tdiv_qr.c \ + tdiv_qr_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tstbit.c ui_pow_ui.c \ + ui_sub.c urandomb.c urandomm.c xor.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps mpz/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu --ignore-deps mpz/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: # $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): # $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libmpz.la: $(libmpz_la_OBJECTS) $(libmpz_la_DEPENDENCIES) $(EXTRA_libmpz_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libmpz_la_OBJECTS) $(libmpz_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gmp-6.3.0/mpz/Makefile.am b/gmp-6.3.0/mpz/Makefile.am new file mode 100644 index 0000000..a5e1f57 --- /dev/null +++ b/gmp-6.3.0/mpz/Makefile.am @@ -0,0 +1,68 @@ +## Process this file with automake to generate Makefile.in + +# Copyright 1996, 1998-2003, 2012 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library. +# +# The GNU MP Library is free software; you can redistribute it and/or modify +# it under the terms of either: +# +# * the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# or +# +# * the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# or both in parallel, as here. +# +# The GNU MP Library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received copies of the GNU General Public License and the +# GNU Lesser General Public License along with the GNU MP Library. If not, +# see https://www.gnu.org/licenses/. + + +AM_CPPFLAGS = -D__GMP_WITHIN_GMP -I$(top_srcdir) + +noinst_LTLIBRARIES = libmpz.la +libmpz_la_SOURCES = aors.h aors_ui.h fits_s.h mul_i.h \ + 2fac_ui.c \ + add.c add_ui.c abs.c aorsmul.c aorsmul_i.c and.c array_init.c \ + bin_ui.c bin_uiui.c cdiv_q.c \ + cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \ + cfdiv_q_2exp.c cfdiv_r_2exp.c \ + clear.c clears.c clrbit.c \ + cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c \ + com.c combit.c \ + cong.c cong_2exp.c cong_ui.c \ + divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c \ + dump.c export.c fac_ui.c fdiv_q.c fdiv_q_ui.c \ + fdiv_qr.c fdiv_qr_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c \ + fib_ui.c fib2_ui.c \ + fits_sint.c fits_slong.c fits_sshort.c \ + fits_uint.c fits_ulong.c fits_ushort.c \ + gcd.c gcd_ui.c gcdext.c get_d.c get_d_2exp.c get_si.c \ + get_str.c get_ui.c getlimbn.c hamdist.c \ + import.c init.c init2.c inits.c inp_raw.c inp_str.c \ + invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c \ + jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \ + lcm.c lcm_ui.c limbs_read.c limbs_write.c limbs_modify.c limbs_finish.c \ + lucnum_ui.c lucnum2_ui.c lucmod.c mfac_uiui.c millerrabin.c \ + mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \ + oddfac_1.c \ + out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \ + powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \ + realloc.c realloc2.c remove.c roinit_n.c root.c rootrem.c rrandomb.c \ + scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \ + set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c stronglucas.c \ + sub.c sub_ui.c \ + swap.c tdiv_ui.c tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c tdiv_qr.c \ + tdiv_qr_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tstbit.c ui_pow_ui.c \ + ui_sub.c urandomb.c urandomm.c xor.c diff --git a/gmp-6.3.0/mpz/Makefile.in b/gmp-6.3.0/mpz/Makefile.in new file mode 100644 index 0000000..6fd9c60 --- /dev/null +++ b/gmp-6.3.0/mpz/Makefile.in @@ -0,0 +1,702 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright 1996, 1998-2003, 2012 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library. +# +# The GNU MP Library is free software; you can redistribute it and/or modify +# it under the terms of either: +# +# * the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# or +# +# * the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# or both in parallel, as here. +# +# The GNU MP Library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received copies of the GNU General Public License and the +# GNU Lesser General Public License along with the GNU MP Library. If not, +# see https://www.gnu.org/licenses/. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = mpz +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libmpz_la_LIBADD = +am_libmpz_la_OBJECTS = 2fac_ui.lo add.lo add_ui.lo abs.lo aorsmul.lo \ + aorsmul_i.lo and.lo array_init.lo bin_ui.lo bin_uiui.lo \ + cdiv_q.lo cdiv_q_ui.lo cdiv_qr.lo cdiv_qr_ui.lo cdiv_r.lo \ + cdiv_r_ui.lo cdiv_ui.lo cfdiv_q_2exp.lo cfdiv_r_2exp.lo \ + clear.lo clears.lo clrbit.lo cmp.lo cmp_d.lo cmp_si.lo \ + cmp_ui.lo cmpabs.lo cmpabs_d.lo cmpabs_ui.lo com.lo combit.lo \ + cong.lo cong_2exp.lo cong_ui.lo divexact.lo divegcd.lo \ + dive_ui.lo divis.lo divis_ui.lo divis_2exp.lo dump.lo \ + export.lo fac_ui.lo fdiv_q.lo fdiv_q_ui.lo fdiv_qr.lo \ + fdiv_qr_ui.lo fdiv_r.lo fdiv_r_ui.lo fdiv_ui.lo fib_ui.lo \ + fib2_ui.lo fits_sint.lo fits_slong.lo fits_sshort.lo \ + fits_uint.lo fits_ulong.lo fits_ushort.lo gcd.lo gcd_ui.lo \ + gcdext.lo get_d.lo get_d_2exp.lo get_si.lo get_str.lo \ + get_ui.lo getlimbn.lo hamdist.lo import.lo init.lo init2.lo \ + inits.lo inp_raw.lo inp_str.lo invert.lo ior.lo iset.lo \ + iset_d.lo iset_si.lo iset_str.lo iset_ui.lo jacobi.lo \ + kronsz.lo kronuz.lo kronzs.lo kronzu.lo lcm.lo lcm_ui.lo \ + limbs_read.lo limbs_write.lo limbs_modify.lo limbs_finish.lo \ + lucnum_ui.lo lucnum2_ui.lo lucmod.lo mfac_uiui.lo \ + millerrabin.lo mod.lo mul.lo mul_2exp.lo mul_si.lo mul_ui.lo \ + n_pow_ui.lo neg.lo nextprime.lo oddfac_1.lo out_raw.lo \ + out_str.lo perfpow.lo perfsqr.lo popcount.lo pow_ui.lo powm.lo \ + powm_sec.lo powm_ui.lo pprime_p.lo prodlimbs.lo \ + primorial_ui.lo random.lo random2.lo realloc.lo realloc2.lo \ + remove.lo roinit_n.lo root.lo rootrem.lo rrandomb.lo scan0.lo \ + scan1.lo set.lo set_d.lo set_f.lo set_q.lo set_si.lo \ + set_str.lo set_ui.lo setbit.lo size.lo sizeinbase.lo sqrt.lo \ + sqrtrem.lo stronglucas.lo sub.lo sub_ui.lo swap.lo tdiv_ui.lo \ + tdiv_q.lo tdiv_q_2exp.lo tdiv_q_ui.lo tdiv_qr.lo tdiv_qr_ui.lo \ + tdiv_r.lo tdiv_r_2exp.lo tdiv_r_ui.lo tstbit.lo ui_pow_ui.lo \ + ui_sub.lo urandomb.lo urandomm.lo xor.lo +libmpz_la_OBJECTS = $(am_libmpz_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libmpz_la_SOURCES) +DIST_SOURCES = $(libmpz_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABI = @ABI@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +ASMFLAGS = @ASMFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@ +CC = @CC@ +CCAS = @CCAS@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFN_LONG_LONG_LIMB = @DEFN_LONG_LONG_LIMB@ +DEFS = @DEFS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ +FGREP = @FGREP@ +GMP_LDFLAGS = @GMP_LDFLAGS@ +GMP_LIMB_BITS = @GMP_LIMB_BITS@ +GMP_NAIL_BITS = @GMP_NAIL_BITS@ +GREP = @GREP@ +HAVE_CLOCK_01 = @HAVE_CLOCK_01@ +HAVE_CPUTIME_01 = @HAVE_CPUTIME_01@ +HAVE_GETRUSAGE_01 = @HAVE_GETRUSAGE_01@ +HAVE_GETTIMEOFDAY_01 = @HAVE_GETTIMEOFDAY_01@ +HAVE_HOST_CPU_FAMILY_power = @HAVE_HOST_CPU_FAMILY_power@ +HAVE_HOST_CPU_FAMILY_powerpc = @HAVE_HOST_CPU_FAMILY_powerpc@ +HAVE_SIGACTION_01 = @HAVE_SIGACTION_01@ +HAVE_SIGALTSTACK_01 = @HAVE_SIGALTSTACK_01@ +HAVE_SIGSTACK_01 = @HAVE_SIGSTACK_01@ +HAVE_STACK_T_01 = @HAVE_STACK_T_01@ +HAVE_SYS_RESOURCE_H_01 = @HAVE_SYS_RESOURCE_H_01@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCURSES = @LIBCURSES@ +LIBGMPXX_LDFLAGS = @LIBGMPXX_LDFLAGS@ +LIBGMP_DLL = @LIBGMP_DLL@ +LIBGMP_LDFLAGS = @LIBGMP_LDFLAGS@ +LIBM = @LIBM@ +LIBM_FOR_BUILD = @LIBM_FOR_BUILD@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4 = @M4@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPEED_CYCLECOUNTER_OBJ = @SPEED_CYCLECOUNTER_OBJ@ +STRIP = @STRIP@ +TAL_OBJECT = @TAL_OBJECT@ +TUNE_LIBS = @TUNE_LIBS@ +TUNE_SQR_OBJ = @TUNE_SQR_OBJ@ +U_FOR_BUILD = @U_FOR_BUILD@ +VERSION = @VERSION@ +WITH_READLINE_01 = @WITH_READLINE_01@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gmp_srclinks = @gmp_srclinks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +mpn_objects = @mpn_objects@ +mpn_objs_in_libgmp = @mpn_objs_in_libgmp@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -D__GMP_WITHIN_GMP -I$(top_srcdir) +noinst_LTLIBRARIES = libmpz.la +libmpz_la_SOURCES = aors.h aors_ui.h fits_s.h mul_i.h \ + 2fac_ui.c \ + add.c add_ui.c abs.c aorsmul.c aorsmul_i.c and.c array_init.c \ + bin_ui.c bin_uiui.c cdiv_q.c \ + cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \ + cfdiv_q_2exp.c cfdiv_r_2exp.c \ + clear.c clears.c clrbit.c \ + cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c \ + com.c combit.c \ + cong.c cong_2exp.c cong_ui.c \ + divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c \ + dump.c export.c fac_ui.c fdiv_q.c fdiv_q_ui.c \ + fdiv_qr.c fdiv_qr_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c \ + fib_ui.c fib2_ui.c \ + fits_sint.c fits_slong.c fits_sshort.c \ + fits_uint.c fits_ulong.c fits_ushort.c \ + gcd.c gcd_ui.c gcdext.c get_d.c get_d_2exp.c get_si.c \ + get_str.c get_ui.c getlimbn.c hamdist.c \ + import.c init.c init2.c inits.c inp_raw.c inp_str.c \ + invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c \ + jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \ + lcm.c lcm_ui.c limbs_read.c limbs_write.c limbs_modify.c limbs_finish.c \ + lucnum_ui.c lucnum2_ui.c lucmod.c mfac_uiui.c millerrabin.c \ + mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \ + oddfac_1.c \ + out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \ + powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \ + realloc.c realloc2.c remove.c roinit_n.c root.c rootrem.c rrandomb.c \ + scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \ + set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c stronglucas.c \ + sub.c sub_ui.c \ + swap.c tdiv_ui.c tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c tdiv_qr.c \ + tdiv_qr_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tstbit.c ui_pow_ui.c \ + ui_sub.c urandomb.c urandomm.c xor.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps mpz/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu --ignore-deps mpz/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libmpz.la: $(libmpz_la_OBJECTS) $(libmpz_la_DEPENDENCIES) $(EXTRA_libmpz_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libmpz_la_OBJECTS) $(libmpz_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gmp-6.3.0/mpz/abs.c b/gmp-6.3.0/mpz/abs.c new file mode 100644 index 0000000..0cfbc49 --- /dev/null +++ b/gmp-6.3.0/mpz/abs.c @@ -0,0 +1,54 @@ +/* mpz_abs(dst, src) -- Assign the absolute value of SRC to DST. + +Copyright 1991, 1993-1995, 2001, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_abs 1 + +#include "gmp-impl.h" + +void +mpz_abs (mpz_ptr w, mpz_srcptr u) +{ + mp_ptr wp; + mp_srcptr up; + mp_size_t size; + + size = ABSIZ (u); + + if (u != w) + { + wp = MPZ_NEWALLOC (w, size); + + up = PTR (u); + + MPN_COPY (wp, up, size); + } + + SIZ (w) = size; +} diff --git a/gmp-6.3.0/mpz/add.c b/gmp-6.3.0/mpz/add.c new file mode 100644 index 0000000..f1f0ae8 --- /dev/null +++ b/gmp-6.3.0/mpz/add.c @@ -0,0 +1,33 @@ +/* mpz_add -- add integers. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_add +#include "aors.h" diff --git a/gmp-6.3.0/mpz/add_ui.c b/gmp-6.3.0/mpz/add_ui.c new file mode 100644 index 0000000..8fd15ad --- /dev/null +++ b/gmp-6.3.0/mpz/add_ui.c @@ -0,0 +1,33 @@ +/* mpz_add_ui -- Add an mpz_t and an unsigned one-word integer. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_add_ui +#include "aors_ui.h" diff --git a/gmp-6.3.0/mpz/and.c b/gmp-6.3.0/mpz/and.c new file mode 100644 index 0000000..5d34547 --- /dev/null +++ b/gmp-6.3.0/mpz/and.c @@ -0,0 +1,222 @@ +/* mpz_and -- Logical and. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2003, 2005, 2012, +2015-2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_and (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) +{ + mp_srcptr op1_ptr, op2_ptr; + mp_size_t op1_size, op2_size; + mp_ptr res_ptr; + mp_size_t res_size; + mp_size_t i; + + op1_size = SIZ(op1); + op2_size = SIZ(op2); + + if (op1_size < op2_size) + { + MPZ_SRCPTR_SWAP (op1, op2); + MP_SIZE_T_SWAP (op1_size, op2_size); + } + + op1_ptr = PTR(op1); + op2_ptr = PTR(op2); + + if (op2_size >= 0) + { + /* First loop finds the size of the result. */ + for (i = op2_size; --i >= 0;) + if ((op1_ptr[i] & op2_ptr[i]) != 0) + { + res_size = i + 1; + /* Handle allocation, now then we know exactly how much space is + needed for the result. */ + /* Don't re-read op1_ptr and op2_ptr. Since res_size <= + MIN(op1_size, op2_size), res is not changed when op1 + is identical to res or op2 is identical to res. */ + SIZ (res) = res_size; + mpn_and_n (MPZ_NEWALLOC (res, res_size), op1_ptr, op2_ptr, res_size); + return; + } + + SIZ (res) = 0; + } + else + { + TMP_DECL; + + op2_size = -op2_size; + TMP_MARK; + if (op1_size < 0) + { + mp_ptr opx, opy; + + /* Both operands are negative, so will be the result. + -((-OP1) & (-OP2)) = -(~(OP1 - 1) & ~(OP2 - 1)) = + = ~(~(OP1 - 1) & ~(OP2 - 1)) + 1 = + = ((OP1 - 1) | (OP2 - 1)) + 1 */ + + /* It might seem as we could end up with an (invalid) result with + a leading zero-limb here when one of the operands is of the + type 1,,0,,..,,.0. But some analysis shows that we surely + would get carry into the zero-limb in this situation... */ + + op1_size = -op1_size; + + TMP_ALLOC_LIMBS_2 (opx, op1_size, opy, op2_size); + mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1); + op1_ptr = opx; + + mpn_sub_1 (opy, op2_ptr, op2_size, (mp_limb_t) 1); + op2_ptr = opy; + + res_ptr = MPZ_NEWALLOC (res, 1 + op2_size); + /* Don't re-read OP1_PTR and OP2_PTR. They point to temporary + space--never to the space PTR(res) used to point to before + reallocation. */ + + MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, + op2_size - op1_size); + mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op1_size); + TMP_FREE; + res_size = op2_size; + + res_ptr[res_size] = 0; + MPN_INCR_U (res_ptr, res_size + 1, (mp_limb_t) 1); + res_size += res_ptr[res_size]; + + SIZ(res) = -res_size; + } + else + { +#if ANDNEW + mp_size_t op2_lim; + mp_size_t count; + + /* OP2 must be negated as with infinite precision. + + Scan from the low end for a non-zero limb. The first non-zero + limb is simply negated (two's complement). Any subsequent + limbs are one's complemented. Of course, we don't need to + handle more limbs than there are limbs in the other, positive + operand as the result for those limbs is going to become zero + anyway. */ + + /* Scan for the least significant non-zero OP2 limb, and zero the + result meanwhile for those limb positions. (We will surely + find a non-zero limb, so we can write the loop with one + termination condition only.) */ + for (i = 0; op2_ptr[i] == 0; i++) + res_ptr[i] = 0; + op2_lim = i; + + if (op1_size <= op2_size) + { + /* The ones-extended OP2 is >= than the zero-extended OP1. + RES_SIZE <= OP1_SIZE. Find the exact size. */ + for (i = op1_size - 1; i > op2_lim; i--) + if ((op1_ptr[i] & ~op2_ptr[i]) != 0) + break; + res_size = i + 1; + for (i = res_size - 1; i > op2_lim; i--) + res_ptr[i] = op1_ptr[i] & ~op2_ptr[i]; + res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim]; + /* Yes, this *can* happen! */ + MPN_NORMALIZE (res_ptr, res_size); + } + else + { + /* The ones-extended OP2 is < than the zero-extended OP1. + RES_SIZE == OP1_SIZE, since OP1 is normalized. */ + res_size = op1_size; + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size); + for (i = op2_size - 1; i > op2_lim; i--) + res_ptr[i] = op1_ptr[i] & ~op2_ptr[i]; + res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim]; + } +#else + + /* OP1 is positive and zero-extended, + OP2 is negative and ones-extended. + The result will be positive. + OP1 & -OP2 = OP1 & ~(OP2 - 1). */ + + mp_ptr opx; + + opx = TMP_ALLOC_LIMBS (op2_size); + mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1); + op2_ptr = opx; + + if (op1_size > op2_size) + { + /* The result has the same size as OP1, since OP1 is normalized + and longer than the ones-extended OP2. */ + res_size = op1_size; + + /* Handle allocation, now then we know exactly how much space is + needed for the result. */ + res_ptr = MPZ_NEWALLOC (res, res_size); + /* Don't re-read OP1_PTR or OP2_PTR. Since res_size = op1_size, + op1 is not changed if it is identical to res. + OP2_PTR points to temporary space. */ + + mpn_andn_n (res_ptr, op1_ptr, op2_ptr, op2_size); + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, res_size - op2_size); + } + else + { + /* Find out the exact result size. Ignore the high limbs of OP2, + OP1 is zero-extended and would make the result zero. */ + res_size = 0; + for (i = op1_size; --i >= 0;) + if ((op1_ptr[i] & ~op2_ptr[i]) != 0) + { + res_size = i + 1; + /* Handle allocation, now then we know exactly how much + space is needed for the result. */ + /* Don't re-read OP1_PTR. Since res_size <= op1_size, + op1 is not changed if it is identical to res. Don't + re-read OP2_PTR. It points to temporary space--never + to the space PTR(res) used to point to before + reallocation. */ + mpn_andn_n (MPZ_NEWALLOC (res, res_size), op1_ptr, op2_ptr, res_size); + + break; + } + } +#endif + SIZ(res) = res_size; + TMP_FREE; + } + } +} diff --git a/gmp-6.3.0/mpz/aors.h b/gmp-6.3.0/mpz/aors.h new file mode 100644 index 0000000..782a5fe --- /dev/null +++ b/gmp-6.3.0/mpz/aors.h @@ -0,0 +1,129 @@ +/* mpz_add, mpz_sub -- add or subtract integers. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2011, 2012, 2020 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +#ifdef OPERATION_add +#define FUNCTION mpz_add +#define VARIATION +#endif +#ifdef OPERATION_sub +#define FUNCTION mpz_sub +#define VARIATION - +#endif + +#ifndef FUNCTION +Error, need OPERATION_add or OPERATION_sub +#endif + + +void +FUNCTION (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) +{ + mp_srcptr up, vp; + mp_ptr wp; + mp_size_t usize, vsize, wsize; + mp_size_t abs_usize; + mp_size_t abs_vsize; + + usize = SIZ(u); + vsize = VARIATION SIZ(v); + abs_usize = ABS (usize); + abs_vsize = ABS (vsize); + + if (abs_usize < abs_vsize) + { + /* Swap U and V. */ + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (usize, vsize); + MP_SIZE_T_SWAP (abs_usize, abs_vsize); + } + + /* True: ABS_USIZE >= ABS_VSIZE. */ + + /* If not space for w (and possible carry), increase space. */ + wsize = abs_usize + 1; + wp = MPZ_REALLOC (w, wsize); + + /* These must be after realloc (u or v may be the same as w). */ + up = PTR(u); + vp = PTR(v); + + if ((usize ^ vsize) < 0) + { + /* U and V have different sign. Need to compare them to determine + which operand to subtract from which. */ + + /* This test is right since ABS_USIZE >= ABS_VSIZE. */ + if (abs_usize != abs_vsize) + { + mpn_sub (wp, up, abs_usize, vp, abs_vsize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize < 0) + wsize = -wsize; + } + else + { + int cmp = mpn_cmp (up, vp, abs_usize); + if (cmp < 0) + { + mpn_sub_n (wp, vp, up, abs_usize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize >= 0) + wsize = -wsize; + } + else if (cmp > 0) + { + mpn_sub_n (wp, up, vp, abs_usize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize < 0) + wsize = -wsize; + } + else + wsize = 0; + } + } + else + { + /* U and V have same sign. Add them. */ + mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize); + wp[abs_usize] = cy_limb; + wsize = abs_usize + cy_limb; + if (usize < 0) + wsize = -wsize; + } + + SIZ(w) = wsize; +} diff --git a/gmp-6.3.0/mpz/aors_ui.h b/gmp-6.3.0/mpz/aors_ui.h new file mode 100644 index 0000000..cbc467b --- /dev/null +++ b/gmp-6.3.0/mpz/aors_ui.h @@ -0,0 +1,125 @@ +/* mpz_add_ui, mpz_sub_ui -- Add or subtract an mpz_t and an unsigned + one-word integer. + +Copyright 1991, 1993, 1994, 1996, 1999-2002, 2004, 2012, 2013, 2015, +2020 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +#ifdef OPERATION_add_ui +#define FUNCTION mpz_add_ui +#define FUNCTION2 mpz_add +#define VARIATION_CMP >= +#define VARIATION_NEG +#define VARIATION_UNNEG - +#endif + +#ifdef OPERATION_sub_ui +#define FUNCTION mpz_sub_ui +#define FUNCTION2 mpz_sub +#define VARIATION_CMP < +#define VARIATION_NEG - +#define VARIATION_UNNEG +#endif + +#ifndef FUNCTION +Error, need OPERATION_add_ui or OPERATION_sub_ui +#endif + + +void +FUNCTION (mpz_ptr w, mpz_srcptr u, unsigned long int vval) +{ + mp_srcptr up; + mp_ptr wp; + mp_size_t usize, wsize; + mp_size_t abs_usize; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (vval > GMP_NUMB_MAX) + { + mpz_t v; + mp_limb_t vl[2]; + PTR(v) = vl; + vl[0] = vval & GMP_NUMB_MASK; + vl[1] = vval >> GMP_NUMB_BITS; + SIZ(v) = 2; + FUNCTION2 (w, u, v); + return; + } +#endif + + usize = SIZ (u); + if (usize == 0) + { + MPZ_NEWALLOC (w, 1)[0] = vval; + SIZ (w) = VARIATION_NEG (vval != 0); + return; + } + + abs_usize = ABS (usize); + + if (usize VARIATION_CMP 0) + { + mp_limb_t cy; + + /* If not space for W (and possible carry), increase space. */ + wp = MPZ_REALLOC (w, abs_usize + 1); + /* These must be after realloc (U may be the same as W). */ + up = PTR (u); + + cy = mpn_add_1 (wp, up, abs_usize, (mp_limb_t) vval); + wp[abs_usize] = cy; + wsize = VARIATION_NEG (abs_usize + cy); + } + else + { + /* If not space for W, increase space. */ + wp = MPZ_REALLOC (w, abs_usize); + /* These must be after realloc (U may be the same as W). */ + up = PTR (u); + + /* The signs are different. Need exact comparison to determine + which operand to subtract from which. */ + if (abs_usize == 1 && up[0] < vval) + { + wp[0] = vval - up[0]; + wsize = VARIATION_NEG 1; + } + else + { + mpn_sub_1 (wp, up, abs_usize, (mp_limb_t) vval); + /* Size can decrease with at most one limb. */ + wsize = VARIATION_UNNEG (abs_usize - (wp[abs_usize - 1] == 0)); + } + } + + SIZ (w) = wsize; +} diff --git a/gmp-6.3.0/mpz/aorsmul.c b/gmp-6.3.0/mpz/aorsmul.c new file mode 100644 index 0000000..ba766f6 --- /dev/null +++ b/gmp-6.3.0/mpz/aorsmul.c @@ -0,0 +1,179 @@ +/* mpz_addmul, mpz_submul -- add or subtract multiple. + +Copyright 2001, 2004, 2005, 2012, 2022 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +/* expecting x and y both with non-zero high limbs */ +#define mpn_cmp_twosizes_lt(xp,xsize, yp,ysize) \ + ((xsize) < (ysize) \ + || ((xsize) == (ysize) && mpn_cmp (xp, yp, xsize) < 0)) + + +/* sub>=0 means an addmul w += x*y, sub<0 means a submul w -= x*y. + + The signs of w, x and y are fully accounted for by each flipping "sub". + + The sign of w is retained for the result, unless the absolute value + submul underflows, in which case it flips. */ + +static void __gmpz_aorsmul (REGPARM_3_1 (mpz_ptr w, mpz_srcptr x, mpz_srcptr y, mp_size_t sub)) REGPARM_ATTR (1); +#define mpz_aorsmul(w,x,y,sub) __gmpz_aorsmul (REGPARM_3_1 (w, x, y, sub)) + +REGPARM_ATTR (1) static void +mpz_aorsmul (mpz_ptr w, mpz_srcptr x, mpz_srcptr y, mp_size_t sub) +{ + mp_size_t xsize, ysize, tsize, wsize, wsize_signed; + mp_ptr wp, tp; + mp_limb_t c; + TMP_DECL; + + /* w unaffected if x==0 or y==0 */ + xsize = SIZ(x); + ysize = SIZ(y); + if (xsize == 0 || ysize == 0) + return; + + /* make x the bigger of the two */ + if (ABS(ysize) > ABS(xsize)) + { + MPZ_SRCPTR_SWAP (x, y); + MP_SIZE_T_SWAP (xsize, ysize); + } + + sub ^= ysize; + ysize = ABS(ysize); + + /* use mpn_addmul_1/mpn_submul_1 if possible */ + if (ysize == 1) + { + mpz_aorsmul_1 (w, x, PTR(y)[0], sub); + return; + } + + sub ^= xsize; + xsize = ABS(xsize); + + wsize_signed = SIZ(w); + sub ^= wsize_signed; + wsize = ABS(wsize_signed); + + tsize = xsize + ysize; + wp = MPZ_REALLOC (w, MAX (wsize, tsize) + 1); + + if (wsize_signed == 0) + { + mp_limb_t high; + /* Nothing to add to, just set w=x*y. No w==x or w==y overlap here, + since we know x,y!=0 but w==0. */ + if (x == y) + { + mpn_sqr (wp, PTR(x),xsize); + high = wp[tsize-1]; + } + else + high = mpn_mul (wp, PTR(x),xsize, PTR(y),ysize); + tsize -= (high == 0); + SIZ(w) = (sub >= 0 ? tsize : -tsize); + return; + } + + TMP_MARK; + tp = TMP_ALLOC_LIMBS (tsize); + + if (x == y) + { + mpn_sqr (tp, PTR(x),xsize); + tsize -= (tp[tsize-1] == 0); + } + else + { + mp_limb_t high; + high = mpn_mul (tp, PTR(x),xsize, PTR(y),ysize); + tsize -= (high == 0); + } + ASSERT (tp[tsize-1] != 0); + if (sub >= 0) + { + mp_srcptr up = wp; + mp_size_t usize = wsize; + + if (usize < tsize) + { + up = tp; + usize = tsize; + tp = wp; + tsize = wsize; + + wsize = usize; + } + + c = mpn_add (wp, up,usize, tp,tsize); + wp[wsize] = c; + wsize += (c != 0); + } + else + { + mp_srcptr up = wp; + mp_size_t usize = wsize; + + if (mpn_cmp_twosizes_lt (up,usize, tp,tsize)) + { + up = tp; + usize = tsize; + tp = wp; + tsize = wsize; + + wsize = usize; + wsize_signed = -wsize_signed; + } + + ASSERT_NOCARRY (mpn_sub (wp, up,usize, tp,tsize)); + wsize = usize; + MPN_NORMALIZE (wp, wsize); + } + + SIZ(w) = (wsize_signed >= 0 ? wsize : -wsize); + + TMP_FREE; +} + + +void +mpz_addmul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) +{ + mpz_aorsmul (w, u, v, (mp_size_t) 0); +} + +void +mpz_submul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) +{ + mpz_aorsmul (w, u, v, (mp_size_t) -1); +} diff --git a/gmp-6.3.0/mpz/aorsmul_i.c b/gmp-6.3.0/mpz/aorsmul_i.c new file mode 100644 index 0000000..317be3e --- /dev/null +++ b/gmp-6.3.0/mpz/aorsmul_i.c @@ -0,0 +1,254 @@ +/* mpz_addmul_ui, mpz_submul_ui - add or subtract small multiple. + + THE mpz_aorsmul_1 FUNCTION IN THIS FILE IS FOR INTERNAL USE ONLY AND IS + ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR + COMPLETELY IN FUTURE GNU MP RELEASES. + +Copyright 2001, 2002, 2004, 2005, 2012, 2021, 2022 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +#if HAVE_NATIVE_mpn_mul_1c +#define MPN_MUL_1C(cout, dst, src, size, n, cin) \ + do { \ + (cout) = mpn_mul_1c (dst, src, size, n, cin); \ + } while (0) +#else +#define MPN_MUL_1C(cout, dst, src, size, n, cin) \ + do { \ + mp_limb_t __cy; \ + __cy = mpn_mul_1 (dst, src, size, n); \ + (cout) = __cy + mpn_add_1 (dst, dst, size, cin); \ + } while (0) +#endif + + +/* sub>=0 means an addmul w += x*y, sub<0 means a submul w -= x*y. + + All that's needed to account for negative w or x is to flip "sub". + + The final w will retain its sign, unless an underflow occurs in a submul + of absolute values, in which case it's flipped. + + If x has more limbs than w, then mpn_submul_1 followed by mpn_com is + used. The alternative would be mpn_mul_1 into temporary space followed + by mpn_sub_n. Avoiding temporary space seem good, and submul+com stands + a chance of being faster since it involves only one set of carry + propagations, not two. Note that doing an addmul_1 with a + twos-complement negative y doesn't work, because it effectively adds an + extra x * 2^GMP_LIMB_BITS. */ + +REGPARM_ATTR(1) void +mpz_aorsmul_1 (mpz_ptr w, mpz_srcptr x, mp_limb_t y, mp_size_t sub) +{ + mp_size_t xsize, wsize, wsize_signed, new_wsize, min_size, dsize; + mp_srcptr xp; + mp_ptr wp; + mp_limb_t cy; + + /* w unaffected if x==0 or y==0 */ + xsize = SIZ (x); + if (xsize == 0 || y == 0) + return; + + sub ^= xsize; + xsize = ABS (xsize); + + wsize_signed = SIZ (w); + if (wsize_signed == 0) + { + /* nothing to add to, just set x*y, "sub" gives the sign */ + wp = MPZ_NEWALLOC (w, xsize+1); + cy = mpn_mul_1 (wp, PTR(x), xsize, y); + wp[xsize] = cy; + xsize += (cy != 0); + SIZ (w) = (sub >= 0 ? xsize : -xsize); + return; + } + + sub ^= wsize_signed; + wsize = ABS (wsize_signed); + + new_wsize = MAX (wsize, xsize); + wp = MPZ_REALLOC (w, new_wsize+1); + xp = PTR (x); + min_size = MIN (wsize, xsize); + + if (sub >= 0) + { + /* addmul of absolute values */ + + cy = mpn_addmul_1 (wp, xp, min_size, y); + wp += min_size; + xp += min_size; + + dsize = xsize - wsize; +#if HAVE_NATIVE_mpn_mul_1c + if (dsize > 0) + cy = mpn_mul_1c (wp, xp, dsize, y, cy); + else if (dsize < 0) + { + dsize = -dsize; + cy = mpn_add_1 (wp, wp, dsize, cy); + } +#else + if (dsize != 0) + { + mp_limb_t cy2; + if (dsize > 0) + cy2 = mpn_mul_1 (wp, xp, dsize, y); + else + { + dsize = -dsize; + cy2 = 0; + } + cy = cy2 + mpn_add_1 (wp, wp, dsize, cy); + } +#endif + + wp[dsize] = cy; + new_wsize += (cy != 0); + } + else + { + /* submul of absolute values */ + + cy = mpn_submul_1 (wp, xp, min_size, y); + if (wsize >= xsize) + { + /* if w bigger than x, then propagate borrow through it */ + if (wsize != xsize) + cy = mpn_sub_1 (wp+xsize, wp+xsize, wsize-xsize, cy); + + if (cy != 0) + { + /* Borrow out of w, take twos complement negative to get + absolute value, flip sign of w. */ + cy -= mpn_neg (wp, wp, new_wsize); + wp[new_wsize] = cy; + new_wsize += (cy != 0); + wsize_signed = -wsize_signed; + } + } + else /* wsize < xsize */ + { + /* x bigger than w, so want x*y-w. Submul has given w-x*y, so + take twos complement and use an mpn_mul_1 for the rest. */ + + mp_limb_t cy2; + + /* -(-cy*b^n + w-x*y) = (cy-1)*b^n + ~(w-x*y) + 1 */ + cy -= mpn_neg (wp, wp, wsize); + + /* If cy-1 == -1 then hold that -1 for latter. mpn_submul_1 never + returns cy==MP_LIMB_T_MAX so that value always indicates a -1. */ + cy2 = (cy == MP_LIMB_T_MAX); + cy += cy2; + MPN_MUL_1C (cy, wp+wsize, xp+wsize, xsize-wsize, y, cy); + wp[new_wsize] = cy; + new_wsize += (cy != 0); + + /* Apply any -1 from above. The value at wp+wsize is non-zero + because y!=0 and the high limb of x will be non-zero. */ + if (cy2) + MPN_DECR_U (wp+wsize, new_wsize-wsize, CNST_LIMB(1)); + + wsize_signed = -wsize_signed; + } + + /* submul can produce high zero limbs due to cancellation, both when w + has more limbs or x has more */ + MPN_NORMALIZE (wp, new_wsize); + } + + SIZ (w) = (wsize_signed >= 0 ? new_wsize : -new_wsize); + + ASSERT (new_wsize == 0 || PTR(w)[new_wsize-1] != 0); +} + + +void +mpz_addmul_ui (mpz_ptr w, mpz_srcptr x, unsigned long y) +{ +#if BITS_PER_ULONG > GMP_NUMB_BITS + if (UNLIKELY (y > GMP_NUMB_MAX)) + { + mpz_t t; + mp_ptr tp; + mp_size_t xn; + TMP_DECL; + TMP_MARK; + xn = SIZ (x); + if (xn == 0) return; + MPZ_TMP_INIT (t, ABS (xn) + 1); + tp = PTR (t); + tp[0] = 0; + MPN_COPY (tp + 1, PTR(x), ABS (xn)); + SIZ(t) = xn >= 0 ? xn + 1 : xn - 1; + mpz_aorsmul_1 (w, t, (mp_limb_t) y >> GMP_NUMB_BITS, (mp_size_t) 0); + PTR(t) = tp + 1; + SIZ(t) = xn; + mpz_aorsmul_1 (w, t, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) 0); + TMP_FREE; + return; + } +#endif + mpz_aorsmul_1 (w, x, (mp_limb_t) y, (mp_size_t) 0); +} + +void +mpz_submul_ui (mpz_ptr w, mpz_srcptr x, unsigned long y) +{ +#if BITS_PER_ULONG > GMP_NUMB_BITS + if (y > GMP_NUMB_MAX) + { + mpz_t t; + mp_ptr tp; + mp_size_t xn; + TMP_DECL; + TMP_MARK; + xn = SIZ (x); + if (xn == 0) return; + MPZ_TMP_INIT (t, ABS (xn) + 1); + tp = PTR (t); + tp[0] = 0; + MPN_COPY (tp + 1, PTR(x), ABS (xn)); + SIZ(t) = xn >= 0 ? xn + 1 : xn - 1; + mpz_aorsmul_1 (w, t, (mp_limb_t) y >> GMP_NUMB_BITS, (mp_size_t) -1); + PTR(t) = tp + 1; + SIZ(t) = xn; + mpz_aorsmul_1 (w, t, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) -1); + TMP_FREE; + return; + } +#endif + mpz_aorsmul_1 (w, x, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) -1); +} diff --git a/gmp-6.3.0/mpz/array_init.c b/gmp-6.3.0/mpz/array_init.c new file mode 100644 index 0000000..df97f34 --- /dev/null +++ b/gmp-6.3.0/mpz/array_init.c @@ -0,0 +1,49 @@ +/* mpz_array_init (array, array_size, size_per_elem) -- + +Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_array_init (mpz_ptr arr, mp_size_t arr_size, mp_size_t nbits) +{ + mp_ptr p; + mp_size_t i; + mp_size_t nlimbs; + + nlimbs = nbits / GMP_NUMB_BITS + 1; + p = __GMP_ALLOCATE_FUNC_LIMBS (arr_size * nlimbs); + + for (i = 0; i < arr_size; i++) + { + ALLOC (&arr[i]) = nlimbs + 1; /* Yes, lie a little... */ + SIZ (&arr[i]) = 0; + PTR (&arr[i]) = p + i * nlimbs; + } +} diff --git a/gmp-6.3.0/mpz/bin_ui.c b/gmp-6.3.0/mpz/bin_ui.c new file mode 100644 index 0000000..04cd340 --- /dev/null +++ b/gmp-6.3.0/mpz/bin_ui.c @@ -0,0 +1,459 @@ +/* mpz_bin_ui(RESULT, N, K) -- Set RESULT to N over K. + +Copyright 1998-2002, 2012, 2013, 2015, 2017-2018, 2020 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +/* How many special cases? Minimum is 2: 0 and 1; + * also 3 {0,1,2} and 5 {0,1,2,3,4} are implemented. + */ +#define APARTAJ_KALKULOJ 2 + +/* Whether to use (1) or not (0) the function mpz_bin_uiui whenever + * the operands fit. + */ +#define UZU_BIN_UIUI 0 + +/* Whether to use a shortcut to precompute the product of four + * elements (1), or precompute only the product of a couple (0). + * + * In both cases the precomputed product is then updated with some + * linear operations to obtain the product of the next four (1) + * [or two (0)] operands. + */ +#define KVAROPE 1 + +static void +posmpz_init (mpz_ptr r) +{ + mp_ptr rp; + ASSERT (SIZ (r) > 0); + rp = SIZ (r) + MPZ_REALLOC (r, SIZ (r) + 2); + *rp = 0; + *++rp = 0; +} + +/* Equivalent to mpz_add_ui (r, r, in), but faster when + 0 < SIZ (r) < ALLOC (r) and limbs above SIZ (r) contain 0. */ +static void +posmpz_inc_ui (mpz_ptr r, unsigned long in) +{ +#if BITS_PER_ULONG > GMP_NUMB_BITS + mpz_add_ui (r, r, in); +#else + ASSERT (SIZ (r) > 0); + MPN_INCR_U (PTR (r), SIZ (r) + 1, in); + SIZ (r) += PTR (r)[SIZ (r)]; +#endif +} + +/* Equivalent to mpz_sub_ui (r, r, in), but faster when + 0 < SIZ (r) and we know in advance that the result is positive. */ +static void +posmpz_dec_ui (mpz_ptr r, unsigned long in) +{ +#if BITS_PER_ULONG > GMP_NUMB_BITS + mpz_sub_ui (r, r, in); +#else + ASSERT (mpz_cmp_ui (r, in) >= 0); + MPN_DECR_U (PTR (r), SIZ (r), in); + SIZ (r) -= (PTR (r)[SIZ (r)-1] == 0); +#endif +} + +/* Equivalent to mpz_tdiv_q_2exp (r, r, 1), but faster when + 0 < SIZ (r) and we know in advance that the result is positive. */ +static void +posmpz_rsh1 (mpz_ptr r) +{ + mp_ptr rp; + mp_size_t rn; + + rn = SIZ (r); + rp = PTR (r); + ASSERT (rn > 0); + mpn_rshift (rp, rp, rn, 1); + SIZ (r) -= rp[rn - 1] == 0; +} + +/* Computes r = n(n+(2*k-1))/2 + It uses a sqare instead of a product, computing + r = ((n+k-1)^2 + n - (k-1)^2)/2 + As a side effect, sets t = n+k-1 + */ +static void +mpz_hmul_nbnpk (mpz_ptr r, mpz_srcptr n, unsigned long int k, mpz_ptr t) +{ + ASSERT (k > 0 && SIZ(n) > 0); + --k; + mpz_add_ui (t, n, k); + mpz_mul (r, t, t); + mpz_add (r, r, n); + posmpz_rsh1 (r); + if (LIKELY (k <= (1UL << (BITS_PER_ULONG / 2)))) + posmpz_dec_ui (r, (k + (k & 1))*(k >> 1)); + else + { + mpz_t tmp; + mpz_init_set_ui (tmp, (k + (k & 1))); + mpz_mul_ui (tmp, tmp, k >> 1); + mpz_sub (r, r, tmp); + mpz_clear (tmp); + } +} + +#if KVAROPE +static void +rek_raising_fac4 (mpz_ptr r, mpz_ptr p, mpz_ptr P, unsigned long int k, unsigned long int lk, mpz_ptr t) +{ + if (k - lk < 5) + { + do { + posmpz_inc_ui (p, 4*k+2); + mpz_addmul_ui (P, p, 4*k); + posmpz_dec_ui (P, k); + mpz_mul (r, r, P); + } while (--k > lk); + } + else + { + mpz_t lt; + unsigned long int m; + + ALLOC (lt) = 0; + SIZ (lt) = 0; + if (t == NULL) + t = lt; + m = ((k + lk) >> 1) + 1; + rek_raising_fac4 (r, p, P, k, m, t); + + posmpz_inc_ui (p, 4*m+2); + mpz_addmul_ui (P, p, 4*m); + posmpz_dec_ui (P, m); + mpz_set (t, P); + rek_raising_fac4 (t, p, P, m - 1, lk, NULL); + + mpz_mul (r, r, t); + mpz_clear (lt); + } +} + +/* Computes (n+1)(n+2)...(n+k)/2^(k/2 +k/4) using the helper function + rek_raising_fac4, and exploiting an idea inspired by a piece of + code that Fredrik Johansson wrote and by a comment by Niels Möller. + + Assume k = 4i then compute: + p = (n+1)(n+4i)/2 - i + (n+1+1)(n+4i)/2 = p + i + (n+4i)/2 + (n+1+1)(n+4i-1)/2 = p + i + ((n+4i)-(n+1+1))/2 = p + i + (n-n+4i-2)/2 = p + 3i-1 + P = (p + i)*(p+3i-1)/2 = (n+1)(n+2)(n+4i-1)(n+4i)/8 + n' = n + 2 + i' = i - 1 + (n'-1)(n')(n'+4i'+1)(n'+4i'+2)/8 = P + (n'-1)(n'+4i'+2)/2 - i' - 1 = p + (n'-1+2)(n'+4i'+2)/2 - i' - 1 = p + (n'+4i'+2) + (n'-1+2)(n'+4i'+2-2)/2 - i' - 1 = p + (n'+4i'+2) - (n'-1+2) = p + 4i' + 1 + (n'-1+2)(n'+4i'+2-2)/2 - i' = p + 4i' + 2 + p' = p + 4i' + 2 = (n'+1)(n'+4i')/2 - i' + p' - 4i' - 2 = p + (p' - 4i' - 2 + i)*(p' - 4i' - 2+3i-1)/2 = P + (p' - 4i' - 2 + i' + 1)*(p' - 4i' - 2 + 3i' + 3 - 1)/2 = P + (p' - 3i' - 1)*(p' - i')/2 = P + (p' - 3i' - 1 + 4i' + 1)*(p' - i' + 4i' - 1)/2 = P + (4i' + 1)*(p' - i')/2 + (p' - 3i' - 1 + 4i' + 1)*(4i' - 1)/2 + (p' + i')*(p' + 3i' - 1)/2 = P + (4i')*(p' + p')/2 + (p' - i' - (p' + i'))/2 + (p' + i')*(p' + 3i' - 1)/2 = P + 4i'p' + (p' - i' - p' - i')/2 + (p' + i')*(p' + 3i' - 1)/2 = P + 4i'p' - i' + P' = P + 4i'p' - i' + + And compute the product P * P' * P" ... + */ + +static void +mpz_raising_fac4 (mpz_ptr r, mpz_ptr n, unsigned long int k, mpz_ptr t, mpz_ptr p) +{ + ASSERT ((k >= APARTAJ_KALKULOJ) && (APARTAJ_KALKULOJ > 0)); + posmpz_init (n); + posmpz_inc_ui (n, 1); + SIZ (r) = 0; + if (k & 1) + { + mpz_set (r, n); + posmpz_inc_ui (n, 1); + } + k >>= 1; + if (APARTAJ_KALKULOJ < 2 && k == 0) + return; + + mpz_hmul_nbnpk (p, n, k, t); + posmpz_init (p); + + if (k & 1) + { + if (SIZ (r)) + mpz_mul (r, r, p); + else + mpz_set (r, p); + posmpz_inc_ui (p, k - 1); + } + k >>= 1; + if (APARTAJ_KALKULOJ < 4 && k == 0) + return; + + mpz_hmul_nbnpk (t, p, k, n); + if (SIZ (r)) + mpz_mul (r, r, t); + else + mpz_set (r, t); + + if (APARTAJ_KALKULOJ > 8 || k > 1) + { + posmpz_dec_ui (p, k); + rek_raising_fac4 (r, p, t, k - 1, 0, n); + } +} + +#else /* KVAROPE */ + +static void +rek_raising_fac (mpz_ptr r, mpz_ptr n, unsigned long int k, unsigned long int lk, mpz_ptr t1, mpz_ptr t2) +{ + /* Should the threshold depend on SIZ (n) ? */ + if (k - lk < 10) + { + do { + posmpz_inc_ui (n, k); + mpz_mul (r, r, n); + --k; + } while (k > lk); + } + else + { + mpz_t t3; + unsigned long int m; + + m = ((k + lk) >> 1) + 1; + rek_raising_fac (r, n, k, m, t1, t2); + + posmpz_inc_ui (n, m); + if (t1 == NULL) + { + mpz_init_set (t3, n); + t1 = t3; + } + else + { + ALLOC (t3) = 0; + mpz_set (t1, n); + } + rek_raising_fac (t1, n, m - 1, lk, t2, NULL); + + mpz_mul (r, r, t1); + mpz_clear (t3); + } +} + +/* Computes (n+1)(n+2)...(n+k)/2^(k/2) using the helper function + rek_raising_fac, and exploiting an idea inspired by a piece of + code that Fredrik Johansson wrote. + + Force an even k = 2i then compute: + p = (n+1)(n+2i)/2 + i' = i - 1 + p == (n+1)(n+2i'+2)/2 + p' = p + i' == (n+2)(n+2i'+1)/2 + n' = n + 1 + p'== (n'+1)(n'+2i')/2 == (n+1 +1)(n+2i -1)/2 + + And compute the product p * p' * p" ... +*/ + +static void +mpz_raising_fac (mpz_ptr r, mpz_ptr n, unsigned long int k, mpz_ptr t, mpz_ptr p) +{ + unsigned long int hk; + ASSERT ((k >= APARTAJ_KALKULOJ) && (APARTAJ_KALKULOJ > 1)); + mpz_add_ui (n, n, 1); + hk = k >> 1; + mpz_hmul_nbnpk (p, n, hk, t); + + if ((k & 1) != 0) + { + mpz_add_ui (t, t, hk + 1); + mpz_mul (r, t, p); + } + else + { + mpz_set (r, p); + } + + if ((APARTAJ_KALKULOJ > 3) || (hk > 1)) + { + posmpz_init (p); + rek_raising_fac (r, p, hk - 1, 0, t, n); + } +} +#endif /* KVAROPE */ + +/* This is a poor implementation. Look at bin_uiui.c for improvement ideas. + In fact consider calling mpz_bin_uiui() when the arguments fit, leaving + the code here only for big n. + + The identity bin(n,k) = (-1)^k * bin(-n+k-1,k) can be found in Knuth vol + 1 section 1.2.6 part G. */ + +void +mpz_bin_ui (mpz_ptr r, mpz_srcptr n, unsigned long int k) +{ + mpz_t ni; + mp_size_t negate; + + if (SIZ (n) < 0) + { + /* bin(n,k) = (-1)^k * bin(-n+k-1,k), and set ni = -n+k-1 - k = -n-1 */ + mpz_init (ni); + mpz_add_ui (ni, n, 1L); + mpz_neg (ni, ni); + negate = (k & 1); /* (-1)^k */ + } + else + { + /* bin(n,k) == 0 if k>n + (no test for this under the n<0 case, since -n+k-1 >= k there) */ + if (mpz_cmp_ui (n, k) < 0) + { + SIZ (r) = 0; + return; + } + + /* set ni = n-k */ + mpz_init (ni); + mpz_sub_ui (ni, n, k); + negate = 0; + } + + /* Now wanting bin(ni+k,k), with ni positive, and "negate" is the sign (0 + for positive, 1 for negative). */ + + /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. In this case it's + whether ni+k-k < k meaning ni 2 + else if (k > 1) + { + mpz_add_ui (ni, ni, 1 + (APARTAJ_KALKULOJ > 2 && k > 2)); + mpz_mul (r, ni, ni); /* r = (n + (k>2))^2 */ + if (APARTAJ_KALKULOJ == 2 || k == 2) + { + mpz_add (r, r, ni); /* n^2+n= n(n+1) */ + posmpz_rsh1 (r); + } +#if APARTAJ_KALKULOJ > 3 +#if APARTAJ_KALKULOJ != 5 +#error Not implemented! 3 < APARTAJ_KALKULOJ != 5 +#endif + else /* k > 2 */ + { /* k = 3, 4 */ + mpz_sub_ui (r, r, 1); /* (n+1)^2-1 */ + if (k == 3) + { + mpz_mul (r, r, ni); /* ((n+1)^2-1)(n+1) = n(n+1)(n+2) */ + /* mpz_divexact_ui (r, r, 6); /\* 6=3<<1; div_by3 ? *\/ */ + } + else /* k = 4 */ + { + mpz_add (ni, ni, r); /* (n+1)^2+n */ + mpz_mul (r, ni, ni); /* ((n+1)^2+n)^2 */ + /* We should subtract one: ((n+1)^2+n)^2-1 = n(n+1)(n+2)(n+3). */ + /* PTR (r) [0] ^= 1; would suffice, but it is not even needed, */ + /* because the next division will shift away this bit anyway. */ + /* mpz_divexact_ui (r, r, 24); /\* 24=3<<3; div_by3 ? *\/ */ + } + mpn_pi1_bdiv_q_1 (PTR(r), PTR(r), SIZ(r), 3, GMP_NUMB_MASK/3*2+1, 1 | (k>>1)); + SIZ(r) -= PTR(r) [SIZ(r) - 1] == 0; + } +#endif + } +#endif + else + { /* k = 1 */ + mpz_add_ui (r, ni, 1); + } + } +#if UZU_BIN_UIUI + else if (mpz_cmp_ui (ni, ULONG_MAX - k) <= 0) + { + mpz_bin_uiui (r, mpz_get_ui (ni) + k, k); + } +#endif + else + { + mp_limb_t count; + mpz_t num, den; + + mpz_init (num); + mpz_init (den); + +#if KVAROPE + mpz_raising_fac4 (num, ni, k, den, r); + popc_limb (count, k); + ASSERT (k - (k >> 1) - (k >> 2) - count >= 0); + mpz_tdiv_q_2exp (num, num, k - (k >> 1) - (k >> 2) - count); +#else + mpz_raising_fac (num, ni, k, den, r); + popc_limb (count, k); + ASSERT (k - (k >> 1) - count >= 0); + mpz_tdiv_q_2exp (num, num, k - (k >> 1) - count); +#endif + + mpz_oddfac_1(den, k, 0); + + mpz_divexact(r, num, den); + mpz_clear (num); + mpz_clear (den); + } + mpz_clear (ni); + + SIZ(r) = (SIZ(r) ^ -negate) + negate; +} diff --git a/gmp-6.3.0/mpz/bin_uiui.c b/gmp-6.3.0/mpz/bin_uiui.c new file mode 100644 index 0000000..542d485 --- /dev/null +++ b/gmp-6.3.0/mpz/bin_uiui.c @@ -0,0 +1,707 @@ +/* mpz_bin_uiui - compute n over k. + +Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato. + +Copyright 2010-2012, 2015-2018, 2020 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +#ifndef BIN_GOETGHELUCK_THRESHOLD +#define BIN_GOETGHELUCK_THRESHOLD 512 +#endif +#ifndef BIN_UIUI_ENABLE_SMALLDC +#define BIN_UIUI_ENABLE_SMALLDC 1 +#endif +#ifndef BIN_UIUI_RECURSIVE_SMALLDC +#define BIN_UIUI_RECURSIVE_SMALLDC (GMP_NUMB_BITS > 32) +#endif + +/* Algorithm: + + Accumulate chunks of factors first limb-by-limb (using one of mul0-mul8) + which are then accumulated into mpn numbers. The first inner loop + accumulates divisor factors, the 2nd inner loop accumulates exactly the same + number of dividend factors. We avoid accumulating more for the divisor, + even with its smaller factors, since we else cannot guarantee divisibility. + + Since we know each division will yield an integer, we compute the quotient + using Hensel norm: If the quotient is limited by 2^t, we compute A / B mod + 2^t. + + Improvements: + + (1) An obvious improvement to this code would be to compute mod 2^t + everywhere. Unfortunately, we cannot determine t beforehand, unless we + invoke some approximation, such as Stirling's formula. Of course, we don't + need t to be tight. However, it is not clear that this would help much, + our numbers are kept reasonably small already. + + (2) Compute nmax/kmax semi-accurately, without scalar division or a loop. + Extracting the 3 msb, then doing a table lookup using cnt*8+msb as index, + would make it both reasonably accurate and fast. (We could use a table + stored into a limb, perhaps.) The table should take the removed factors of + 2 into account (those done on-the-fly in mulN). + + (3) The first time in the loop we compute the odd part of a + factorial in kp, we might use oddfac_1 for this task. + */ + +/* This threshold determines how large divisor to accumulate before we call + bdiv. Perhaps we should never call bdiv, and accumulate all we are told, + since we are just basecase code anyway? Presumably, this depends on the + relative speed of the asymptotically fast code and this code. */ +#define SOME_THRESHOLD 20 + +/* Multiply-into-limb functions. These remove factors of 2 on-the-fly. FIXME: + All versions of MAXFACS don't take this 2 removal into account now, meaning + that then, shifting just adds some overhead. (We remove factors from the + completed limb anyway.) */ + +static mp_limb_t +mul1 (mp_limb_t m) +{ + return m; +} + +static mp_limb_t +mul2 (mp_limb_t m) +{ + /* We need to shift before multiplying, to avoid an overflow. */ + mp_limb_t m01 = (m | 1) * ((m + 1) >> 1); + return m01; +} + +static mp_limb_t +mul3 (mp_limb_t m) +{ + mp_limb_t m01 = (m + 0) * (m + 1) >> 1; + mp_limb_t m2 = (m + 2); + return m01 * m2; +} + +static mp_limb_t +mul4 (mp_limb_t m) +{ + mp_limb_t m03 = (m + 0) * (m + 3) >> 1; + return m03 * (m03 + 1); /* mul2 (m03) ? */ +} + +static mp_limb_t +mul5 (mp_limb_t m) +{ + mp_limb_t m03 = (m + 0) * (m + 3) >> 1; + mp_limb_t m034 = m03 * (m + 4); + return (m03 + 1) * m034; +} + +static mp_limb_t +mul6 (mp_limb_t m) +{ + mp_limb_t m05 = (m + 0) * (m + 5); + mp_limb_t m1234 = (m05 + 5) * (m05 + 5) >> 3; + return m1234 * (m05 >> 1); +} + +static mp_limb_t +mul7 (mp_limb_t m) +{ + mp_limb_t m05 = (m + 0) * (m + 5); + mp_limb_t m1234 = (m05 + 5) * (m05 + 5) >> 3; + mp_limb_t m056 = m05 * (m + 6) >> 1; + return m1234 * m056; +} + +static mp_limb_t +mul8 (mp_limb_t m) +{ + mp_limb_t m07 = (m + 0) * (m + 7); + mp_limb_t m0257 = m07 * (m07 + 10) >> 3; + mp_limb_t m1346 = m07 + 9 + m0257; + return m0257 * m1346; +} + +/* +static mp_limb_t +mul9 (mp_limb_t m) +{ + return (m + 8) * mul8 (m) ; +} + +static mp_limb_t +mul10 (mp_limb_t m) +{ + mp_limb_t m09 = (m + 0) * (m + 9); + mp_limb_t m18 = (m09 >> 1) + 4; + mp_limb_t m0369 = m09 * (m09 + 18) >> 3; + mp_limb_t m2457 = m09 * 2 + 35 + m0369; + return ((m0369 * m2457) >> 1) * m18; +} +*/ + +typedef mp_limb_t (* mulfunc_t) (mp_limb_t); + +static const mulfunc_t mulfunc[] = {mul1,mul2,mul3,mul4,mul5,mul6,mul7,mul8 /* ,mul9,mul10 */}; +#define M (numberof(mulfunc)) + +/* Number of factors-of-2 removed by the corresponding mulN function. */ +static const unsigned char tcnttab[] = {0, 1, 1, 2, 2, 4, 4, 6 /*,6,8*/}; + +#if 1 +/* This variant is inaccurate but share the code with other functions. */ +#define MAXFACS(max,l) \ + do { \ + (max) = log_n_max (l); \ + } while (0) +#else + +/* This variant is exact(?) but uses a loop. It takes the 2 removal + of mulN into account. */ +static const unsigned long ftab[] = +#if GMP_NUMB_BITS == 64 + /* 1 to 8 factors per iteration */ + {CNST_LIMB(0xffffffffffffffff),CNST_LIMB(0x16a09e667),0x32cbfc,0x16a08,0x24c0,0xa11,0x345,0x1ab /*,0xe9,0x8e */}; +#endif +#if GMP_NUMB_BITS == 32 + /* 1 to 7 factors per iteration */ + {0xffffffff,0x16a09,0x7ff,0x168,0x6f,0x3d,0x20 /* ,0x17 */}; +#endif + +#define MAXFACS(max,l) \ + do { \ + int __i; \ + for (__i = numberof (ftab) - 1; l > ftab[__i]; __i--) \ + ; \ + (max) = __i + 1; \ + } while (0) +#endif + +/* Entry i contains (i!/2^t)^(-1) where t is chosen such that the parenthesis + is an odd integer. */ +static const mp_limb_t facinv[] = { ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE }; + +static void +mpz_bdiv_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k) +{ + unsigned nmax, kmax, nmaxnow, numfac; + mp_ptr np, kp; + mp_size_t nn, kn, alloc; + mp_limb_t i, j, t, iii, jjj, cy, dinv; + int cnt; + mp_size_t maxn; + TMP_DECL; + + ASSERT (k > ODD_FACTORIAL_TABLE_LIMIT); + TMP_MARK; + + maxn = 1 + n / GMP_NUMB_BITS; /* absolutely largest result size (limbs) */ + + /* FIXME: This allocation might be insufficient, but is usually way too + large. */ + alloc = SOME_THRESHOLD - 1 + MAX (3 * maxn / 2, SOME_THRESHOLD); + alloc = MIN (alloc, (mp_size_t) k) + 1; + TMP_ALLOC_LIMBS_2 (np, alloc, kp, SOME_THRESHOLD + 1); + + MAXFACS (nmax, n); + ASSERT (nmax <= M); + MAXFACS (kmax, k); + ASSERT (kmax <= M); + ASSERT (k >= M); + + i = n - k + 1; + + np[0] = 1; nn = 1; + + numfac = 1; + j = ODD_FACTORIAL_TABLE_LIMIT + 1; + jjj = ODD_FACTORIAL_TABLE_MAX; + ASSERT (__gmp_oddfac_table[ODD_FACTORIAL_TABLE_LIMIT] == ODD_FACTORIAL_TABLE_MAX); + + while (1) + { + kp[0] = jjj; /* store new factors */ + kn = 1; + t = k - j + 1; + kmax = MIN (kmax, t); + + while (kmax != 0 && kn < SOME_THRESHOLD) + { + jjj = mulfunc[kmax - 1] (j); + j += kmax; /* number of factors used */ + count_trailing_zeros (cnt, jjj); /* count low zeros */ + jjj >>= cnt; /* remove remaining low zeros */ + cy = mpn_mul_1 (kp, kp, kn, jjj); /* accumulate new factors */ + kp[kn] = cy; + kn += cy != 0; + t = k - j + 1; + kmax = MIN (kmax, t); + } + numfac = j - numfac; + + while (numfac != 0) + { + nmaxnow = MIN (nmax, numfac); + iii = mulfunc[nmaxnow - 1] (i); + i += nmaxnow; /* number of factors used */ + count_trailing_zeros (cnt, iii); /* count low zeros */ + iii >>= cnt; /* remove remaining low zeros */ + cy = mpn_mul_1 (np, np, nn, iii); /* accumulate new factors */ + np[nn] = cy; + nn += cy != 0; + numfac -= nmaxnow; + } + + ASSERT (nn < alloc); + + binvert_limb (dinv, kp[0]); + nn += (np[nn - 1] >= kp[kn - 1]); + nn -= kn; + mpn_sbpi1_bdiv_q (np, np, nn, kp, MIN(kn,nn), -dinv); + mpn_neg (np, np, nn); + + if (kmax == 0) + break; + numfac = j; + + jjj = mulfunc[kmax - 1] (j); + j += kmax; /* number of factors used */ + count_trailing_zeros (cnt, jjj); /* count low zeros */ + jjj >>= cnt; /* remove remaining low zeros */ + } + + /* Put back the right number of factors of 2. */ + popc_limb (cnt, n - k); + popc_limb (j, k); + cnt += j; + popc_limb (j, n); + cnt -= j; + if (cnt != 0) + { + ASSERT (cnt < GMP_NUMB_BITS); /* can happen, but not for intended use */ + cy = mpn_lshift (np, np, nn, cnt); + np[nn] = cy; + nn += cy != 0; + } + + nn -= np[nn - 1] == 0; /* normalisation */ + + kp = MPZ_NEWALLOC (r, nn); + SIZ(r) = nn; + MPN_COPY (kp, np, nn); + TMP_FREE; +} + +static void +mpz_smallk_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k) +{ + unsigned nmax, numfac; + mp_ptr rp; + mp_size_t rn, alloc; + mp_limb_t i, iii, cy; + unsigned i2cnt, cnt; + + MAXFACS (nmax, n); + nmax = MIN (nmax, M); + + i = n - k + 1; + + i2cnt = __gmp_fac2cnt_table[k / 2 - 1]; /* low zeros count */ + if (nmax >= k) + { + MPZ_NEWALLOC (r, 1) [0] = mulfunc[k - 1] (i) * facinv[k - 2] >> + (i2cnt - tcnttab[k - 1]); + SIZ(r) = 1; + return; + } + + count_leading_zeros (cnt, (mp_limb_t) n); + cnt = GMP_LIMB_BITS - cnt; + alloc = cnt * k / GMP_NUMB_BITS + 3; /* FIXME: ensure rounding is enough. */ + rp = MPZ_NEWALLOC (r, alloc); + + rp[0] = mulfunc[nmax - 1] (i); + rn = 1; + i += nmax; /* number of factors used */ + i2cnt -= tcnttab[nmax - 1]; /* low zeros count */ + numfac = k - nmax; + do + { + nmax = MIN (nmax, numfac); + iii = mulfunc[nmax - 1] (i); + i += nmax; /* number of factors used */ + i2cnt -= tcnttab[nmax - 1]; /* update low zeros count */ + cy = mpn_mul_1 (rp, rp, rn, iii); /* accumulate new factors */ + rp[rn] = cy; + rn += cy != 0; + numfac -= nmax; + } while (numfac != 0); + + ASSERT (rn < alloc); + + mpn_pi1_bdiv_q_1 (rp, rp, rn, __gmp_oddfac_table[k], facinv[k - 2], i2cnt); + /* A two-fold, branch-free normalisation is possible :*/ + /* rn -= rp[rn - 1] == 0; */ + /* rn -= rp[rn - 1] == 0; */ + MPN_NORMALIZE_NOT_ZERO (rp, rn); + + SIZ(r) = rn; +} + +/* Algorithm: + + Plain and simply multiply things together. + + We tabulate factorials (k!/2^t)^(-1) mod B (where t is chosen such + that k!/2^t is odd). + +*/ + +static mp_limb_t +bc_bin_uiui (unsigned int n, unsigned int k) +{ + return ((__gmp_oddfac_table[n] * facinv[k - 2] * facinv[n - k - 2]) + << (__gmp_fac2cnt_table[n / 2 - 1] - __gmp_fac2cnt_table[k / 2 - 1] - __gmp_fac2cnt_table[(n-k) / 2 - 1])) + & GMP_NUMB_MASK; +} + +/* Algorithm: + + Recursively exploit the relation + bin(n,k) = bin(n,k>>1)*bin(n-k>>1,k-k>>1)/bin(k,k>>1) . + + Values for binomial(k,k>>1) that fit in a limb are precomputed + (with inverses). +*/ + +/* bin2kk[i - ODD_CENTRAL_BINOMIAL_OFFSET] = + binomial(i*2,i)/2^t (where t is chosen so that it is odd). */ +static const mp_limb_t bin2kk[] = { ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE }; + +/* bin2kkinv[i] = bin2kk[i]^-1 mod B */ +static const mp_limb_t bin2kkinv[] = { ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE }; + +/* bin2kk[i] = binomial((i+MIN_S)*2,i+MIN_S)/2^t. This table contains the t values. */ +static const unsigned char fac2bin[] = { CENTRAL_BINOMIAL_2FAC_TABLE }; + +static void +mpz_smallkdc_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k) +{ + mp_ptr rp; + mp_size_t rn; + unsigned long int hk; + + hk = k >> 1; + + if ((! BIN_UIUI_RECURSIVE_SMALLDC) || hk <= ODD_FACTORIAL_TABLE_LIMIT) + mpz_smallk_bin_uiui (r, n, hk); + else + mpz_smallkdc_bin_uiui (r, n, hk); + k -= hk; + n -= hk; + if (n <= ODD_FACTORIAL_EXTTABLE_LIMIT) { + mp_limb_t cy; + rn = SIZ (r); + rp = MPZ_REALLOC (r, rn + 1); + cy = mpn_mul_1 (rp, rp, rn, bc_bin_uiui (n, k)); + rp [rn] = cy; + rn += cy != 0; + } else { + mp_limb_t buffer[ODD_CENTRAL_BINOMIAL_TABLE_LIMIT + 3]; + mpz_t t; + + ALLOC (t) = ODD_CENTRAL_BINOMIAL_TABLE_LIMIT + 3; + PTR (t) = buffer; + if ((! BIN_UIUI_RECURSIVE_SMALLDC) || k <= ODD_FACTORIAL_TABLE_LIMIT) + mpz_smallk_bin_uiui (t, n, k); + else + mpz_smallkdc_bin_uiui (t, n, k); + mpz_mul (r, r, t); + rp = PTR (r); + rn = SIZ (r); + } + + mpn_pi1_bdiv_q_1 (rp, rp, rn, bin2kk[k - ODD_CENTRAL_BINOMIAL_OFFSET], + bin2kkinv[k - ODD_CENTRAL_BINOMIAL_OFFSET], + fac2bin[k - ODD_CENTRAL_BINOMIAL_OFFSET] - (k != hk)); + /* A two-fold, branch-free normalisation is possible :*/ + /* rn -= rp[rn - 1] == 0; */ + /* rn -= rp[rn - 1] == 0; */ + MPN_NORMALIZE_NOT_ZERO (rp, rn); + + SIZ(r) = rn; +} + +/* mpz_goetgheluck_bin_uiui(RESULT, N, K) -- Set RESULT to binomial(N,K). + * + * Contributed to the GNU project by Marco Bodrato. + * + * Implementation of the algorithm by P. Goetgheluck, "Computing + * Binomial Coefficients", The American Mathematical Monthly, Vol. 94, + * No. 4 (April 1987), pp. 360-365. + * + * Acknowledgment: Peter Luschny did spot the slowness of the previous + * code and suggested the reference. + */ + +/* TODO: Remove duplicated constants / macros / static functions... + */ + +/*************************************************************/ +/* Section macros: common macros, for swing/fac/bin (&sieve) */ +/*************************************************************/ + +#define FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I) \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = 1; \ + } + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +#define LOOP_ON_SIEVE_CONTINUE(prime,end) \ + __max_i = (end); \ + \ + do { \ + ++__i; \ + if ((*__sieve & __mask) == 0) \ + { \ + mp_limb_t prime; \ + prime = id_to_n(__i) + +#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \ + do { \ + mp_limb_t __mask, *__sieve, __max_i, __i; \ + \ + __i = (start)-(off); \ + __sieve = (sieve) + __i / GMP_LIMB_BITS; \ + __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \ + __i += (off); \ + \ + LOOP_ON_SIEVE_CONTINUE(prime,end) + +#define LOOP_ON_SIEVE_STOP \ + } \ + __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \ + __sieve += __mask & 1; \ + } while (__i <= __max_i) + +#define LOOP_ON_SIEVE_END \ + LOOP_ON_SIEVE_STOP; \ + } while (0) + +/*********************************************************/ +/* Section sieve: sieving functions and tools for primes */ +/*********************************************************/ + +#if WANT_ASSERT +static mp_limb_t +bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; } +#endif + +/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/ +static mp_limb_t +id_to_n (mp_limb_t id) { return id*3+1+(id&1); } + +/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */ +static mp_limb_t +n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; } + +static mp_size_t +primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; } + +/*********************************************************/ +/* Section binomial: fast binomial implementation */ +/*********************************************************/ + +#define COUNT_A_PRIME(P, N, K, PR, MAX_PR, VEC, I) \ + do { \ + mp_limb_t __a, __b, __prime, __ma,__mb; \ + __prime = (P); \ + __a = (N); __b = (K); __mb = 0; \ + FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I); \ + do { \ + __mb += __b % __prime; __b /= __prime; \ + __ma = __a % __prime; __a /= __prime; \ + if (__ma < __mb) { \ + __mb = 1; (PR) *= __prime; \ + } else __mb = 0; \ + } while (__a >= __prime); \ + } while (0) + +#define SH_COUNT_A_PRIME(P, N, K, PR, MAX_PR, VEC, I) \ + do { \ + mp_limb_t __prime; \ + __prime = (P); \ + if (((N) % __prime) < ((K) % __prime)) { \ + FACTOR_LIST_STORE (__prime, PR, MAX_PR, VEC, I); \ + } \ + } while (0) + +/* Returns an approximation of the sqare root of x. + * It gives: + * limb_apprsqrt (x) ^ 2 <= x < (limb_apprsqrt (x)+1) ^ 2 + * or + * x <= limb_apprsqrt (x) ^ 2 <= x * 9/8 + */ +static mp_limb_t +limb_apprsqrt (mp_limb_t x) +{ + int s; + + ASSERT (x > 2); + count_leading_zeros (s, x); + s = (GMP_LIMB_BITS - s) >> 1; + return ((CNST_LIMB(1) << (s - 1)) + (x >> 1 >> s)); +} + +static void +mpz_goetgheluck_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k) +{ + mp_limb_t *sieve, *factors, count; + mp_limb_t prod, max_prod; + mp_size_t j; + TMP_DECL; + + ASSERT (BIN_GOETGHELUCK_THRESHOLD >= 13); + ASSERT (n >= 25); + + TMP_MARK; + sieve = TMP_ALLOC_LIMBS (primesieve_size (n)); + + count = gmp_primesieve (sieve, n) + 1; + factors = TMP_ALLOC_LIMBS (count / log_n_max (n) + 1); + + max_prod = GMP_NUMB_MAX / n; + + /* Handle primes = 2, 3 separately. */ + popc_limb (count, n - k); + popc_limb (j, k); + count += j; + popc_limb (j, n); + count -= j; + prod = CNST_LIMB(1) << count; + + j = 0; + COUNT_A_PRIME (3, n, k, prod, max_prod, factors, j); + + /* Accumulate prime factors from 5 to n/2 */ + { + mp_limb_t s; + + s = limb_apprsqrt(n); + s = n_to_bit (s); + ASSERT (bit_to_n (s+1) * bit_to_n (s+1) > n); + ASSERT (s <= n_to_bit (n >> 1)); + LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), s, 0,sieve); + COUNT_A_PRIME (prime, n, k, prod, max_prod, factors, j); + LOOP_ON_SIEVE_STOP; + + ASSERT (max_prod <= GMP_NUMB_MAX / 2); + max_prod <<= 1; + + LOOP_ON_SIEVE_CONTINUE (prime, n_to_bit (n >> 1)); + SH_COUNT_A_PRIME (prime, n, k, prod, max_prod, factors, j); + LOOP_ON_SIEVE_END; + + max_prod >>= 1; + } + + /* Store primes from (n-k)+1 to n */ + ASSERT (n_to_bit (n - k) < n_to_bit (n)); + + LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (n - k) + 1, n_to_bit (n), 0,sieve); + FACTOR_LIST_STORE (prime, prod, max_prod, factors, j); + LOOP_ON_SIEVE_END; + + if (LIKELY (j != 0)) + { + factors[j++] = prod; + mpz_prodlimbs (r, factors, j); + } + else + { + MPZ_NEWALLOC (r, 1)[0] = prod; + SIZ (r) = 1; + } + TMP_FREE; +} + +#undef COUNT_A_PRIME +#undef SH_COUNT_A_PRIME +#undef LOOP_ON_SIEVE_END +#undef LOOP_ON_SIEVE_STOP +#undef LOOP_ON_SIEVE_BEGIN +#undef LOOP_ON_SIEVE_CONTINUE + +/*********************************************************/ +/* End of implementation of Goetgheluck's algorithm */ +/*********************************************************/ + +void +mpz_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k) +{ + if (UNLIKELY (n < k)) { + SIZ (r) = 0; +#if BITS_PER_ULONG > GMP_NUMB_BITS + } else if (UNLIKELY (n > GMP_NUMB_MAX)) { + mpz_t tmp; + + mpz_init_set_ui (tmp, n); + mpz_bin_ui (r, tmp, k); + mpz_clear (tmp); +#endif + } else { + ASSERT (n <= GMP_NUMB_MAX); + /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. */ + k = MIN (k, n - k); + if (k < 2) { + MPZ_NEWALLOC (r, 1)[0] = k ? n : 1; /* 1 + ((-k) & (n-1)); */ + SIZ(r) = 1; + } else if (n <= ODD_FACTORIAL_EXTTABLE_LIMIT) { /* k >= 2, n >= 4 */ + MPZ_NEWALLOC (r, 1)[0] = bc_bin_uiui (n, k); + SIZ(r) = 1; + } else if (k <= ODD_FACTORIAL_TABLE_LIMIT) + mpz_smallk_bin_uiui (r, n, k); + else if (BIN_UIUI_ENABLE_SMALLDC && + k <= (BIN_UIUI_RECURSIVE_SMALLDC ? ODD_CENTRAL_BINOMIAL_TABLE_LIMIT : ODD_FACTORIAL_TABLE_LIMIT)* 2) + mpz_smallkdc_bin_uiui (r, n, k); + else if (ABOVE_THRESHOLD (k, BIN_GOETGHELUCK_THRESHOLD) && + k > (n >> 4)) /* k > ODD_FACTORIAL_TABLE_LIMIT */ + mpz_goetgheluck_bin_uiui (r, n, k); + else + mpz_bdiv_bin_uiui (r, n, k); + } +} diff --git a/gmp-6.3.0/mpz/cdiv_q.c b/gmp-6.3.0/mpz/cdiv_q.c new file mode 100644 index 0000000..f19eb74 --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_q.c @@ -0,0 +1,52 @@ +/* mpz_cdiv_q -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. + +Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_cdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t dividend_size = SIZ (dividend); + mp_size_t divisor_size = SIZ (divisor); + mpz_t rem; + TMP_DECL; + + TMP_MARK; + + MPZ_TMP_INIT (rem, ABS (divisor_size)); + + mpz_tdiv_qr (quot, rem, dividend, divisor); + + if ((divisor_size ^ dividend_size) >= 0 && SIZ (rem) != 0) + mpz_add_ui (quot, quot, 1L); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/cdiv_q_ui.c b/gmp-6.3.0/mpz/cdiv_q_ui.c new file mode 100644 index 0000000..269d9a3 --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_q_ui.c @@ -0,0 +1,102 @@ +/* mpz_cdiv_q_ui -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. In order to make it + always fit into the return type, the negative of the true remainder is + returned. + +Copyright 1994, 1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_cdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + qp[0] = 0; + rl = np[0]; + qn = 1; /* a white lie, fixed below */ + } + else + { + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; + } + + if (rl != 0 && ns >= 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + + if (rl != 0 && ns >= 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/cdiv_qr.c b/gmp-6.3.0/mpz/cdiv_qr.c new file mode 100644 index 0000000..bc9b892 --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_qr.c @@ -0,0 +1,64 @@ +/* mpz_cdiv_qr -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. + +Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_cdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t divisor_size = SIZ (divisor); + mp_size_t xsize; + mpz_t temp_divisor; /* N.B.: lives until function returns! */ + TMP_DECL; + + TMP_MARK; + + /* We need the original value of the divisor after the quotient and + remainder have been preliminary calculated. We have to copy it to + temporary space if it's the same variable as either QUOT or REM. */ + if (quot == divisor || rem == divisor) + { + MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); + mpz_set (temp_divisor, divisor); + divisor = temp_divisor; + } + + xsize = SIZ (dividend) ^ divisor_size;; + mpz_tdiv_qr (quot, rem, dividend, divisor); + + if (xsize >= 0 && SIZ (rem) != 0) + { + mpz_add_ui (quot, quot, 1L); + mpz_sub (rem, rem, divisor); + } + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/cdiv_qr_ui.c b/gmp-6.3.0/mpz/cdiv_qr_ui.c new file mode 100644 index 0000000..0c11fb6 --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_qr_ui.c @@ -0,0 +1,118 @@ +/* mpz_cdiv_qr_ui -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. In order to make it + always fit into the return type, the negative of the true remainder is + returned. + +Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_cdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp; + mp_size_t rn; + + rp = MPZ_REALLOC (rem, 2); + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + qp[0] = 0; + qn = 1; /* a white lie, fixed below */ + rl = np[0]; + rp[0] = rl; + } + else + { + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; + } + + if (rl != 0 && ns >= 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + SIZ(rem) = -rn; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + if (ns >= 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + MPZ_NEWALLOC (rem, 1)[0] = rl; + SIZ(rem) = -(rl != 0); + } + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/cdiv_r.c b/gmp-6.3.0/mpz/cdiv_r.c new file mode 100644 index 0000000..83c624a --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_r.c @@ -0,0 +1,60 @@ +/* mpz_cdiv_r -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. + +Copyright 1994-1996, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_cdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t divisor_size = SIZ (divisor); + mpz_t temp_divisor; /* N.B.: lives until function returns! */ + TMP_DECL; + + TMP_MARK; + + /* We need the original value of the divisor after the remainder has been + preliminary calculated. We have to copy it to temporary space if it's + the same variable as REM. */ + if (rem == divisor) + { + + MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); + mpz_set (temp_divisor, divisor); + divisor = temp_divisor; + } + + mpz_tdiv_r (rem, dividend, divisor); + + if ((divisor_size ^ SIZ (dividend)) >= 0 && SIZ (rem) != 0) + mpz_sub (rem, rem, divisor); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/cdiv_r_ui.c b/gmp-6.3.0/mpz/cdiv_r_ui.c new file mode 100644 index 0000000..84d51db --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_r_ui.c @@ -0,0 +1,109 @@ +/* mpz_cdiv_r_ui -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. In order to make it + always fit into the return type, the negative of the true remainder is + returned. + +Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_cdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp, qp; + mp_size_t rn; + TMP_DECL; + + rp = MPZ_REALLOC (rem, 2); + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + rp[0] = rl; + } + else + { + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + } + + if (rl != 0 && ns >= 0) + { + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + SIZ(rem) = -rn; + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + if (ns >= 0) + rl = divisor - rl; + + MPZ_NEWALLOC (rem, 1)[0] = rl; + SIZ(rem) = -1; + } + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/cdiv_ui.c b/gmp-6.3.0/mpz/cdiv_ui.c new file mode 100644 index 0000000..e1a1c49 --- /dev/null +++ b/gmp-6.3.0/mpz/cdiv_ui.c @@ -0,0 +1,102 @@ +/* mpz_cdiv_ui -- Division rounding the quotient towards +infinity. The + remainder gets the opposite sign as the denominator. In order to make it + always fit into the return type, the negative of the true remainder is + returned. + +Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_cdiv_ui (mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + mp_ptr qp; + mp_size_t rn; + TMP_DECL; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + rp[0] = rl; + } + else + { + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + } + + if (rl != 0 && ns >= 0) + { + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + if (rl == 0) + ; + else + { + if (ns >= 0) + rl = divisor - rl; + } + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/cfdiv_q_2exp.c b/gmp-6.3.0/mpz/cfdiv_q_2exp.c new file mode 100644 index 0000000..413ea36 --- /dev/null +++ b/gmp-6.3.0/mpz/cfdiv_q_2exp.c @@ -0,0 +1,111 @@ +/* mpz_cdiv_q_2exp, mpz_fdiv_q_2exp -- quotient from mpz divided by 2^n. + +Copyright 1991, 1993, 1994, 1996, 1998, 1999, 2001, 2002, 2004, 2012, +2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +/* dir==1 for ceil, dir==-1 for floor */ + +static void __gmpz_cfdiv_q_2exp (REGPARM_3_1 (mpz_ptr, mpz_srcptr, mp_bitcnt_t, int)) REGPARM_ATTR (1); +#define cfdiv_q_2exp(w,u,cnt,dir) __gmpz_cfdiv_q_2exp (REGPARM_3_1 (w,u,cnt,dir)) + +REGPARM_ATTR (1) static void +cfdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt, int dir) +{ + mp_size_t wsize, usize, abs_usize, limb_cnt, i; + mp_srcptr up; + mp_ptr wp; + mp_limb_t round, rmask; + + usize = SIZ (u); + abs_usize = ABS (usize); + limb_cnt = cnt / GMP_NUMB_BITS; + wsize = abs_usize - limb_cnt; + if (wsize <= 0) + { + /* u < 2**cnt, so result 1, 0 or -1 according to rounding */ + MPZ_NEWALLOC (w, 1)[0] = 1; + SIZ(w) = (usize == 0 || (usize ^ dir) < 0 ? 0 : dir); + return; + } + + /* +1 limb to allow for mpn_add_1 below */ + wp = MPZ_REALLOC (w, wsize+1); + + /* Check for rounding if direction matches u sign. + Set round if we're skipping non-zero limbs. */ + up = PTR(u); + round = 0; + rmask = ((usize ^ dir) >= 0 ? MP_LIMB_T_MAX : 0); + if (rmask != 0) + for (i = 0; i < limb_cnt && round == 0; i++) + round = up[i]; + + cnt %= GMP_NUMB_BITS; + if (cnt != 0) + { + round |= rmask & mpn_rshift (wp, up + limb_cnt, wsize, cnt); + wsize -= (wp[wsize - 1] == 0); + } + else + MPN_COPY_INCR (wp, up + limb_cnt, wsize); + + if (round != 0) + { + if (wsize != 0) + { + mp_limb_t cy; + cy = mpn_add_1 (wp, wp, wsize, CNST_LIMB(1)); + wp[wsize] = cy; + wsize += cy; + } + else + { + /* We shifted something to zero. */ + wp[0] = 1; + wsize = 1; + } + } + SIZ(w) = (usize >= 0 ? wsize : -wsize); +} + + +void +mpz_cdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt) +{ + cfdiv_q_2exp (w, u, cnt, 1); +} + +void +mpz_fdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt) +{ + cfdiv_q_2exp (w, u, cnt, -1); +} diff --git a/gmp-6.3.0/mpz/cfdiv_r_2exp.c b/gmp-6.3.0/mpz/cfdiv_r_2exp.c new file mode 100644 index 0000000..fedb97d --- /dev/null +++ b/gmp-6.3.0/mpz/cfdiv_r_2exp.c @@ -0,0 +1,159 @@ +/* mpz_cdiv_r_2exp, mpz_fdiv_r_2exp -- remainder from mpz divided by 2^n. + +Copyright 2001, 2002, 2004, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +/* Bit mask of "n" least significant bits of a limb. */ +#define LOW_MASK(n) ((CNST_LIMB(1) << (n)) - 1) + + +/* dir==1 for ceil, dir==-1 for floor */ + +static void __gmpz_cfdiv_r_2exp (REGPARM_3_1 (mpz_ptr, mpz_srcptr, mp_bitcnt_t, int)) REGPARM_ATTR (1); +#define cfdiv_r_2exp(w,u,cnt,dir) __gmpz_cfdiv_r_2exp (REGPARM_3_1 (w, u, cnt, dir)) + +REGPARM_ATTR (1) static void +cfdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt, int dir) +{ + mp_size_t usize, abs_usize, limb_cnt, i; + mp_srcptr up; + mp_ptr wp; + mp_limb_t high; + + usize = SIZ(u); + if (usize == 0) + { + SIZ(w) = 0; + return; + } + + limb_cnt = cnt / GMP_NUMB_BITS; + cnt %= GMP_NUMB_BITS; + abs_usize = ABS (usize); + + /* MPZ_REALLOC(w) below is only when w!=u, so we can fetch PTR(u) here + nice and early */ + up = PTR(u); + + if ((usize ^ dir) < 0) + { + /* Round towards zero, means just truncate */ + + if (w == u) + { + /* if already smaller than limb_cnt then do nothing */ + if (abs_usize <= limb_cnt) + return; + wp = (mp_ptr) up; + } + else + { + i = MIN (abs_usize, limb_cnt+1); + wp = MPZ_NEWALLOC (w, i); + MPN_COPY (wp, up, i); + + /* if smaller than limb_cnt then only the copy is needed */ + if (abs_usize <= limb_cnt) + { + SIZ(w) = usize; + return; + } + } + } + else + { + /* Round away from zero, means twos complement if non-zero */ + + /* if u!=0 and smaller than divisor, then must negate */ + if (abs_usize <= limb_cnt) + goto negate; + + /* if non-zero low limb, then must negate */ + for (i = 0; i < limb_cnt; i++) + if (up[i] != 0) + goto negate; + + /* if non-zero partial limb, then must negate */ + if ((up[limb_cnt] & LOW_MASK (cnt)) != 0) + goto negate; + + /* otherwise low bits of u are zero, so that's the result */ + SIZ(w) = 0; + return; + + negate: + /* twos complement negation to get 2**cnt-u */ + + wp = MPZ_REALLOC (w, limb_cnt+1); + up = PTR(u); + + /* Ones complement */ + i = MIN (abs_usize, limb_cnt+1); + ASSERT_CARRY (mpn_neg (wp, up, i)); + for ( ; i <= limb_cnt; i++) + wp[i] = GMP_NUMB_MAX; + + usize = -usize; + } + + /* Mask the high limb */ + high = wp[limb_cnt]; + high &= LOW_MASK (cnt); + wp[limb_cnt] = high; + + /* Strip any consequent high zeros */ + while (high == 0) + { + limb_cnt--; + if (limb_cnt < 0) + { + SIZ(w) = 0; + return; + } + high = wp[limb_cnt]; + } + + limb_cnt++; + SIZ(w) = (usize >= 0 ? limb_cnt : -limb_cnt); +} + + +void +mpz_cdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt) +{ + cfdiv_r_2exp (w, u, cnt, 1); +} + +void +mpz_fdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt) +{ + cfdiv_r_2exp (w, u, cnt, -1); +} diff --git a/gmp-6.3.0/mpz/clear.c b/gmp-6.3.0/mpz/clear.c new file mode 100644 index 0000000..f8c38a2 --- /dev/null +++ b/gmp-6.3.0/mpz/clear.c @@ -0,0 +1,40 @@ +/* mpz_clear -- de-allocate the space occupied by the dynamic digit space of + an integer. + +Copyright 1991, 1993-1995, 2000, 2001, 2012, 2014, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_clear (mpz_ptr x) +{ + if (ALLOC (x)) + __GMP_FREE_FUNC_LIMBS (PTR (x), ALLOC(x)); +} diff --git a/gmp-6.3.0/mpz/clears.c b/gmp-6.3.0/mpz/clears.c new file mode 100644 index 0000000..7ac257a --- /dev/null +++ b/gmp-6.3.0/mpz/clears.c @@ -0,0 +1,50 @@ +/* mpz_clears() -- Clear multiple mpz_t variables. + +Copyright 2009, 2014, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + +void +mpz_clears (mpz_ptr x, ...) +{ + va_list ap; + + va_start (ap, x); + + do + { + if (ALLOC (x)) + __GMP_FREE_FUNC_LIMBS (PTR (x), ALLOC (x)); + x = va_arg (ap, mpz_ptr); + } + while (x != NULL); + + va_end (ap); +} diff --git a/gmp-6.3.0/mpz/clrbit.c b/gmp-6.3.0/mpz/clrbit.c new file mode 100644 index 0000000..8b3c854 --- /dev/null +++ b/gmp-6.3.0/mpz/clrbit.c @@ -0,0 +1,115 @@ +/* mpz_clrbit -- clear a specified bit. + +Copyright 1991, 1993-1995, 2001, 2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_clrbit (mpz_ptr d, mp_bitcnt_t bit_idx) +{ + mp_size_t dsize = SIZ (d); + mp_ptr dp = PTR (d); + mp_size_t limb_idx; + mp_limb_t mask; + + limb_idx = bit_idx / GMP_NUMB_BITS; + mask = CNST_LIMB(1) << (bit_idx % GMP_NUMB_BITS); + if (dsize >= 0) + { + if (limb_idx < dsize) + { + mp_limb_t dlimb; + dlimb = dp[limb_idx] & ~mask; + dp[limb_idx] = dlimb; + + if (UNLIKELY ((dlimb == 0) + limb_idx == dsize)) /* dsize == limb_idx + 1 */ + { + /* high limb became zero, must normalize */ + MPN_NORMALIZE (dp, limb_idx); + SIZ (d) = limb_idx; + } + } + else + ; + } + else + { + /* Simulate two's complement arithmetic, i.e. simulate + 1. Set OP = ~(OP - 1) [with infinitely many leading ones]. + 2. clear the bit. + 3. Set OP = ~OP + 1. */ + + dsize = -dsize; + + if (limb_idx < dsize) + { + mp_size_t zero_bound; + + /* No index upper bound on this loop, we're sure there's a non-zero limb + sooner or later. */ + zero_bound = 0; + while (dp[zero_bound] == 0) + zero_bound++; + + if (limb_idx > zero_bound) + { + dp[limb_idx] |= mask; + } + else if (limb_idx == zero_bound) + { + mp_limb_t dlimb; + dlimb = (((dp[limb_idx] - 1) | mask) + 1) & GMP_NUMB_MASK; + dp[limb_idx] = dlimb; + + if (dlimb == 0) + { + /* Increment at limb_idx + 1. Extend the number with a zero limb + for simplicity. */ + dp = MPZ_REALLOC (d, dsize + 1); + dp[dsize] = 0; + MPN_INCR_U (dp + limb_idx + 1, dsize - limb_idx, 1); + dsize += dp[dsize]; + + SIZ (d) = -dsize; + } + } + else + ; + } + else + { + /* Ugh. The bit should be cleared outside of the end of the + number. We have to increase the size of the number. */ + dp = MPZ_REALLOC (d, limb_idx + 1); + SIZ (d) = -(limb_idx + 1); + MPN_ZERO (dp + dsize, limb_idx - dsize); + dp[limb_idx] = mask; + } + } +} diff --git a/gmp-6.3.0/mpz/cmp.c b/gmp-6.3.0/mpz/cmp.c new file mode 100644 index 0000000..ba4c023 --- /dev/null +++ b/gmp-6.3.0/mpz/cmp.c @@ -0,0 +1,53 @@ +/* mpz_cmp(u,v) -- Compare U, V. Return positive, zero, or negative + based on if U > V, U == V, or U < V. + +Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2011, 2020 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_cmp (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW +{ + mp_size_t usize, vsize, asize; + mp_srcptr up, vp; + int cmp; + + usize = SIZ(u); + vsize = SIZ(v); + /* Cannot use usize - vsize, may overflow an "int" */ + if (usize != vsize) + return (usize > vsize) ? 1 : -1; + + asize = ABS (usize); + up = PTR(u); + vp = PTR(v); + MPN_CMP (cmp, up, vp, asize); + return (usize >= 0 ? cmp : -cmp); +} diff --git a/gmp-6.3.0/mpz/cmp_d.c b/gmp-6.3.0/mpz/cmp_d.c new file mode 100644 index 0000000..b5b5e8b --- /dev/null +++ b/gmp-6.3.0/mpz/cmp_d.c @@ -0,0 +1,144 @@ +/* mpz_cmp_d -- compare absolute values of mpz and double. + +Copyright 2001-2003 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_FLOAT_H +#include /* for DBL_MAX */ +#endif + +#include "gmp-impl.h" + + +#define RETURN_CMP(zl, dl) \ + do { \ + zlimb = (zl); \ + dlimb = (dl); \ + if (zlimb != dlimb) \ + return (zlimb >= dlimb ? ret : -ret); \ + } while (0) + +#define RETURN_NONZERO(ptr, size, val) \ + do { \ + mp_size_t __i; \ + for (__i = (size)-1; __i >= 0; __i--) \ + if ((ptr)[__i] != 0) \ + return val; \ + return 0; \ + } while (0) + + +int +mpz_cmp_d (mpz_srcptr z, double d) +{ + mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb; + mp_srcptr zp; + mp_size_t zsize; + int dexp, ret; + + /* d=NaN is an invalid operation, there's no sensible return value. + d=Inf or -Inf is always bigger than z. */ + DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), goto z_zero); + + /* 1. Either operand zero. */ + zsize = SIZ(z); + if (d == 0.0) + return zsize; + if (zsize == 0) + { + z_zero: + return (d < 0.0 ? 1 : -1); + } + + /* 2. Opposite signs. */ + if (zsize >= 0) + { + if (d < 0.0) + return 1; /* >=0 cmp <0 */ + ret = 1; + } + else + { + if (d >= 0.0) + return -1; /* <0 cmp >=0 */ + ret = -1; + d = -d; + zsize = -zsize; + } + + /* 3. Small d, knowing abs(z) >= 1. */ + if (d < 1.0) + return ret; + + dexp = __gmp_extract_double (darray, d); + ASSERT (dexp >= 1); + + /* 4. Check for different high limb positions. */ + if (zsize != dexp) + return (zsize >= dexp ? ret : -ret); + + /* 5. Limb data. */ + zp = PTR(z); + +#if LIMBS_PER_DOUBLE == 2 + RETURN_CMP (zp[zsize-1], darray[1]); + if (zsize == 1) + return (darray[0] != 0 ? -ret : 0); + + RETURN_CMP (zp[zsize-2], darray[0]); + RETURN_NONZERO (zp, zsize-2, ret); +#endif + +#if LIMBS_PER_DOUBLE == 3 + RETURN_CMP (zp[zsize-1], darray[2]); + if (zsize == 1) + return ((darray[0] | darray[1]) != 0 ? -ret : 0); + + RETURN_CMP (zp[zsize-2], darray[1]); + if (zsize == 2) + return (darray[0] != 0 ? -ret : 0); + + RETURN_CMP (zp[zsize-3], darray[0]); + RETURN_NONZERO (zp, zsize-3, ret); +#endif + +#if LIMBS_PER_DOUBLE >= 4 + { + int i; + for (i = 1; i <= LIMBS_PER_DOUBLE; i++) + { + RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]); + if (i >= zsize) + RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -ret); + } + RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, ret); + } +#endif +} diff --git a/gmp-6.3.0/mpz/cmp_si.c b/gmp-6.3.0/mpz/cmp_si.c new file mode 100644 index 0000000..23296c8 --- /dev/null +++ b/gmp-6.3.0/mpz/cmp_si.c @@ -0,0 +1,69 @@ +/* mpz_cmp_si(u,v) -- Compare an integer U with a single-word int V. + Return positive, zero, or negative based on if U > V, U == V, or U < V. + +Copyright 1991, 1993-1996, 2000-2002, 2012, 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +_mpz_cmp_si (mpz_srcptr u, signed long int v_digit) __GMP_NOTHROW +{ +#if GMP_NAIL_BITS != 0 + /* FIXME. This isn't very pretty. */ + mpz_t tmp; + mp_limb_t tt[2]; + PTR(tmp) = tt; + ALLOC(tmp) = 2; + mpz_set_si (tmp, v_digit); + return mpz_cmp (u, tmp); +#else + + mp_size_t vsize, usize; + + usize = SIZ (u); + vsize = (v_digit > 0) - (v_digit < 0); + + if ((usize == 0) | (usize != vsize)) + return usize - vsize; + else { + mp_limb_t u_digit, absv_digit; + + u_digit = PTR (u)[0]; + absv_digit = ABS_CAST (unsigned long, v_digit); + + if (u_digit == absv_digit) + return 0; + + if (u_digit > absv_digit) + return usize; + else + return -usize; + } +#endif +} diff --git a/gmp-6.3.0/mpz/cmp_ui.c b/gmp-6.3.0/mpz/cmp_ui.c new file mode 100644 index 0000000..4b40ab7 --- /dev/null +++ b/gmp-6.3.0/mpz/cmp_ui.c @@ -0,0 +1,77 @@ +/* mpz_cmp_ui.c -- Compare an mpz_t a with an mp_limb_t b. Return positive, + zero, or negative based on if a > b, a == b, or a < b. + +Copyright 1991, 1993-1996, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +_mpz_cmp_ui (mpz_srcptr u, unsigned long int v_digit) __GMP_NOTHROW +{ + mp_ptr up; + mp_size_t un; + mp_limb_t ul; + + up = PTR(u); + un = SIZ(u); + + if (un == 0) + return -(v_digit != 0); + + if (un == 1) + { + ul = up[0]; + if (ul > v_digit) + return 1; + if (ul < v_digit) + return -1; + return 0; + } + +#if GMP_NAIL_BITS != 0 + if (v_digit > GMP_NUMB_MAX) + { + if (un == 2) + { + ul = up[0] + (up[1] << GMP_NUMB_BITS); + + if ((up[1] >> GMP_NAIL_BITS) != 0) + return 1; + + if (ul > v_digit) + return 1; + if (ul < v_digit) + return -1; + return 0; + } + } +#endif + + return un > 0 ? 1 : -1; +} diff --git a/gmp-6.3.0/mpz/cmpabs.c b/gmp-6.3.0/mpz/cmpabs.c new file mode 100644 index 0000000..7e9f160 --- /dev/null +++ b/gmp-6.3.0/mpz/cmpabs.c @@ -0,0 +1,53 @@ +/* mpz_cmpabs(u,v) -- Compare U, V. Return positive, zero, or negative + based on if U > V, U == V, or U < V. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2020 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +int +mpz_cmpabs (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW +{ + mp_size_t usize, vsize; + mp_srcptr up, vp; + int cmp; + + usize = ABSIZ (u); + vsize = ABSIZ (v); + /* Cannot use usize - vsize, may overflow an "int" */ + if (usize != vsize) + return (usize > vsize) ? 1 : -1; + + up = PTR(u); + vp = PTR(v); + MPN_CMP (cmp, up, vp, usize); + return cmp; +} diff --git a/gmp-6.3.0/mpz/cmpabs_d.c b/gmp-6.3.0/mpz/cmpabs_d.c new file mode 100644 index 0000000..d2431cc --- /dev/null +++ b/gmp-6.3.0/mpz/cmpabs_d.c @@ -0,0 +1,129 @@ +/* mpz_cmpabs_d -- compare absolute values of mpz and double. + +Copyright 2001-2003, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_FLOAT_H +#include /* for DBL_MAX */ +#endif + +#include "gmp-impl.h" + + +#define RETURN_CMP(zl, dl) \ + do { \ + zlimb = (zl); \ + dlimb = (dl); \ + if (zlimb != dlimb) \ + return (zlimb >= dlimb ? 1 : -1); \ + } while (0) + +#define RETURN_NONZERO(ptr, size, val) \ + do { \ + mp_size_t __i; \ + for (__i = (size)-1; __i >= 0; __i--) \ + if ((ptr)[__i] != 0) \ + return val; \ + return 0; \ + } while (0) + + +int +mpz_cmpabs_d (mpz_srcptr z, double d) +{ + mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb; + mp_srcptr zp; + mp_size_t zsize; + int dexp; + + /* d=NaN is an invalid operation, there's no sensible return value. + d=Inf or -Inf is always bigger than z. */ + DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), return -1); + + /* 1. Check for either operand zero. */ + zsize = SIZ(z); + if (d == 0.0) + return (zsize != 0); + if (zsize == 0) + return -1; /* d != 0 */ + + /* 2. Ignore signs. */ + zsize = ABS(zsize); + d = ABS(d); + + /* 3. Small d, knowing abs(z) >= 1. */ + if (d < 1.0) + return 1; + + dexp = __gmp_extract_double (darray, d); + ASSERT (dexp >= 1); + + /* 4. Check for different high limb positions. */ + if (zsize != dexp) + return (zsize >= dexp ? 1 : -1); + + /* 5. Limb data. */ + zp = PTR(z); + +#if LIMBS_PER_DOUBLE == 2 + RETURN_CMP (zp[zsize-1], darray[1]); + if (zsize == 1) + return (darray[0] != 0 ? -1 : 0); + + RETURN_CMP (zp[zsize-2], darray[0]); + RETURN_NONZERO (zp, zsize-2, 1); +#endif + +#if LIMBS_PER_DOUBLE == 3 + RETURN_CMP (zp[zsize-1], darray[2]); + if (zsize == 1) + return ((darray[0] | darray[1]) != 0 ? -1 : 0); + + RETURN_CMP (zp[zsize-2], darray[1]); + if (zsize == 2) + return (darray[0] != 0 ? -1 : 0); + + RETURN_CMP (zp[zsize-3], darray[0]); + RETURN_NONZERO (zp, zsize-3, 1); +#endif + +#if LIMBS_PER_DOUBLE >= 4 + { + int i; + for (i = 1; i <= LIMBS_PER_DOUBLE; i++) + { + RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]); + if (i >= zsize) + RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -1); + } + RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, 1); + } +#endif +} diff --git a/gmp-6.3.0/mpz/cmpabs_ui.c b/gmp-6.3.0/mpz/cmpabs_ui.c new file mode 100644 index 0000000..6deffb3 --- /dev/null +++ b/gmp-6.3.0/mpz/cmpabs_ui.c @@ -0,0 +1,76 @@ +/* mpz_cmpabs_ui.c -- Compare an mpz_t a with an mp_limb_t b. Return positive, + zero, or negative based on if a > b, a == b, or a < b. + +Copyright 1991, 1993-1995, 1997, 2000-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_cmpabs_ui (mpz_srcptr u, unsigned long int v_digit) __GMP_NOTHROW +{ + mp_ptr up; + mp_size_t un; + mp_limb_t ul; + + up = PTR(u); + un = SIZ(u); + + if (un == 0) + return -(v_digit != 0); + + un = ABS (un); + + if (un == 1) + { + ul = up[0]; + if (ul > v_digit) + return 1; + if (ul < v_digit) + return -1; + return 0; + } + +#if GMP_NAIL_BITS != 0 + if (v_digit > GMP_NUMB_MAX) + { + if (un == 2) + { + ul = up[0] + (up[1] << GMP_NUMB_BITS); + + if (ul > v_digit) + return 1; + if (ul < v_digit) + return -1; + return 0; + } + } +#endif + + return 1; +} diff --git a/gmp-6.3.0/mpz/com.c b/gmp-6.3.0/mpz/com.c new file mode 100644 index 0000000..c5d22b0 --- /dev/null +++ b/gmp-6.3.0/mpz/com.c @@ -0,0 +1,87 @@ +/* mpz_com(mpz_ptr dst, mpz_ptr src) -- Assign the bit-complemented value of + SRC to DST. + +Copyright 1991, 1993, 1994, 1996, 2001, 2003, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_com (mpz_ptr dst, mpz_srcptr src) +{ + mp_size_t size = SIZ (src); + mp_srcptr src_ptr; + mp_ptr dst_ptr; + + if (size >= 0) + { + /* As with infinite precision: one's complement, two's complement. + But this can be simplified using the identity -x = ~x + 1. + So we're going to compute (~~x) + 1 = x + 1! */ + + if (UNLIKELY (size == 0)) + { + /* special case, as mpn_add_1 wants size!=0 */ + MPZ_NEWALLOC (dst, 1)[0] = 1; + SIZ (dst) = -1; + } + else + { + mp_limb_t cy; + + dst_ptr = MPZ_REALLOC (dst, size + 1); + + src_ptr = PTR (src); + + cy = mpn_add_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); + dst_ptr[size] = cy; + size += cy; + + /* Store a negative size, to indicate ones-extension. */ + SIZ (dst) = -size; + } + } + else + { + /* As with infinite precision: two's complement, then one's complement. + But that can be simplified using the identity -x = ~(x - 1). + So we're going to compute ~~(x - 1) = x - 1! */ + size = -size; + + dst_ptr = MPZ_REALLOC (dst, size); + + src_ptr = PTR (src); + + mpn_sub_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); + size -= dst_ptr[size - 1] == 0; + + /* Store a positive size, to indicate zero-extension. */ + SIZ (dst) = size; + } +} diff --git a/gmp-6.3.0/mpz/combit.c b/gmp-6.3.0/mpz/combit.c new file mode 100644 index 0000000..0a29875 --- /dev/null +++ b/gmp-6.3.0/mpz/combit.c @@ -0,0 +1,103 @@ +/* mpz_combit -- complement a specified bit. + +Copyright 2002, 2003, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_combit (mpz_ptr d, mp_bitcnt_t bit_index) +{ + mp_size_t dsize = SIZ(d); + mp_ptr dp = PTR(d); + + mp_size_t limb_index = bit_index / GMP_NUMB_BITS; + mp_limb_t bit = (CNST_LIMB (1) << (bit_index % GMP_NUMB_BITS)); + + /* Check for the most common case: Positive input, no realloc or + normalization needed. */ + if (limb_index + 1 < dsize) + dp[limb_index] ^= bit; + + /* Check for the hairy case. d < 0, and we have all zero bits to the + right of the bit to toggle. */ + else if (limb_index < -dsize + && (limb_index == 0 || mpn_zero_p (dp, limb_index)) + && (dp[limb_index] & (bit - 1)) == 0) + { + ASSERT (dsize < 0); + dsize = -dsize; + + if (dp[limb_index] & bit) + { + /* We toggle the least significant one bit. Corresponds to + an add, with potential carry propagation, on the absolute + value. */ + dp = MPZ_REALLOC (d, 1 + dsize); + dp[dsize] = 0; + MPN_INCR_U (dp + limb_index, 1 + dsize - limb_index, bit); + SIZ(d) = - dsize - dp[dsize]; + } + else + { + /* We toggle a zero bit, subtract from the absolute value. */ + MPN_DECR_U (dp + limb_index, dsize - limb_index, bit); + /* The absolute value shrinked by at most one bit. */ + dsize -= dp[dsize - 1] == 0; + ASSERT (dsize > 0 && dp[dsize - 1] != 0); + SIZ (d) = -dsize; + } + } + else + { + /* Simple case: Toggle the bit in the absolute value. */ + dsize = ABS(dsize); + if (limb_index < dsize) + { + mp_limb_t dlimb; + dlimb = dp[limb_index] ^ bit; + dp[limb_index] = dlimb; + + /* Can happen only when limb_index = dsize - 1. Avoid SIZ(d) + bookkeeping in the common case. */ + if (UNLIKELY ((dlimb == 0) + limb_index == dsize)) /* dsize == limb_index + 1 */ + { + /* high limb became zero, must normalize */ + MPN_NORMALIZE (dp, limb_index); + SIZ (d) = SIZ (d) >= 0 ? limb_index : -limb_index; + } + } + else + { + dp = MPZ_REALLOC (d, limb_index + 1); + MPN_ZERO(dp + dsize, limb_index - dsize); + dp[limb_index++] = bit; + SIZ(d) = SIZ(d) >= 0 ? limb_index : -limb_index; + } + } +} diff --git a/gmp-6.3.0/mpz/cong.c b/gmp-6.3.0/mpz/cong.c new file mode 100644 index 0000000..5d2d835 --- /dev/null +++ b/gmp-6.3.0/mpz/cong.c @@ -0,0 +1,182 @@ +/* mpz_congruent_p -- test congruence of two mpz's. + +Copyright 2001, 2002, 2005 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* For big divisors this code is only very slightly better than the user + doing a combination of mpz_sub and mpz_tdiv_r, but it's quite convenient, + and perhaps in the future can be improved, in similar ways to + mpn_divisible_p perhaps. + + The csize==1 / dsize==1 special case makes mpz_congruent_p as good as + mpz_congruent_ui_p on relevant operands, though such a combination + probably doesn't occur often. + + Alternatives: + + If c= 0 ? alow : -alow); + if (((alow-clow) & dmask) != 0) + return 0; + + if (csize == 1) + { + if (dsize == 1) + { + cong_1: + if (sign < 0) + NEG_MOD (clow, clow, dlow); + + if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) + { + r = mpn_mod_1 (ap, asize, dlow); + if (clow < dlow) + return r == clow; + else + return r == (clow % dlow); + } + + if ((dlow & 1) == 0) + { + /* Strip low zero bits to get odd d required by modexact. If + d==e*2^n then a==c mod d if and only if both a==c mod e and + a==c mod 2^n, the latter having been done above. */ + unsigned twos; + count_trailing_zeros (twos, dlow); + dlow >>= twos; + } + + r = mpn_modexact_1c_odd (ap, asize, dlow, clow); + return r == 0 || r == dlow; + } + + /* dlow==0 is avoided since we don't want to bother handling extra low + zero bits if dsecond is even (would involve borrow if a,c differ in + sign and alow,clow!=0). */ + if (dsize == 2 && dlow != 0) + { + mp_limb_t dsecond = dp[1]; + + if (dsecond <= dmask) + { + unsigned twos; + count_trailing_zeros (twos, dlow); + dlow = (dlow >> twos) | (dsecond << (GMP_NUMB_BITS-twos)); + ASSERT_LIMB (dlow); + + /* dlow will be odd here, so the test for it even under cong_1 + is unnecessary, but the rest of that code is wanted. */ + goto cong_1; + } + } + } + + TMP_MARK; + xp = TMP_ALLOC_LIMBS (asize+1); + + /* calculate abs(a-c) */ + if (sign >= 0) + { + /* same signs, subtract */ + if (asize > csize || mpn_cmp (ap, cp, asize) >= 0) + ASSERT_NOCARRY (mpn_sub (xp, ap, asize, cp, csize)); + else + ASSERT_NOCARRY (mpn_sub_n (xp, cp, ap, asize)); + MPN_NORMALIZE (xp, asize); + } + else + { + /* different signs, add */ + mp_limb_t carry; + carry = mpn_add (xp, ap, asize, cp, csize); + xp[asize] = carry; + asize += (carry != 0); + } + + result = mpn_divisible_p (xp, asize, dp, dsize); + + TMP_FREE; + return result; +} diff --git a/gmp-6.3.0/mpz/cong_2exp.c b/gmp-6.3.0/mpz/cong_2exp.c new file mode 100644 index 0000000..9de9645 --- /dev/null +++ b/gmp-6.3.0/mpz/cong_2exp.c @@ -0,0 +1,149 @@ +/* mpz_congruent_2exp_p -- test congruence of mpz mod 2^n. + +Copyright 2001, 2002, 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +int +mpz_congruent_2exp_p (mpz_srcptr a, mpz_srcptr c, mp_bitcnt_t d) __GMP_NOTHROW +{ + mp_size_t i, dlimbs; + unsigned dbits; + mp_ptr ap, cp; + mp_limb_t dmask, alimb, climb, sum; + mp_size_t as, cs, asize, csize; + + as = SIZ(a); + asize = ABS(as); + + cs = SIZ(c); + csize = ABS(cs); + + if (asize < csize) + { + MPZ_SRCPTR_SWAP (a, c); + MP_SIZE_T_SWAP (asize, csize); + } + + dlimbs = d / GMP_NUMB_BITS; + dbits = d % GMP_NUMB_BITS; + dmask = (CNST_LIMB(1) << dbits) - 1; + + ap = PTR(a); + cp = PTR(c); + + if (csize == 0) + goto a_zeros; + + if ((cs ^ as) >= 0) + { + /* same signs, direct comparison */ + + /* a==c for limbs in common */ + if (mpn_cmp (ap, cp, MIN (csize, dlimbs)) != 0) + return 0; + + /* if that's all of dlimbs, then a==c for remaining bits */ + if (csize > dlimbs) + return ((ap[dlimbs]-cp[dlimbs]) & dmask) == 0; + + a_zeros: + /* a remains, need all zero bits */ + + /* if d covers all of a and c, then must be exactly equal */ + if (asize <= dlimbs) + return asize == csize; + + /* whole limbs zero */ + for (i = csize; i < dlimbs; i++) + if (ap[i] != 0) + return 0; + + /* partial limb zero */ + return (ap[dlimbs] & dmask) == 0; + } + else + { + /* different signs, negated comparison */ + + /* common low zero limbs, stopping at first non-zeros, which must + match twos complement */ + i = 0; + do + { + ASSERT (i < csize); /* always have a non-zero limb on c */ + alimb = ap[i]; + climb = cp[i]; + sum = (alimb + climb) & GMP_NUMB_MASK; + + if (i >= dlimbs) + return (sum & dmask) == 0; + ++i; + + /* require both zero, or first non-zeros as twos-complements */ + if (sum != 0) + return 0; + } while (alimb == 0); + + /* further limbs matching as ones-complement */ + for (; i < csize; ++i) + { + alimb = ap[i]; + climb = cp[i]; + sum = alimb ^ climb ^ GMP_NUMB_MASK; + + if (i >= dlimbs) + return (sum & dmask) == 0; + + if (sum != 0) + return 0; + } + + /* no more c, so require all 1 bits in a */ + + if (asize < dlimbs) + return 0; /* not enough a */ + + /* whole limbs */ + for ( ; i < dlimbs; i++) + if (ap[i] != GMP_NUMB_MAX) + return 0; + + /* if only whole limbs, no further fetches from a */ + if (dbits == 0) + return 1; + + /* need enough a */ + if (asize == dlimbs) + return 0; + + return ((ap[dlimbs]+1) & dmask) == 0; + } +} diff --git a/gmp-6.3.0/mpz/cong_ui.c b/gmp-6.3.0/mpz/cong_ui.c new file mode 100644 index 0000000..6f86c23 --- /dev/null +++ b/gmp-6.3.0/mpz/cong_ui.c @@ -0,0 +1,115 @@ +/* mpz_congruent_ui_p -- test congruence of mpz and ulong. + +Copyright 2000-2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* There's some explicit checks for c GMP_NUMB_MAX || cu > GMP_NUMB_MAX) + { + mp_limb_t climbs[2], dlimbs[2]; + mpz_t cz, dz; + + ALLOC(cz) = 2; + PTR(cz) = climbs; + ALLOC(dz) = 2; + PTR(dz) = dlimbs; + + mpz_set_ui (cz, cu); + mpz_set_ui (dz, du); + return mpz_congruent_p (a, cz, dz); + } + + /* NEG_MOD works on limbs, so convert ulong to limb */ + c = cu; + d = du; + + if (asize < 0) + { + asize = -asize; + NEG_MOD (c, c, d); + } + + ap = PTR (a); + + if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) + { + r = mpn_mod_1 (ap, asize, d); + if (c < d) + return r == c; + else + return r == (c % d); + } + + if ((d & 1) == 0) + { + /* Strip low zero bits to get odd d required by modexact. If + d==e*2^n then a==c mod d if and only if both a==c mod 2^n + and a==c mod e. */ + + unsigned twos; + + if ((ap[0]-c) & LOW_ZEROS_MASK (d)) + return 0; + + count_trailing_zeros (twos, d); + d >>= twos; + } + + r = mpn_modexact_1c_odd (ap, asize, d, c); + return r == 0 || r == d; +} diff --git a/gmp-6.3.0/mpz/dive_ui.c b/gmp-6.3.0/mpz/dive_ui.c new file mode 100644 index 0000000..c859b96 --- /dev/null +++ b/gmp-6.3.0/mpz/dive_ui.c @@ -0,0 +1,68 @@ +/* mpz_divexact_ui -- exact division mpz by ulong. + +Copyright 2001, 2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_divexact_ui (mpz_ptr dst, mpz_srcptr src, unsigned long divisor) +{ + mp_size_t size, abs_size; + mp_ptr dst_ptr; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + /* For nails don't try to be clever if d is bigger than a limb, just fake + up an mpz_t and go to the main mpz_divexact. */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dlimbs[2]; + mpz_t dz; + ALLOC(dz) = 2; + PTR(dz) = dlimbs; + mpz_set_ui (dz, divisor); + mpz_divexact (dst, src, dz); + return; + } + + size = SIZ(src); + if (size == 0) + { + SIZ(dst) = 0; + return; + } + abs_size = ABS (size); + + dst_ptr = MPZ_REALLOC (dst, abs_size); + + MPN_DIVREM_OR_DIVEXACT_1 (dst_ptr, PTR(src), abs_size, (mp_limb_t) divisor); + abs_size -= (dst_ptr[abs_size-1] == 0); + SIZ(dst) = (size >= 0 ? abs_size : -abs_size); +} diff --git a/gmp-6.3.0/mpz/divegcd.c b/gmp-6.3.0/mpz/divegcd.c new file mode 100644 index 0000000..dc236c3 --- /dev/null +++ b/gmp-6.3.0/mpz/divegcd.c @@ -0,0 +1,156 @@ +/* mpz_divexact_gcd -- exact division optimized for GCDs. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE AND ARE ALMOST CERTAIN TO + BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES. + +Copyright 2000, 2005, 2011, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* Set q to a/d, expecting d to be from a GCD and therefore usually small. + + The distribution of GCDs of random numbers can be found in Knuth volume 2 + section 4.5.2 theorem D. + + GCD chance + 1 60.8% + 2^k 20.2% (1<=k<32) + 3*2^k 9.0% (1<=k<32) + other 10.1% + + Only the low limb is examined for optimizations, since GCDs bigger than + 2^32 (or 2^64) will occur very infrequently. + + Future: This could change to an mpn_divexact_gcd, possibly partly + inlined, if/when the relevant mpq functions change to an mpn based + implementation. */ + + +#if GMP_NUMB_BITS % 2 == 0 +static void +mpz_divexact_by3 (mpz_ptr q, mpz_srcptr a) +{ + mp_size_t size = SIZ(a); + mp_size_t abs_size = ABS(size); + mp_ptr qp; + + qp = MPZ_REALLOC (q, abs_size); + + mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 3); + + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size>0 ? abs_size : -abs_size); +} +#endif + +#if GMP_NUMB_BITS % 4 == 0 +static void +mpz_divexact_by5 (mpz_ptr q, mpz_srcptr a) +{ + mp_size_t size = SIZ(a); + mp_size_t abs_size = ABS(size); + mp_ptr qp; + + qp = MPZ_REALLOC (q, abs_size); + + mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 5); + + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size>0 ? abs_size : -abs_size); +} +#endif + +static void +mpz_divexact_limb (mpz_ptr q, mpz_srcptr a, mp_limb_t d) +{ + mp_size_t size = SIZ(a); + mp_size_t abs_size = ABS(size); + mp_ptr qp; + + qp = MPZ_REALLOC (q, abs_size); + + MPN_DIVREM_OR_DIVEXACT_1 (qp, PTR(a), abs_size, d); + + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size > 0 ? abs_size : -abs_size); +} + +void +mpz_divexact_gcd (mpz_ptr q, mpz_srcptr a, mpz_srcptr d) +{ + ASSERT (mpz_sgn (d) > 0); + + if (SIZ(a) == 0) + { + SIZ(q) = 0; + return; + } + + if (SIZ(d) == 1) + { + mp_limb_t dl = PTR(d)[0]; + int twos; + + if ((dl & 1) == 0) + { + count_trailing_zeros (twos, dl); + dl >>= twos; + mpz_tdiv_q_2exp (q, a, twos); + a = q; + } + + if (dl == 1) + { + if (q != a) + mpz_set (q, a); + return; + } +#if GMP_NUMB_BITS % 2 == 0 + if (dl == 3) + { + mpz_divexact_by3 (q, a); + return; + } +#endif +#if GMP_NUMB_BITS % 4 == 0 + if (dl == 5) + { + mpz_divexact_by5 (q, a); + return; + } +#endif + + mpz_divexact_limb (q, a, dl); + return; + } + + mpz_divexact (q, a, d); +} diff --git a/gmp-6.3.0/mpz/divexact.c b/gmp-6.3.0/mpz/divexact.c new file mode 100644 index 0000000..8336819 --- /dev/null +++ b/gmp-6.3.0/mpz/divexact.c @@ -0,0 +1,89 @@ +/* mpz_divexact -- finds quotient when known that quot * den == num && den != 0. + +Contributed to the GNU project by Niels Möller. + +Copyright 1991, 1993-1998, 2000-2002, 2005-2007, 2009, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#include "gmp-impl.h" + +void +mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den) +{ + mp_ptr qp; + mp_size_t qn; + mp_srcptr np, dp; + mp_size_t nn, dn; + TMP_DECL; + +#if WANT_ASSERT + { + mpz_t rem; + mpz_init (rem); + mpz_tdiv_r (rem, num, den); + ASSERT (SIZ(rem) == 0); + mpz_clear (rem); + } +#endif + + nn = ABSIZ (num); + dn = ABSIZ (den); + + if (nn < dn) + { + /* This special case avoids segfaults below when the function is + incorrectly called with |N| < |D|, N != 0. It also handles the + well-defined case N = 0. */ + SIZ(quot) = 0; + return; + } + + qn = nn - dn + 1; + + TMP_MARK; + + if (quot == num || quot == den) + qp = TMP_ALLOC_LIMBS (qn); + else + qp = MPZ_NEWALLOC (quot, qn); + + np = PTR(num); + dp = PTR(den); + + mpn_divexact (qp, np, nn, dp, dn); + MPN_NORMALIZE (qp, qn); + + if (qp != PTR(quot)) + MPN_COPY (MPZ_NEWALLOC (quot, qn), qp, qn); + + SIZ(quot) = (SIZ(num) ^ SIZ(den)) >= 0 ? qn : -qn; + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/divis.c b/gmp-6.3.0/mpz/divis.c new file mode 100644 index 0000000..35429a7 --- /dev/null +++ b/gmp-6.3.0/mpz/divis.c @@ -0,0 +1,43 @@ +/* mpz_divisible_p -- mpz by mpz divisibility test + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_divisible_p (mpz_srcptr a, mpz_srcptr d) +{ + mp_size_t dsize = SIZ(d); + mp_size_t asize = SIZ(a); + + if (UNLIKELY (dsize == 0)) + return (asize == 0); + + return mpn_divisible_p (PTR(a), ABS(asize), PTR(d), ABS(dsize)); +} diff --git a/gmp-6.3.0/mpz/divis_2exp.c b/gmp-6.3.0/mpz/divis_2exp.c new file mode 100644 index 0000000..4ecb0c0 --- /dev/null +++ b/gmp-6.3.0/mpz/divis_2exp.c @@ -0,0 +1,60 @@ +/* mpz_divisible_2exp_p -- mpz by 2^n divisibility test + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +int +mpz_divisible_2exp_p (mpz_srcptr a, mp_bitcnt_t d) __GMP_NOTHROW +{ + mp_size_t i, dlimbs; + unsigned dbits; + mp_ptr ap; + mp_limb_t dmask; + mp_size_t asize; + + asize = ABSIZ(a); + dlimbs = d / GMP_NUMB_BITS; + + /* if d covers the whole of a, then only a==0 is divisible */ + if (asize <= dlimbs) + return asize == 0; + + /* whole limbs must be zero */ + ap = PTR(a); + for (i = 0; i < dlimbs; i++) + if (ap[i] != 0) + return 0; + + /* left over bits must be zero */ + dbits = d % GMP_NUMB_BITS; + dmask = (CNST_LIMB(1) << dbits) - 1; + return (ap[dlimbs] & dmask) == 0; +} diff --git a/gmp-6.3.0/mpz/divis_ui.c b/gmp-6.3.0/mpz/divis_ui.c new file mode 100644 index 0000000..b24c7dc --- /dev/null +++ b/gmp-6.3.0/mpz/divis_ui.c @@ -0,0 +1,80 @@ +/* mpz_divisible_ui_p -- mpz by ulong divisibility test. + +Copyright 2000-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +int +mpz_divisible_ui_p (mpz_srcptr a, unsigned long d) +{ + mp_size_t asize; + mp_ptr ap; + unsigned twos; + + asize = SIZ(a); + if (UNLIKELY (d == 0)) + return (asize == 0); + + if (asize == 0) /* 0 divisible by any d */ + return 1; + + /* For nails don't try to be clever if d is bigger than a limb, just fake + up an mpz_t and go to the main mpz_divisible_p. */ + if (d > GMP_NUMB_MAX) + { + mp_limb_t dlimbs[2]; + mpz_t dz; + ALLOC(dz) = 2; + PTR(dz) = dlimbs; + mpz_set_ui (dz, d); + return mpz_divisible_p (a, dz); + } + + ap = PTR(a); + asize = ABS(asize); /* ignore sign of a */ + + if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD)) + return mpn_mod_1 (ap, asize, (mp_limb_t) d) == 0; + + if (! (d & 1)) + { + /* Strip low zero bits to get odd d required by modexact. If d==e*2^n + and a is divisible by 2^n and by e, then it's divisible by d. */ + + if ((ap[0] & LOW_ZEROS_MASK (d)) != 0) + return 0; + + count_trailing_zeros (twos, (mp_limb_t) d); + d >>= twos; + } + + return mpn_modexact_1_odd (ap, asize, (mp_limb_t) d) == 0; +} diff --git a/gmp-6.3.0/mpz/dump.c b/gmp-6.3.0/mpz/dump.c new file mode 100644 index 0000000..6135ddd --- /dev/null +++ b/gmp-6.3.0/mpz/dump.c @@ -0,0 +1,48 @@ +/* mpz_dump - Dump an integer to stdout. + + THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS NOT SAFE TO + CALL THIS FUNCTION DIRECTLY. IN FACT, IT IS ALMOST GUARANTEED THAT THIS + FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. + + +Copyright 1999-2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include /* for strlen */ +#include "gmp-impl.h" + +void +mpz_dump (mpz_srcptr u) +{ + char *str; + + str = mpz_get_str (0, 10, u); + printf ("%s\n", str); + (*__gmp_free_func) (str, strlen (str) + 1); +} diff --git a/gmp-6.3.0/mpz/export.c b/gmp-6.3.0/mpz/export.c new file mode 100644 index 0000000..2dacd69 --- /dev/null +++ b/gmp-6.3.0/mpz/export.c @@ -0,0 +1,189 @@ +/* mpz_export -- create word data from mpz. + +Copyright 2002, 2003, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" +#include "longlong.h" + + +#if HAVE_LIMB_BIG_ENDIAN +#define HOST_ENDIAN 1 +#endif +#if HAVE_LIMB_LITTLE_ENDIAN +#define HOST_ENDIAN (-1) +#endif +#ifndef HOST_ENDIAN +static const mp_limb_t endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1; +#define HOST_ENDIAN (* (signed char *) &endian_test) +#endif + +void * +mpz_export (void *data, size_t *countp, int order, + size_t size, int endian, size_t nail, mpz_srcptr z) +{ + mp_size_t zsize; + mp_srcptr zp; + size_t count, dummy; + unsigned long numb; + unsigned align; + + ASSERT (order == 1 || order == -1); + ASSERT (endian == 1 || endian == 0 || endian == -1); + ASSERT (nail <= 8*size); + ASSERT (nail < 8*size || SIZ(z) == 0); /* nail < 8*size+(SIZ(z)==0) */ + + if (countp == NULL) + countp = &dummy; + + zsize = SIZ(z); + if (zsize == 0) + { + *countp = 0; + return data; + } + + zsize = ABS (zsize); + zp = PTR(z); + numb = 8*size - nail; + MPN_SIZEINBASE_2EXP (count, zp, zsize, numb); + *countp = count; + + if (data == NULL) + data = (*__gmp_allocate_func) (count*size); + + if (endian == 0) + endian = HOST_ENDIAN; + + align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t); + + if (nail == GMP_NAIL_BITS) + { + if (size == sizeof (mp_limb_t) && align == 0) + { + if (order == -1 && endian == HOST_ENDIAN) + { + MPN_COPY ((mp_ptr) data, zp, (mp_size_t) count); + return data; + } + if (order == 1 && endian == HOST_ENDIAN) + { + MPN_REVERSE ((mp_ptr) data, zp, (mp_size_t) count); + return data; + } + + if (order == -1 && endian == -HOST_ENDIAN) + { + MPN_BSWAP ((mp_ptr) data, zp, (mp_size_t) count); + return data; + } + if (order == 1 && endian == -HOST_ENDIAN) + { + MPN_BSWAP_REVERSE ((mp_ptr) data, zp, (mp_size_t) count); + return data; + } + } + } + + { + mp_limb_t limb, wbitsmask; + size_t i, numb; + mp_size_t j, wbytes, woffset; + unsigned char *dp; + int lbits, wbits; + mp_srcptr zend; + + numb = size * 8 - nail; + + /* whole bytes per word */ + wbytes = numb / 8; + + /* possible partial byte */ + wbits = numb % 8; + wbitsmask = (CNST_LIMB(1) << wbits) - 1; + + /* offset to get to the next word */ + woffset = (endian >= 0 ? size : - (mp_size_t) size) + + (order < 0 ? size : - (mp_size_t) size); + + /* least significant byte */ + dp = (unsigned char *) data + + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0); + +#define EXTRACT(N, MASK) \ + do { \ + if (lbits >= (N)) \ + { \ + *dp = limb MASK; \ + limb >>= (N); \ + lbits -= (N); \ + } \ + else \ + { \ + mp_limb_t newlimb; \ + newlimb = (zp == zend ? 0 : *zp++); \ + *dp = (limb | (newlimb << lbits)) MASK; \ + limb = newlimb >> ((N)-lbits); \ + lbits += GMP_NUMB_BITS - (N); \ + } \ + } while (0) + + zend = zp + zsize; + lbits = 0; + limb = 0; + for (i = 0; i < count; i++) + { + for (j = 0; j < wbytes; j++) + { + EXTRACT (8, + 0); + dp -= endian; + } + if (wbits != 0) + { + EXTRACT (wbits, & wbitsmask); + dp -= endian; + j++; + } + for ( ; j < size; j++) + { + *dp = '\0'; + dp -= endian; + } + dp += woffset; + } + + ASSERT (zp == PTR(z) + ABSIZ(z)); + + /* low byte of word after most significant */ + ASSERT (dp == (unsigned char *) data + + (order < 0 ? count*size : - (mp_size_t) size) + + (endian >= 0 ? (mp_size_t) size - 1 : 0)); + } + return data; +} diff --git a/gmp-6.3.0/mpz/fac_ui.c b/gmp-6.3.0/mpz/fac_ui.c new file mode 100644 index 0000000..a7998b3 --- /dev/null +++ b/gmp-6.3.0/mpz/fac_ui.c @@ -0,0 +1,122 @@ +/* mpz_fac_ui(RESULT, N) -- Set RESULT to N!. + +Contributed to the GNU project by Marco Bodrato. + +Copyright 1991, 1993-1995, 2000-2003, 2011, 2012, 2015, 2021 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +#if TUNE_PROGRAM_BUILD +#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD_LIMIT-1)+1)) +#else +#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_ODD_THRESHOLD)+1)) +#endif + +/* Computes n!, the factorial of n. + WARNING: it assumes that n fits in a limb! + */ +void +mpz_fac_ui (mpz_ptr x, unsigned long n) +{ + static const mp_limb_t table[] = { ONE_LIMB_FACTORIAL_TABLE }; + + ASSERT (n <= GMP_NUMB_MAX); + + if (n < numberof (table)) + { + MPZ_NEWALLOC (x, 1)[0] = table[n]; + SIZ (x) = 1; + } + else if (BELOW_THRESHOLD (n, FAC_ODD_THRESHOLD)) + { + mp_limb_t prod, max_prod; + mp_size_t j; + mp_ptr factors; + mp_limb_t fac, diff = n - numberof (table); + TMP_SDECL; + + TMP_SMARK; + factors = TMP_SALLOC_LIMBS (2 + diff / FACTORS_PER_LIMB); + + factors[0] = table[numberof (table)-1]; + j = 1; + if ((diff & 1) == 0) + { + prod = n; + /* if (diff != 0) */ + fac = --n * numberof (table); + } + else + { + prod = n * numberof (table); + fac = prod + --diff; + } + +#if TUNE_PROGRAM_BUILD + max_prod = GMP_NUMB_MAX / (FAC_DSC_THRESHOLD_LIMIT * FAC_DSC_THRESHOLD_LIMIT); +#else + max_prod = GMP_NUMB_MAX / + (((FAC_ODD_THRESHOLD + numberof (table) + 1) / 2) * + ((FAC_ODD_THRESHOLD + numberof (table)) / 2)); +#endif + for (;diff != 0; fac += (diff -= 2)) + FACTOR_LIST_STORE (fac, prod, max_prod, factors, j); + + factors[j++] = prod; + mpz_prodlimbs (x, factors, j); + + TMP_SFREE; + } + else + { + mp_limb_t count; + mpz_oddfac_1 (x, n, 0); + if (n <= TABLE_LIMIT_2N_MINUS_POPC_2N) + count = __gmp_fac2cnt_table[n / 2 - 1]; + else + { + popc_limb (count, n); + count = n - count; + } + mpz_mul_2exp (x, x, count); + } +} + +#undef FACTORS_PER_LIMB +#undef FACTOR_LIST_STORE diff --git a/gmp-6.3.0/mpz/fdiv_q.c b/gmp-6.3.0/mpz/fdiv_q.c new file mode 100644 index 0000000..f17023e --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_q.c @@ -0,0 +1,52 @@ +/* mpz_fdiv_q -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_fdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t dividend_size = SIZ (dividend); + mp_size_t divisor_size = SIZ (divisor); + mpz_t rem; + TMP_DECL; + + TMP_MARK; + + MPZ_TMP_INIT (rem, ABS (divisor_size)); + + mpz_tdiv_qr (quot, rem, dividend, divisor); + + if ((divisor_size ^ dividend_size) < 0 && SIZ (rem) != 0) + mpz_sub_ui (quot, quot, 1L); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/fdiv_q_ui.c b/gmp-6.3.0/mpz/fdiv_q_ui.c new file mode 100644 index 0000000..539f951 --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_q_ui.c @@ -0,0 +1,100 @@ +/* mpz_fdiv_q_ui -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_fdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + qp[0] = 0; + rl = np[0]; + qn = 1; /* a white lie, fixed below */ + } + else + { + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; + } + + if (rl != 0 && ns < 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + + if (rl != 0 && ns < 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/fdiv_qr.c b/gmp-6.3.0/mpz/fdiv_qr.c new file mode 100644 index 0000000..a0a6166 --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_qr.c @@ -0,0 +1,64 @@ +/* mpz_fdiv_qr -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_fdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t divisor_size = SIZ (divisor); + mp_size_t xsize; + mpz_t temp_divisor; /* N.B.: lives until function returns! */ + TMP_DECL; + + TMP_MARK; + + /* We need the original value of the divisor after the quotient and + remainder have been preliminary calculated. We have to copy it to + temporary space if it's the same variable as either QUOT or REM. */ + if (quot == divisor || rem == divisor) + { + MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); + mpz_set (temp_divisor, divisor); + divisor = temp_divisor; + } + + xsize = SIZ (dividend) ^ divisor_size;; + mpz_tdiv_qr (quot, rem, dividend, divisor); + + if (xsize < 0 && SIZ (rem) != 0) + { + mpz_sub_ui (quot, quot, 1L); + mpz_add (rem, rem, divisor); + } + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/fdiv_qr_ui.c b/gmp-6.3.0/mpz/fdiv_qr_ui.c new file mode 100644 index 0000000..984ca1c --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_qr_ui.c @@ -0,0 +1,116 @@ +/* mpz_fdiv_qr_ui -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_fdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp; + mp_size_t rn; + + rp = MPZ_REALLOC (rem, 2); + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + qp[0] = 0; + qn = 1; /* a white lie, fixed below */ + rl = np[0]; + rp[0] = rl; + } + else + { + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; + } + + if (rl != 0 && ns < 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + SIZ(rem) = rn; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + if (ns < 0) + { + mpn_incr_u (qp, (mp_limb_t) 1); + rl = divisor - rl; + } + + MPZ_NEWALLOC (rem, 1)[0] = rl; + SIZ(rem) = rl != 0; + } + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/fdiv_r.c b/gmp-6.3.0/mpz/fdiv_r.c new file mode 100644 index 0000000..c7a3c8e --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_r.c @@ -0,0 +1,59 @@ +/* mpz_fdiv_r -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_fdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t divisor_size = SIZ (divisor); + mpz_t temp_divisor; /* N.B.: lives until function returns! */ + TMP_DECL; + + TMP_MARK; + + /* We need the original value of the divisor after the remainder has been + preliminary calculated. We have to copy it to temporary space if it's + the same variable as REM. */ + if (rem == divisor) + { + MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); + mpz_set (temp_divisor, divisor); + divisor = temp_divisor; + } + + mpz_tdiv_r (rem, dividend, divisor); + + if ((divisor_size ^ SIZ (dividend)) < 0 && SIZ (rem) != 0) + mpz_add (rem, rem, divisor); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/fdiv_r_ui.c b/gmp-6.3.0/mpz/fdiv_r_ui.c new file mode 100644 index 0000000..f2df8a8 --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_r_ui.c @@ -0,0 +1,107 @@ +/* mpz_fdiv_r_ui -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_fdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp, qp; + mp_size_t rn; + TMP_DECL; + + rp = MPZ_REALLOC (rem, 2); + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + rp[0] = rl; + } + else + { + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + } + + if (rl != 0 && ns < 0) + { + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + SIZ(rem) = rn; + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + if (ns < 0) + rl = divisor - rl; + + MPZ_NEWALLOC (rem, 1)[0] = rl; + SIZ(rem) = 1; + } + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/fdiv_ui.c b/gmp-6.3.0/mpz/fdiv_ui.c new file mode 100644 index 0000000..f0aacdb --- /dev/null +++ b/gmp-6.3.0/mpz/fdiv_ui.c @@ -0,0 +1,100 @@ +/* mpz_fdiv_ui -- Division rounding the quotient towards -infinity. + The remainder gets the same sign as the denominator. + +Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_fdiv_ui (mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + mp_ptr qp; + mp_size_t rn; + TMP_DECL; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + rp[0] = rl; + } + else + { + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + } + + if (rl != 0 && ns < 0) + { + rl = divisor - rl; + rp[0] = rl & GMP_NUMB_MASK; + rp[1] = rl >> GMP_NUMB_BITS; + } + + rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + if (rl == 0) + ; + else + { + if (ns < 0) + rl = divisor - rl; + } + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/fib2_ui.c b/gmp-6.3.0/mpz/fib2_ui.c new file mode 100644 index 0000000..ea26227 --- /dev/null +++ b/gmp-6.3.0/mpz/fib2_ui.c @@ -0,0 +1,58 @@ +/* mpz_fib2_ui -- calculate Fibonacci numbers. + +Copyright 2001, 2012, 2014, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + + +void +mpz_fib2_ui (mpz_ptr fn, mpz_ptr fnsub1, unsigned long n) +{ + mp_ptr fp, f1p; + mp_size_t size; + + if (n <= FIB_TABLE_LIMIT) + { + MPZ_NEWALLOC (fn, 1)[0] = FIB_TABLE (n); + SIZ(fn) = (n != 0); /* F[0]==0, others are !=0 */ + MPZ_NEWALLOC (fnsub1, 1)[0] = FIB_TABLE ((int) n - 1); + SIZ(fnsub1) = (n != 1); /* F[1-1]==0, others are !=0 */ + return; + } + + size = MPN_FIB2_SIZE (n); + fp = MPZ_NEWALLOC (fn, size); + f1p = MPZ_NEWALLOC (fnsub1, size); + + size = mpn_fib2_ui (fp, f1p, n); + + SIZ(fn) = size; + SIZ(fnsub1) = size - (f1p[size-1] == 0); +} diff --git a/gmp-6.3.0/mpz/fib_ui.c b/gmp-6.3.0/mpz/fib_ui.c new file mode 100644 index 0000000..a65f3c9 --- /dev/null +++ b/gmp-6.3.0/mpz/fib_ui.c @@ -0,0 +1,158 @@ +/* mpz_fib_ui -- calculate Fibonacci numbers. + +Copyright 2000-2002, 2005, 2012, 2014, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + + +/* change to "#define TRACE(x) x" to get some traces */ +#define TRACE(x) + + +/* In the F[2k+1] below for k odd, the -2 won't give a borrow from the low + limb because the result F[2k+1] is an F[4m+3] and such numbers are always + == 1, 2 or 5 mod 8, whereas an underflow would leave 6 or 7. (This is + the same as in mpn_fib2_ui.) + + In the F[2k+1] for k even, the +2 won't give a carry out of the low limb + in normal circumstances. This is an F[4m+1] and we claim that F[3*2^b+1] + == 1 mod 2^b is the first F[4m+1] congruent to 0 or 1 mod 2^b, and hence + if n < 2^GMP_NUMB_BITS then F[n] cannot have a low limb of 0 or 1. No + proof for this claim, but it's been verified up to b==32 and has such a + nice pattern it must be true :-). Of interest is that F[3*2^b] == 0 mod + 2^(b+1) seems to hold too. + + When n >= 2^GMP_NUMB_BITS, which can arise in a nails build, then the low + limb of F[4m+1] can certainly be 1, and an mpn_add_1 must be used. */ + +void +mpz_fib_ui (mpz_ptr fn, unsigned long n) +{ + mp_ptr fp, xp, yp; + mp_size_t size, xalloc; + unsigned long n2; + mp_limb_t c; + TMP_DECL; + + if (n <= FIB_TABLE_LIMIT) + { + MPZ_NEWALLOC (fn, 1)[0] = FIB_TABLE (n); + SIZ(fn) = (n != 0); /* F[0]==0, others are !=0 */ + return; + } + + n2 = n/2; + xalloc = MPN_FIB2_SIZE (n2) + 1; + fp = MPZ_NEWALLOC (fn, 2 * xalloc); + + TMP_MARK; + TMP_ALLOC_LIMBS_2 (xp,xalloc, yp,xalloc); + size = mpn_fib2_ui (xp, yp, n2); + + TRACE (printf ("mpz_fib_ui last step n=%lu size=%ld bit=%lu\n", + n >> 1, size, n&1); + mpn_trace ("xp", xp, size); + mpn_trace ("yp", yp, size)); + + if (n & 1) + { + /* F[2k+1] = (2F[k]+F[k-1])*(2F[k]-F[k-1]) + 2*(-1)^k */ + mp_size_t xsize, ysize; + +#if HAVE_NATIVE_mpn_add_n_sub_n + xp[size] = mpn_lshift (xp, xp, size, 1); + yp[size] = 0; + ASSERT_NOCARRY (mpn_add_n_sub_n (xp, yp, xp, yp, size+1)); + xsize = size + (xp[size] != 0); + ASSERT (yp[size] <= 1); + ysize = size + yp[size]; +#else + mp_limb_t c2; + + c2 = mpn_lshift (fp, xp, size, 1); + c = c2 + mpn_add_n (xp, fp, yp, size); + xp[size] = c; + xsize = size + (c != 0); + c2 -= mpn_sub_n (yp, fp, yp, size); + yp[size] = c2; + ASSERT (c2 <= 1); + ysize = size + c2; +#endif + + size = xsize + ysize; + c = mpn_mul (fp, xp, xsize, yp, ysize); + +#if GMP_NUMB_BITS >= BITS_PER_ULONG + /* no overflow, see comments above */ + ASSERT (n & 2 ? fp[0] >= 2 : fp[0] <= GMP_NUMB_MAX-2); + fp[0] += (n & 2 ? -CNST_LIMB(2) : CNST_LIMB(2)); +#else + if (n & 2) + { + ASSERT (fp[0] >= 2); + fp[0] -= 2; + } + else + { + ASSERT (c != GMP_NUMB_MAX); /* because it's the high of a mul */ + c += mpn_add_1 (fp, fp, size-1, CNST_LIMB(2)); + fp[size-1] = c; + } +#endif + } + else + { + /* F[2k] = F[k]*(F[k]+2F[k-1]) */ + + mp_size_t xsize, ysize; +#if HAVE_NATIVE_mpn_addlsh1_n + c = mpn_addlsh1_n (yp, xp, yp, size); +#else + c = mpn_lshift (yp, yp, size, 1); + c += mpn_add_n (yp, yp, xp, size); +#endif + yp[size] = c; + xsize = size; + ysize = size + (c != 0); + size += ysize; + c = mpn_mul (fp, yp, ysize, xp, xsize); + } + + /* one or two high zeros */ + size -= (c == 0); + size -= (fp[size-1] == 0); + SIZ(fn) = size; + + TRACE (printf ("done special, size=%ld\n", size); + mpn_trace ("fp ", fp, size)); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/fits_s.h b/gmp-6.3.0/mpz/fits_s.h new file mode 100644 index 0000000..9fd6a0b --- /dev/null +++ b/gmp-6.3.0/mpz/fits_s.h @@ -0,0 +1,60 @@ +/* int mpz_fits_X_p (mpz_t z) -- test whether z fits signed type X. + +Copyright 1997, 2000-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +int +FUNCTION (mpz_srcptr z) __GMP_NOTHROW +{ + mp_size_t n = SIZ(z); + mp_ptr p = PTR(z); + mp_limb_t limb = p[0]; + + if (n == 0) + return 1; + if (n == 1) + return limb <= MAXIMUM; + if (n == -1) + return limb <= NEG_CAST (mp_limb_t, MINIMUM); +#if GMP_NAIL_BITS != 0 + { + if ((p[1] >> GMP_NAIL_BITS) == 0) + { + limb += p[1] << GMP_NUMB_BITS; + if (n == 2) + return limb <= MAXIMUM; + if (n == -2) + return limb <= NEG_CAST (mp_limb_t, MINIMUM); + } + } +#endif + return 0; +} diff --git a/gmp-6.3.0/mpz/fits_sint.c b/gmp-6.3.0/mpz/fits_sint.c new file mode 100644 index 0000000..d548c45 --- /dev/null +++ b/gmp-6.3.0/mpz/fits_sint.c @@ -0,0 +1,36 @@ +/* int mpz_fits_sint_p (mpz_t z) -- test whether z fits an int. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define FUNCTION mpz_fits_sint_p +#define MAXIMUM INT_MAX +#define MINIMUM INT_MIN + +#include "fits_s.h" diff --git a/gmp-6.3.0/mpz/fits_slong.c b/gmp-6.3.0/mpz/fits_slong.c new file mode 100644 index 0000000..9306a00 --- /dev/null +++ b/gmp-6.3.0/mpz/fits_slong.c @@ -0,0 +1,36 @@ +/* int mpz_fits_slong_p (mpz_t z) -- test whether z fits a long. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define FUNCTION mpz_fits_slong_p +#define MAXIMUM LONG_MAX +#define MINIMUM LONG_MIN + +#include "fits_s.h" diff --git a/gmp-6.3.0/mpz/fits_sshort.c b/gmp-6.3.0/mpz/fits_sshort.c new file mode 100644 index 0000000..431d6b0 --- /dev/null +++ b/gmp-6.3.0/mpz/fits_sshort.c @@ -0,0 +1,36 @@ +/* int mpz_fits_sshort_p (mpz_t z) -- test whether z fits a short. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define FUNCTION mpz_fits_sshort_p +#define MAXIMUM SHRT_MAX +#define MINIMUM SHRT_MIN + +#include "fits_s.h" diff --git a/gmp-6.3.0/mpz/fits_uint.c b/gmp-6.3.0/mpz/fits_uint.c new file mode 100644 index 0000000..6becc8b --- /dev/null +++ b/gmp-6.3.0/mpz/fits_uint.c @@ -0,0 +1,33 @@ +/* mpz_fits_uint_p -- test whether z fits an unsigned int. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_fits_uint_p 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/fits_ulong.c b/gmp-6.3.0/mpz/fits_ulong.c new file mode 100644 index 0000000..c70886b --- /dev/null +++ b/gmp-6.3.0/mpz/fits_ulong.c @@ -0,0 +1,33 @@ +/* mpz_fits_ulong_p -- test whether z fits an unsigned long. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_fits_ulong_p 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/fits_ushort.c b/gmp-6.3.0/mpz/fits_ushort.c new file mode 100644 index 0000000..16873d6 --- /dev/null +++ b/gmp-6.3.0/mpz/fits_ushort.c @@ -0,0 +1,33 @@ +/* mpz_fits_ushort_p -- test whether z fits an unsigned short. + +Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_fits_ushort_p 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/gcd.c b/gmp-6.3.0/mpz/gcd.c new file mode 100644 index 0000000..9557155 --- /dev/null +++ b/gmp-6.3.0/mpz/gcd.c @@ -0,0 +1,164 @@ +/* mpz/gcd.c: Calculate the greatest common divisor of two integers. + +Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2010, 2015, 2016 +Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +void +mpz_gcd (mpz_ptr g, mpz_srcptr u, mpz_srcptr v) +{ + unsigned long int g_zero_bits, u_zero_bits, v_zero_bits; + mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs; + mp_ptr tp; + mp_ptr up; + mp_size_t usize; + mp_ptr vp; + mp_size_t vsize; + mp_size_t gsize; + TMP_DECL; + + up = PTR(u); + usize = ABSIZ (u); + vp = PTR(v); + vsize = ABSIZ (v); + /* GCD(0, V) == V. */ + if (usize == 0) + { + SIZ (g) = vsize; + if (g == v) + return; + tp = MPZ_NEWALLOC (g, vsize); + MPN_COPY (tp, vp, vsize); + return; + } + + /* GCD(U, 0) == U. */ + if (vsize == 0) + { + SIZ (g) = usize; + if (g == u) + return; + tp = MPZ_NEWALLOC (g, usize); + MPN_COPY (tp, up, usize); + return; + } + + if (usize == 1) + { + SIZ (g) = 1; + MPZ_NEWALLOC (g, 1)[0] = mpn_gcd_1 (vp, vsize, up[0]); + return; + } + + if (vsize == 1) + { + SIZ(g) = 1; + MPZ_NEWALLOC (g, 1)[0] = mpn_gcd_1 (up, usize, vp[0]); + return; + } + + TMP_MARK; + + /* Eliminate low zero bits from U and V and move to temporary storage. */ + tp = up; + while (*tp == 0) + tp++; + u_zero_limbs = tp - up; + usize -= u_zero_limbs; + count_trailing_zeros (u_zero_bits, *tp); + up = TMP_ALLOC_LIMBS (usize); + if (u_zero_bits != 0) + { + mpn_rshift (up, tp, usize, u_zero_bits); + usize -= up[usize - 1] == 0; + } + else + MPN_COPY (up, tp, usize); + + tp = vp; + while (*tp == 0) + tp++; + v_zero_limbs = tp - vp; + vsize -= v_zero_limbs; + count_trailing_zeros (v_zero_bits, *tp); + vp = TMP_ALLOC_LIMBS (vsize); + if (v_zero_bits != 0) + { + mpn_rshift (vp, tp, vsize, v_zero_bits); + vsize -= vp[vsize - 1] == 0; + } + else + MPN_COPY (vp, tp, vsize); + + if (u_zero_limbs > v_zero_limbs) + { + g_zero_limbs = v_zero_limbs; + g_zero_bits = v_zero_bits; + } + else + { + g_zero_limbs = u_zero_limbs; + if (u_zero_limbs < v_zero_limbs) + g_zero_bits = u_zero_bits; + else /* Equal. */ + g_zero_bits = MIN (u_zero_bits, v_zero_bits); + } + + /* Call mpn_gcd. The 2nd argument must not have more bits than the 1st. */ + vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1])) + ? mpn_gcd (vp, vp, vsize, up, usize) + : mpn_gcd (vp, up, usize, vp, vsize); + + /* Here G <-- V << (g_zero_limbs*GMP_LIMB_BITS + g_zero_bits). */ + gsize = vsize + g_zero_limbs; + if (g_zero_bits != 0) + { + mp_limb_t cy_limb; + gsize += (vp[vsize - 1] >> (GMP_NUMB_BITS - g_zero_bits)) != 0; + tp = MPZ_NEWALLOC (g, gsize); + MPN_ZERO (tp, g_zero_limbs); + + tp = tp + g_zero_limbs; + cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits); + if (cy_limb != 0) + tp[vsize] = cy_limb; + } + else + { + tp = MPZ_NEWALLOC (g, gsize); + MPN_ZERO (tp, g_zero_limbs); + MPN_COPY (tp + g_zero_limbs, vp, vsize); + } + + SIZ (g) = gsize; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/gcd_ui.c b/gmp-6.3.0/mpz/gcd_ui.c new file mode 100644 index 0000000..64aa46d --- /dev/null +++ b/gmp-6.3.0/mpz/gcd_ui.c @@ -0,0 +1,92 @@ +/* mpz_gcd_ui -- Calculate the greatest common divisor of two integers. + +Copyright 1994, 1996, 1999-2004, 2015, 2022 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + +unsigned long int +mpz_gcd_ui (mpz_ptr w, mpz_srcptr u, unsigned long int v) +{ + mp_size_t un; + mp_limb_t res; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (v > GMP_NUMB_MAX) + { + mpz_t vz, lw; + mp_limb_t vlimbs[2], wlimbs[2]; + + if (w == NULL) + { + PTR(lw) = wlimbs; + ALLOC(lw) = 2; + SIZ(lw) = 0; + w = lw; + } + vlimbs[0] = v & GMP_NUMB_MASK; + vlimbs[1] = v >> GMP_NUMB_BITS; + PTR(vz) = vlimbs; + SIZ(vz) = 2; + mpz_gcd (w, u, vz); + /* because v!=0 we will have w<=v hence fitting a ulong */ + ASSERT (mpz_fits_ulong_p (w)); + return mpz_get_ui (w); + } +#endif + + un = ABSIZ(u); + + if (un == 0) + res = v; + else if (v == 0) + { + if (w != NULL) + { + if (u != w) + { + MPZ_NEWALLOC (w, un); + MPN_COPY (PTR(w), PTR(u), un); + } + SIZ(w) = un; + } + /* Return u if it fits a ulong, otherwise 0. */ + res = PTR(u)[0]; + return (un == 1 && res <= ULONG_MAX ? res : 0); + } + else + res = mpn_gcd_1 (PTR(u), un, (mp_limb_t) v); + + if (w != NULL) + { + MPZ_NEWALLOC (w, 1)[0] = res; + SIZ(w) = res != 0; + } + return res; +} diff --git a/gmp-6.3.0/mpz/gcdext.c b/gmp-6.3.0/mpz/gcdext.c new file mode 100644 index 0000000..b1f73c2 --- /dev/null +++ b/gmp-6.3.0/mpz/gcdext.c @@ -0,0 +1,135 @@ +/* mpz_gcdext(g, s, t, a, b) -- Set G to gcd(a, b), and S and T such that + g = as + bt. + +Copyright 1991, 1993-1997, 2000, 2001, 2005, 2011, 2012, 2015 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + +void +mpz_gcdext (mpz_ptr g, mpz_ptr s, mpz_ptr t, mpz_srcptr a, mpz_srcptr b) +{ + mp_size_t asize, bsize; + mp_ptr tmp_ap, tmp_bp; + mp_size_t gsize, ssize, tmp_ssize; + mp_ptr gp, tmp_gp, tmp_sp; + TMP_DECL; + + /* mpn_gcdext requires that Usize >= Vsize. Therefore, we often + have to swap U and V. The computed cofactor will be the + "smallest" one, which is faster to produce. The wanted one will + be computed here; this is needed anyway when both are requested. */ + + asize = ABSIZ (a); + bsize = ABSIZ (b); + + ASSERT (s != NULL); + + if (asize < bsize) + { + MPZ_SRCPTR_SWAP (a, b); + MP_SIZE_T_SWAP (asize, bsize); + MPZ_PTR_SWAP (s, t); + } + + if (bsize == 0) + { + /* g = |a|, s = sgn(a), t = 0. */ + ssize = SIZ (a) >= 0 ? (asize != 0) : -1; + + if (g != NULL) + { + /* If g == a, then ALLOC(g) == ALLOC(a) >= asize, i.e. + the next MPZ_NEWALLOC returns the old PTR(a) .*/ + gp = MPZ_NEWALLOC (g, asize); + MPN_COPY (gp, PTR (a), asize); + SIZ (g) = asize; + } + if (t != NULL) + SIZ (t) = 0; + if (s != NULL) + { + SIZ (s) = ssize; + MPZ_NEWALLOC (s, 1)[0] = 1; + } + return; + } + + TMP_MARK; + + TMP_ALLOC_LIMBS_2 (tmp_gp, bsize, tmp_sp, asize + bsize + bsize + 1); + tmp_bp = tmp_sp + bsize + 1; + tmp_ap = tmp_bp + bsize; + MPN_COPY (tmp_ap, PTR (a), asize); + MPN_COPY (tmp_bp, PTR (b), bsize); + + gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, tmp_ap, asize, tmp_bp, bsize); + + ssize = ABS (tmp_ssize); + tmp_ssize = SIZ (a) >= 0 ? tmp_ssize : -tmp_ssize; + + if (t != NULL) + { + mpz_t x; + mpz_t gtmp, stmp; + + PTR (gtmp) = tmp_gp; + SIZ (gtmp) = gsize; + + PTR (stmp) = tmp_sp; + SIZ (stmp) = tmp_ssize; + + ASSERT (ssize <= bsize); /* ssize*2 + asize + 1 <= asize + bsize*2 + 1 */ + PTR (x) = tmp_sp + ssize; + ALLOC (x) = ssize + asize + 1; + + mpz_mul (x, stmp, a); + mpz_sub (x, gtmp, x); + mpz_divexact (t, x, b); + } + + if (s != NULL) + { + mp_ptr sp; + + sp = MPZ_NEWALLOC (s, ssize); + MPN_COPY (sp, tmp_sp, ssize); + SIZ (s) = tmp_ssize; + } + + if (g != NULL) + { + gp = MPZ_NEWALLOC (g, gsize); + MPN_COPY (gp, tmp_gp, gsize); + SIZ (g) = gsize; + } + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/get_d.c b/gmp-6.3.0/mpz/get_d.c new file mode 100644 index 0000000..61d4e36 --- /dev/null +++ b/gmp-6.3.0/mpz/get_d.c @@ -0,0 +1,43 @@ +/* double mpz_get_d (mpz_t src) -- Return the double approximation to SRC. + +Copyright 1996, 1997, 2000-2003 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +double +mpz_get_d (mpz_srcptr z) +{ + mp_size_t size; + + size = SIZ (z); + if (UNLIKELY (size == 0)) + return 0.0; + + return mpn_get_d (PTR (z), ABS (size), size, 0L); +} diff --git a/gmp-6.3.0/mpz/get_d_2exp.c b/gmp-6.3.0/mpz/get_d_2exp.c new file mode 100644 index 0000000..beb364a --- /dev/null +++ b/gmp-6.3.0/mpz/get_d_2exp.c @@ -0,0 +1,53 @@ +/* double mpz_get_d_2exp (signed long int *exp, mpz_t src). + +Copyright 2001, 2003, 2004, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +double +mpz_get_d_2exp (signed long int *exp2, mpz_srcptr src) +{ + mp_size_t size, abs_size; + mp_srcptr ptr; + long exp; + + size = SIZ(src); + if (UNLIKELY (size == 0)) + { + *exp2 = 0; + return 0.0; + } + + ptr = PTR(src); + abs_size = ABS(size); + MPN_SIZEINBASE_2EXP(exp, ptr, abs_size, 1); + *exp2 = exp; + return mpn_get_d (ptr, abs_size, size, -exp); +} diff --git a/gmp-6.3.0/mpz/get_si.c b/gmp-6.3.0/mpz/get_si.c new file mode 100644 index 0000000..c65be2e --- /dev/null +++ b/gmp-6.3.0/mpz/get_si.c @@ -0,0 +1,52 @@ +/* mpz_get_si(integer) -- Return the least significant digit from INTEGER. + +Copyright 1991, 1993-1995, 2000-2002, 2006, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +signed long int +mpz_get_si (mpz_srcptr z) __GMP_NOTHROW +{ + mp_ptr zp = PTR (z); + mp_size_t size = SIZ (z); + mp_limb_t zl = zp[0]; + +#if GMP_NAIL_BITS != 0 + if (ULONG_MAX > GMP_NUMB_MAX && ABS (size) >= 2) + zl |= zp[1] << GMP_NUMB_BITS; +#endif + + if (size > 0) + return zl & LONG_MAX; + else if (size < 0) + /* This expression is necessary to properly handle 0x80000000 */ + return -1 - (long) ((zl - 1) & LONG_MAX); + else + return 0; +} diff --git a/gmp-6.3.0/mpz/get_str.c b/gmp-6.3.0/mpz/get_str.c new file mode 100644 index 0000000..c00a9a3 --- /dev/null +++ b/gmp-6.3.0/mpz/get_str.c @@ -0,0 +1,115 @@ +/* mpz_get_str (string, base, mp_src) -- Convert the multiple precision + number MP_SRC to a string STRING of base BASE. If STRING is NULL + allocate space for the result. In any case, return a pointer to the + result. If STRING is not NULL, the caller must ensure enough space is + available to store the result. + +Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2012, 2017 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for strlen */ +#include "gmp-impl.h" +#include "longlong.h" + +char * +mpz_get_str (char *res_str, int base, mpz_srcptr x) +{ + mp_ptr xp; + mp_size_t x_size = SIZ (x); + char *return_str; + size_t str_size; + size_t alloc_size = 0; + const char *num_to_text; + int i; + TMP_DECL; + + num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + if (base > 1) + { + if (base <= 36) + num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz"; + else if (UNLIKELY (base > 62)) + return NULL; + } + else if (base > -2) + { + base = 10; + } + else + { + base = -base; + if (UNLIKELY (base > 36)) + return NULL; + } + + /* allocate string for the user if necessary */ + if (res_str == NULL) + { + /* digits, null terminator, possible minus sign */ + MPN_SIZEINBASE (alloc_size, PTR(x), ABS(x_size), base); + alloc_size += 1 + (x_size<0); + res_str = __GMP_ALLOCATE_FUNC_TYPE (alloc_size, char); + } + return_str = res_str; + + if (x_size < 0) + { + *res_str++ = '-'; + x_size = -x_size; + } + + /* mpn_get_str clobbers its input on non power-of-2 bases */ + TMP_MARK; + xp = PTR (x); + if (! POW2_P (base)) + { + xp = TMP_ALLOC_LIMBS (x_size | 1); /* |1 in case x_size==0 */ + MPN_COPY (xp, PTR (x), x_size); + } + + str_size = mpn_get_str ((unsigned char *) res_str, base, xp, x_size); + ASSERT (alloc_size == 0 || str_size <= alloc_size - (SIZ(x) < 0)); + + /* Convert result to printable chars. */ + for (i = 0; i < str_size; i++) + res_str[i] = num_to_text[(int) res_str[i]]; + res_str[str_size] = 0; + + TMP_FREE; + + /* if allocated then resize down to the actual space required */ + if (alloc_size != 0) + { + size_t actual_size = str_size + 1 + (res_str - return_str); + ASSERT (actual_size == strlen (return_str) + 1); + __GMP_REALLOCATE_FUNC_MAYBE_TYPE (return_str, alloc_size, actual_size, + char); + } + return return_str; +} diff --git a/gmp-6.3.0/mpz/get_ui.c b/gmp-6.3.0/mpz/get_ui.c new file mode 100644 index 0000000..2d7ea4e --- /dev/null +++ b/gmp-6.3.0/mpz/get_ui.c @@ -0,0 +1,33 @@ +/* mpz_get_ui(integer) -- Return the least significant digit from INTEGER. + +Copyright 1991, 1993-1995, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_get_ui 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/getlimbn.c b/gmp-6.3.0/mpz/getlimbn.c new file mode 100644 index 0000000..d34d764 --- /dev/null +++ b/gmp-6.3.0/mpz/getlimbn.c @@ -0,0 +1,33 @@ +/* mpz_getlimbn(integer,n) -- Return the N:th limb from INTEGER. + +Copyright 1993-1996, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_getlimbn 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/hamdist.c b/gmp-6.3.0/mpz/hamdist.c new file mode 100644 index 0000000..1dfb7b8 --- /dev/null +++ b/gmp-6.3.0/mpz/hamdist.c @@ -0,0 +1,174 @@ +/* mpz_hamdist -- calculate hamming distance. + +Copyright 1994, 1996, 2001, 2002, 2009-2011 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +mp_bitcnt_t +mpz_hamdist (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW +{ + mp_srcptr up, vp; + mp_size_t usize, vsize; + mp_bitcnt_t count; + + usize = SIZ(u); + vsize = SIZ(v); + + up = PTR(u); + vp = PTR(v); + + if (usize >= 0) + { + if (vsize < 0) + return ~ (mp_bitcnt_t) 0; + + /* positive/positive */ + + if (usize < vsize) + MPN_SRCPTR_SWAP (up,usize, vp,vsize); + + count = 0; + if (vsize != 0) + count = mpn_hamdist (up, vp, vsize); + + usize -= vsize; + if (usize != 0) + count += mpn_popcount (up + vsize, usize); + + return count; + } + else + { + mp_limb_t ulimb, vlimb; + mp_size_t old_vsize, step; + + if (vsize >= 0) + return ~ (mp_bitcnt_t) 0; + + /* negative/negative */ + + usize = -usize; + vsize = -vsize; + + /* skip common low zeros */ + for (;;) + { + ASSERT (usize > 0); + ASSERT (vsize > 0); + + usize--; + vsize--; + + ulimb = *up++; + vlimb = *vp++; + + if (ulimb != 0) + break; + + if (vlimb != 0) + { + MPN_SRCPTR_SWAP (up,usize, vp,vsize); + ulimb = vlimb; + vlimb = 0; + break; + } + } + + /* twos complement first non-zero limbs (ulimb is non-zero, but vlimb + might be zero) */ + ulimb = -ulimb; + vlimb = -vlimb; + popc_limb (count, (ulimb ^ vlimb) & GMP_NUMB_MASK); + + if (vlimb == 0) + { + mp_bitcnt_t twoscount; + + /* first non-zero of v */ + old_vsize = vsize; + do + { + ASSERT (vsize > 0); + vsize--; + vlimb = *vp++; + } + while (vlimb == 0); + + /* part of u corresponding to skipped v zeros */ + step = old_vsize - vsize - 1; + count += step * GMP_NUMB_BITS; + step = MIN (step, usize); + if (step != 0) + { + count -= mpn_popcount (up, step); + usize -= step; + up += step; + } + + /* First non-zero vlimb as twos complement, xor with ones + complement ulimb. Note -v^(~0^u) == (v-1)^u. */ + vlimb--; + if (usize != 0) + { + usize--; + vlimb ^= *up++; + } + popc_limb (twoscount, vlimb); + count += twoscount; + } + + /* Overlapping part of u and v, if any. Ones complement both, so just + plain hamdist. */ + step = MIN (usize, vsize); + if (step != 0) + { + count += mpn_hamdist (up, vp, step); + usize -= step; + vsize -= step; + up += step; + vp += step; + } + + /* Remaining high part of u or v, if any, ones complement but xor + against all ones in the other, so plain popcount. */ + if (usize != 0) + { + remaining: + count += mpn_popcount (up, usize); + } + else if (vsize != 0) + { + up = vp; + usize = vsize; + goto remaining; + } + return count; + } +} diff --git a/gmp-6.3.0/mpz/import.c b/gmp-6.3.0/mpz/import.c new file mode 100644 index 0000000..9ff0670 --- /dev/null +++ b/gmp-6.3.0/mpz/import.c @@ -0,0 +1,166 @@ +/* mpz_import -- set mpz from word data. + +Copyright 2002, 2012, 2021, 2022 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + + + +#if HAVE_LIMB_BIG_ENDIAN +#define HOST_ENDIAN 1 +#endif +#if HAVE_LIMB_LITTLE_ENDIAN +#define HOST_ENDIAN (-1) +#endif +#ifndef HOST_ENDIAN +static const mp_limb_t endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1; +#define HOST_ENDIAN (* (signed char *) &endian_test) +#endif + + +void +mpz_import (mpz_ptr z, size_t count, int order, + size_t size, int endian, size_t nail, const void *data) +{ + mp_size_t zsize; + mp_ptr zp; + + ASSERT (order == 1 || order == -1); + ASSERT (endian == 1 || endian == 0 || endian == -1); + ASSERT (nail <= 8*size); + + zsize = BITS_TO_LIMBS (count * (8*size - nail)); + zp = MPZ_NEWALLOC (z, zsize); + + if (endian == 0) + endian = HOST_ENDIAN; + + /* Can't use these special cases with nails currently, since they don't + mask out the nail bits in the input data. */ + if (nail == 0 && GMP_NAIL_BITS == 0 + && size == sizeof (mp_limb_t) + && (((char *) data - (char *) NULL) % sizeof (mp_limb_t)) == 0 /* align */) + { + if (order == -1) + { + if (endian == HOST_ENDIAN) + MPN_COPY (zp, (mp_srcptr) data, (mp_size_t) count); + else /* if (endian == - HOST_ENDIAN) */ + MPN_BSWAP (zp, (mp_srcptr) data, (mp_size_t) count); + } + else /* if (order == 1) */ + { + if (endian == HOST_ENDIAN) + MPN_REVERSE (zp, (mp_srcptr) data, (mp_size_t) count); + else /* if (endian == - HOST_ENDIAN) */ + MPN_BSWAP_REVERSE (zp, (mp_srcptr) data, (mp_size_t) count); + } + } + else + { + mp_limb_t limb, byte, wbitsmask; + size_t i, j, numb, wbytes; + mp_size_t woffset; + unsigned char *dp; + int lbits, wbits; + + numb = size * 8 - nail; + + /* whole bytes to process */ + wbytes = numb / 8; + + /* partial byte to process */ + wbits = numb % 8; + wbitsmask = (CNST_LIMB(1) << wbits) - 1; + + /* offset to get to the next word after processing wbytes and wbits */ + woffset = (numb + 7) / 8; + woffset = (endian >= 0 ? woffset : -woffset) + + (order < 0 ? size : - (mp_size_t) size); + + /* least significant byte */ + dp = (unsigned char *) data + + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0); + +#define ACCUMULATE(N) \ + do { \ + ASSERT (lbits < GMP_NUMB_BITS); \ + ASSERT (limb <= (CNST_LIMB(1) << lbits) - 1); \ + \ + limb |= (mp_limb_t) byte << lbits; \ + lbits += (N); \ + if (lbits >= GMP_NUMB_BITS) \ + { \ + *zp++ = limb & GMP_NUMB_MASK; \ + lbits -= GMP_NUMB_BITS; \ + ASSERT (lbits < (N)); \ + limb = byte >> ((N) - lbits); \ + } \ + } while (0) + + limb = 0; + lbits = 0; + for (i = 0; i < count; i++) + { + for (j = 0; j < wbytes; j++) + { + byte = *dp; + dp -= endian; + ACCUMULATE (8); + } + if (wbits != 0) + { + byte = *dp & wbitsmask; + dp -= endian; + ACCUMULATE (wbits); + } + dp += woffset; + } + + if (lbits != 0) + { + ASSERT (lbits <= GMP_NUMB_BITS); + ASSERT_LIMB (limb); + *zp++ = limb; + } + + ASSERT (zp == PTR(z) + zsize); + + /* low byte of word after most significant */ + ASSERT (dp == (unsigned char *) data + + (order < 0 ? count*size : - (mp_size_t) size) + + (endian >= 0 ? (mp_size_t) size - 1 : 0)); + + } + + zp = PTR(z); + MPN_NORMALIZE (zp, zsize); + SIZ(z) = zsize; +} diff --git a/gmp-6.3.0/mpz/init.c b/gmp-6.3.0/mpz/init.c new file mode 100644 index 0000000..b85a2da --- /dev/null +++ b/gmp-6.3.0/mpz/init.c @@ -0,0 +1,41 @@ +/* mpz_init() -- Make a new multiple precision number with value 0. + +Copyright 1991, 1993-1995, 2000-2002, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init (mpz_ptr x) __GMP_NOTHROW +{ + static const mp_limb_t dummy_limb=0xc1a0; + ALLOC (x) = 0; + PTR (x) = (mp_ptr) &dummy_limb; + SIZ (x) = 0; +} diff --git a/gmp-6.3.0/mpz/init2.c b/gmp-6.3.0/mpz/init2.c new file mode 100644 index 0000000..cdb46bf --- /dev/null +++ b/gmp-6.3.0/mpz/init2.c @@ -0,0 +1,50 @@ +/* mpz_init2 -- initialize mpz, with requested size in bits. + +Copyright 2001, 2002, 2008, 2021, 2022 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init2 (mpz_ptr x, mp_bitcnt_t bits) +{ + mp_size_t new_alloc; + + bits -= (bits != 0); /* Round down, except if 0 */ + new_alloc = 1 + bits / GMP_NUMB_BITS; + + if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */ + { + if (UNLIKELY (new_alloc > INT_MAX)) + MPZ_OVERFLOW; + } + + PTR(x) = __GMP_ALLOCATE_FUNC_LIMBS (new_alloc); + ALLOC(x) = new_alloc; + SIZ(x) = 0; +} diff --git a/gmp-6.3.0/mpz/inits.c b/gmp-6.3.0/mpz/inits.c new file mode 100644 index 0000000..1660744 --- /dev/null +++ b/gmp-6.3.0/mpz/inits.c @@ -0,0 +1,53 @@ +/* mpz_inits() -- Initialize multiple mpz_t variables and set them to 0. + +Copyright 2009, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + +void +mpz_inits (mpz_ptr x, ...) __GMP_NOTHROW +{ + static const mp_limb_t dummy_limb=0xc1a0; + va_list ap; + + va_start (ap, x); + + do + { + ALLOC (x) = 0; + PTR (x) = (mp_ptr) &dummy_limb; + SIZ (x) = 0; + + x = va_arg (ap, mpz_ptr); + } + while (x != NULL); + + va_end (ap); +} diff --git a/gmp-6.3.0/mpz/inp_raw.c b/gmp-6.3.0/mpz/inp_raw.c new file mode 100644 index 0000000..746d926 --- /dev/null +++ b/gmp-6.3.0/mpz/inp_raw.c @@ -0,0 +1,172 @@ +/* mpz_inp_raw -- read an mpz_t in raw format. + +Copyright 2001, 2002, 2005, 2012, 2016, 2021 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + + +/* NTOH_LIMB_FETCH fetches a limb which is in network byte order (ie. big + endian) and produces a normal host byte order result. */ + +#if HAVE_LIMB_BIG_ENDIAN +#define NTOH_LIMB_FETCH(limb, src) do { (limb) = *(src); } while (0) +#endif + +#if HAVE_LIMB_LITTLE_ENDIAN +#define NTOH_LIMB_FETCH(limb, src) BSWAP_LIMB_FETCH (limb, src) +#endif + +#ifndef NTOH_LIMB_FETCH +#define NTOH_LIMB_FETCH(limb, src) \ + do { \ + const unsigned char *__p = (const unsigned char *) (src); \ + mp_limb_t __limb; \ + int __i; \ + __limb = 0; \ + for (__i = 0; __i < GMP_LIMB_BYTES; __i++) \ + __limb = (__limb << 8) | __p[__i]; \ + (limb) = __limb; \ + } while (0) +#endif + + +/* Enhancement: The byte swap loop ought to be safe to vectorize on Cray + etc, but someone who knows what they're doing needs to check it. */ + +size_t +mpz_inp_raw (mpz_ptr x, FILE *fp) +{ + unsigned char csize_bytes[4]; + mp_size_t csize, abs_xsize, i; + size_t size; + size_t abs_csize; + char *cp; + mp_ptr xp, sp, ep; + mp_limb_t slimb, elimb; + + if (fp == 0) + fp = stdin; + + /* 4 bytes for size */ + if (UNLIKELY (fread (csize_bytes, sizeof (csize_bytes), 1, fp) != 1)) + return 0; + + size = (((size_t) csize_bytes[0] << 24) + ((size_t) csize_bytes[1] << 16) + + ((size_t) csize_bytes[2] << 8) + ((size_t) csize_bytes[3])); + + if (size < 0x80000000u) + csize = size; + else + csize = size - 0x80000000u - 0x80000000u; + + abs_csize = ABS (csize); + + if (UNLIKELY (abs_csize > ~(mp_bitcnt_t) 0 / 8)) + return 0; /* Bit size overflows */ + + /* round up to a multiple of limbs */ + abs_xsize = BITS_TO_LIMBS ((mp_bitcnt_t) abs_csize * 8); + + if (abs_xsize != 0) + { + xp = MPZ_NEWALLOC (x, abs_xsize); + + /* Get limb boundaries right in the read, for the benefit of the + non-nails case. */ + xp[0] = 0; + cp = (char *) (xp + abs_xsize) - abs_csize; + if (UNLIKELY (fread (cp, abs_csize, 1, fp) != 1)) + return 0; + + if (GMP_NAIL_BITS == 0) + { + /* Reverse limbs to least significant first, and byte swap. If + abs_xsize is odd then on the last iteration elimb and slimb are + the same. It doesn't seem extra code to handle that case + separately, to save an NTOH. */ + sp = xp; + ep = xp + abs_xsize-1; + for (i = 0; i < (abs_xsize+1)/2; i++) + { + NTOH_LIMB_FETCH (elimb, ep); + NTOH_LIMB_FETCH (slimb, sp); + *sp++ = elimb; + *ep-- = slimb; + } + } + else + { + /* It ought to be possible to do the transformation in-place, but + for now it's easier to use an extra temporary area. */ + mp_limb_t byte, limb; + int bits; + mp_size_t tpos; + mp_ptr tp; + TMP_DECL; + + TMP_MARK; + tp = TMP_ALLOC_LIMBS (abs_xsize); + limb = 0; + bits = 0; + tpos = 0; + for (i = abs_csize-1; i >= 0; i--) + { + byte = (unsigned char) cp[i]; + limb |= (byte << bits); + bits += 8; + if (bits >= GMP_NUMB_BITS) + { + ASSERT (tpos < abs_xsize); + tp[tpos++] = limb & GMP_NUMB_MASK; + bits -= GMP_NUMB_BITS; + ASSERT (bits < 8); + limb = byte >> (8 - bits); + } + } + if (bits != 0) + { + ASSERT (tpos < abs_xsize); + tp[tpos++] = limb; + } + ASSERT (tpos == abs_xsize); + + MPN_COPY (xp, tp, abs_xsize); + TMP_FREE; + } + + /* GMP 1.x mpz_out_raw wrote high zero bytes, strip any high zero + limbs resulting from this. Should be a non-zero value here, but + for safety don't assume that. */ + MPN_NORMALIZE (xp, abs_xsize); + } + + SIZ(x) = (csize >= 0 ? abs_xsize : -abs_xsize); + return abs_csize + 4; +} diff --git a/gmp-6.3.0/mpz/inp_str.c b/gmp-6.3.0/mpz/inp_str.c new file mode 100644 index 0000000..0756055 --- /dev/null +++ b/gmp-6.3.0/mpz/inp_str.c @@ -0,0 +1,173 @@ +/* mpz_inp_str(dest_integer, stream, base) -- Input a number in base + BASE from stdio stream STREAM and store the result in DEST_INTEGER. + + OF THE FUNCTIONS IN THIS FILE, ONLY mpz_inp_str IS FOR EXTERNAL USE, THE + REST ARE INTERNALS AND ARE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE + CHANGES OR DISAPPEAR COMPLETELY IN FUTURE GNU MP RELEASES. + +Copyright 1991, 1993, 1994, 1996, 1998, 2000-2003, 2011-2013 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include +#include "gmp-impl.h" +#include "longlong.h" + +#define digit_value_tab __gmp_digit_value_tab + +size_t +mpz_inp_str (mpz_ptr x, FILE *stream, int base) +{ + int c; + size_t nread; + + if (stream == 0) + stream = stdin; + + nread = 0; + + /* Skip whitespace. */ + do + { + c = getc (stream); + nread++; + } + while (isspace (c)); + + return mpz_inp_str_nowhite (x, stream, base, c, nread); +} + +/* shared by mpq_inp_str */ +size_t +mpz_inp_str_nowhite (mpz_ptr x, FILE *stream, int base, int c, size_t nread) +{ + char *str; + size_t alloc_size, str_size; + int negative; + mp_size_t xsize; + const unsigned char *digit_value; + + ASSERT_ALWAYS (EOF == -1); /* FIXME: handle this by adding explicit */ + /* comparisons of c and EOF before each */ + /* read of digit_value[]. */ + + digit_value = digit_value_tab; + if (base > 36) + { + /* For bases > 36, use the collating sequence + 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */ + digit_value += 208; + if (UNLIKELY (base > 62)) + return 0; /* too large base */ + } + + negative = 0; + if (c == '-') + { + negative = 1; + c = getc (stream); + nread++; + } + + if (c == EOF || digit_value[c] >= (base == 0 ? 10 : base)) + return 0; /* error if no digits */ + + /* If BASE is 0, try to find out the base by looking at the initial + characters. */ + if (base == 0) + { + base = 10; + if (c == '0') + { + base = 8; + c = getc (stream); + nread++; + if (c == 'x' || c == 'X') + { + base = 16; + c = getc (stream); + nread++; + } + else if (c == 'b' || c == 'B') + { + base = 2; + c = getc (stream); + nread++; + } + } + } + + /* Skip leading zeros. */ + while (c == '0') + { + c = getc (stream); + nread++; + } + + alloc_size = 100; + str = __GMP_ALLOCATE_FUNC_TYPE (alloc_size, char); + str_size = 0; + + while (c != EOF) + { + int dig; + dig = digit_value[c]; + if (dig >= base) + break; + if (str_size >= alloc_size) + { + size_t old_alloc_size = alloc_size; + alloc_size = alloc_size * 3 / 2; + str = __GMP_REALLOCATE_FUNC_TYPE (str, old_alloc_size, alloc_size, char); + } + str[str_size++] = dig; + c = getc (stream); + } + nread += str_size; + + ungetc (c, stream); + nread--; + + /* Make sure the string is not empty, mpn_set_str would fail. */ + if (str_size == 0) + { + SIZ (x) = 0; + } + else + { + LIMBS_PER_DIGIT_IN_BASE (xsize, str_size, base); + MPZ_NEWALLOC (x, xsize); + + /* Convert the byte array in base BASE to our bignum format. */ + xsize = mpn_set_str (PTR (x), (unsigned char *) str, str_size, base); + SIZ (x) = negative ? -xsize : xsize; + } + (*__gmp_free_func) (str, alloc_size); + return nread; +} diff --git a/gmp-6.3.0/mpz/invert.c b/gmp-6.3.0/mpz/invert.c new file mode 100644 index 0000000..5532d13 --- /dev/null +++ b/gmp-6.3.0/mpz/invert.c @@ -0,0 +1,72 @@ +/* mpz_invert (inv, x, n). Find multiplicative inverse of X in Z(N). + If X has an inverse, return non-zero and store inverse in INVERSE, + otherwise, return 0 and put garbage in INVERSE. + +Copyright 1996-2001, 2005, 2012, 2014 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_invert (mpz_ptr inverse, mpz_srcptr x, mpz_srcptr n) +{ + mpz_t gcd, tmp; + mp_size_t xsize, nsize, size; + TMP_DECL; + + xsize = ABSIZ (x); + nsize = ABSIZ (n); + + size = MAX (xsize, nsize) + 1; + TMP_MARK; + + MPZ_TMP_INIT (gcd, size); + MPZ_TMP_INIT (tmp, size); + mpz_gcdext (gcd, tmp, (mpz_ptr) 0, x, n); + + /* If no inverse existed, return with an indication of that. */ + if (!MPZ_EQUAL_1_P (gcd)) + { + TMP_FREE; + return 0; + } + + /* Make sure we return a positive inverse. */ + if (SIZ (tmp) < 0) + { + if (SIZ (n) < 0) + mpz_sub (inverse, tmp, n); + else + mpz_add (inverse, tmp, n); + } + else + mpz_set (inverse, tmp); + + TMP_FREE; + return 1; +} diff --git a/gmp-6.3.0/mpz/ior.c b/gmp-6.3.0/mpz/ior.c new file mode 100644 index 0000000..32f3042 --- /dev/null +++ b/gmp-6.3.0/mpz/ior.c @@ -0,0 +1,184 @@ +/* mpz_ior -- Logical inclusive or. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012, 2013, +2015-2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) +{ + mp_srcptr op1_ptr, op2_ptr; + mp_size_t op1_size, op2_size; + mp_ptr res_ptr; + mp_size_t res_size; + mp_size_t i; + + op1_size = SIZ(op1); + op2_size = SIZ(op2); + + if (op1_size < op2_size) + { + MPZ_SRCPTR_SWAP (op1, op2); + MP_SIZE_T_SWAP (op1_size, op2_size); + } + + op1_ptr = PTR(op1); + res_ptr = PTR(res); + + if (op2_size >= 0) + { + if (res_ptr != op1_ptr) + { + res_ptr = MPZ_REALLOC (res, op1_size); + /* No overlapping possible: op1_ptr = PTR(op1); */ + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, + op1_size - op2_size); + } + if (LIKELY (op2_size != 0)) + mpn_ior_n (res_ptr, op1_ptr, PTR(op2), op2_size); + + SIZ(res) = op1_size; + } + else + { + mp_ptr opx; + TMP_DECL; + + TMP_MARK; + if (op1_size < 0) + { + mp_ptr opy; + + /* Both operands are negative, so will be the result. + -((-OP1) | (-OP2)) = -(~(OP1 - 1) | ~(OP2 - 1)) = + = ~(~(OP1 - 1) | ~(OP2 - 1)) + 1 = + = ((OP1 - 1) & (OP2 - 1)) + 1 */ + + res_size = -op1_size; + + /* Possible optimization: Decrease mpn_sub precision, + as we won't use the entire res of both. */ + TMP_ALLOC_LIMBS_2 (opx, res_size, opy, res_size); + mpn_sub_1 (opx, op1_ptr, res_size, (mp_limb_t) 1); + op1_ptr = opx; + + mpn_sub_1 (opy, PTR(op2), res_size, (mp_limb_t) 1); + op2_ptr = opy; + + /* First loop finds the size of the result. */ + for (i = res_size; --i >= 0;) + if ((op1_ptr[i] & op2_ptr[i]) != 0) + break; + res_size = i + 1; + + res_ptr = MPZ_NEWALLOC (res, res_size + 1); + + if (res_size != 0) + { + /* Second loop computes the real result. */ + mpn_and_n (res_ptr, op1_ptr, op2_ptr, res_size); + + res_ptr[res_size] = 0; + MPN_INCR_U (res_ptr, res_size + 1, 1); + res_size += res_ptr[res_size]; + } + else + { + res_ptr[0] = 1; + res_size = 1; + } + + SIZ(res) = -res_size; + } + else + { + mp_limb_t cy; + mp_size_t count; + + /* Operand 2 negative, so will be the result. + -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) = + = ~(OP1 | ~(OP2 - 1)) + 1 = + = (~OP1 & (OP2 - 1)) + 1 */ + + op2_size = -op2_size; + + res_ptr = MPZ_REALLOC (res, op2_size); + op1_ptr = PTR(op1); + + opx = TMP_ALLOC_LIMBS (op2_size); + mpn_sub_1 (opx, PTR(op2), op2_size, (mp_limb_t) 1); + op2_ptr = opx; + op2_size -= op2_ptr[op2_size - 1] == 0; + + if (op1_size >= op2_size) + { + /* We can just ignore the part of OP1 that stretches above OP2, + because the result limbs are zero there. */ + + /* First loop finds the size of the result. */ + for (i = op2_size; --i >= 0;) + if ((~op1_ptr[i] & op2_ptr[i]) != 0) + break; + res_size = i + 1; + count = res_size; + } + else + { + res_size = op2_size; + + /* Copy the part of OP2 that stretches above OP1, to RES. */ + MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); + count = op1_size; + } + + if (res_size != 0) + { + /* Second loop computes the real result. */ + if (LIKELY (count != 0)) + mpn_andn_n (res_ptr, op2_ptr, op1_ptr, count); + + cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1); + if (cy) + { + res_ptr[res_size] = cy; + ++res_size; + } + } + else + { + res_ptr[0] = 1; + res_size = 1; + } + + SIZ(res) = -res_size; + } + TMP_FREE; + } +} diff --git a/gmp-6.3.0/mpz/iset.c b/gmp-6.3.0/mpz/iset.c new file mode 100644 index 0000000..252cada --- /dev/null +++ b/gmp-6.3.0/mpz/iset.c @@ -0,0 +1,52 @@ +/* mpz_init_set (src_integer) -- Make a new multiple precision number with + a value copied from SRC_INTEGER. + +Copyright 1991, 1993, 1994, 1996, 2000-2002, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init_set (mpz_ptr w, mpz_srcptr u) +{ + mp_ptr wp, up; + mp_size_t usize, size; + + usize = SIZ (u); + size = ABS (usize); + + ALLOC (w) = MAX (size, 1); + wp = __GMP_ALLOCATE_FUNC_LIMBS (ALLOC (w)); + + PTR (w) = wp; + up = PTR (u); + + MPN_COPY (wp, up, size); + SIZ (w) = usize; +} diff --git a/gmp-6.3.0/mpz/iset_d.c b/gmp-6.3.0/mpz/iset_d.c new file mode 100644 index 0000000..5d04a6f --- /dev/null +++ b/gmp-6.3.0/mpz/iset_d.c @@ -0,0 +1,43 @@ +/* mpz_init_set_d(integer, val) -- Initialize and assign INTEGER with a double + value VAL. + +Copyright 1996, 2000, 2001, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init_set_d (mpz_ptr dest, double val) +{ + static const mp_limb_t dummy_limb=0xc1a0; + + ALLOC (dest) = 0; + SIZ (dest) = 0; + PTR (dest) = (mp_ptr) &dummy_limb; + mpz_set_d (dest, val); +} diff --git a/gmp-6.3.0/mpz/iset_si.c b/gmp-6.3.0/mpz/iset_si.c new file mode 100644 index 0000000..7179cb0 --- /dev/null +++ b/gmp-6.3.0/mpz/iset_si.c @@ -0,0 +1,58 @@ +/* mpz_init_set_si(dest,val) -- Make a new multiple precision in DEST and + assign VAL to the new number. + +Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init_set_si (mpz_ptr dest, signed long int val) +{ + mp_size_t size; + mp_limb_t vl; + + ALLOC (dest) = 1; + PTR (dest) = __GMP_ALLOCATE_FUNC_LIMBS (1); + + vl = (mp_limb_t) ABS_CAST (unsigned long int, val); + + PTR (dest)[0] = vl & GMP_NUMB_MASK; + size = vl != 0; + +#if GMP_NAIL_BITS != 0 + if (vl > GMP_NUMB_MAX) + { + MPZ_REALLOC (dest, 2); + PTR (dest)[1] = vl >> GMP_NUMB_BITS; + size = 2; + } +#endif + + SIZ (dest) = val >= 0 ? size : -size; +} diff --git a/gmp-6.3.0/mpz/iset_str.c b/gmp-6.3.0/mpz/iset_str.c new file mode 100644 index 0000000..2df12f9 --- /dev/null +++ b/gmp-6.3.0/mpz/iset_str.c @@ -0,0 +1,47 @@ +/* mpz_init_set_str(string, base) -- Convert the \0-terminated string STRING in + base BASE to a multiple precision integer. Allow white space in the string. + If BASE == 0 determine the base in the C standard way, i.e. 0xhh...h means + base 16, 0oo...o means base 8, otherwise assume base 10. + +Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_init_set_str (mpz_ptr x, const char *str, int base) +{ + static const mp_limb_t dummy_limb=0xc1a0; + ALLOC (x) = 0; + PTR (x) = (mp_ptr) &dummy_limb; + + /* if str has no digits mpz_set_str leaves x->_mp_size unset */ + SIZ (x) = 0; + + return mpz_set_str (x, str, base); +} diff --git a/gmp-6.3.0/mpz/iset_ui.c b/gmp-6.3.0/mpz/iset_ui.c new file mode 100644 index 0000000..22a8e15 --- /dev/null +++ b/gmp-6.3.0/mpz/iset_ui.c @@ -0,0 +1,58 @@ +/* mpz_init_set_ui(dest,val) -- Make a new multiple precision in DEST and + assign VAL to the new number. + +Copyright 1991, 1993-1995, 2000-2002, 2004, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_init_set_ui (mpz_ptr dest, unsigned long int val) +{ + mp_size_t size; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (val > GMP_NUMB_MAX) + { + ALLOC (dest) = 2; + PTR (dest) = __GMP_ALLOCATE_FUNC_LIMBS (2); + PTR (dest)[1] = val >> GMP_NUMB_BITS; + size = 2; + } + else +#endif + { + ALLOC (dest) = 1; + PTR (dest) = __GMP_ALLOCATE_FUNC_LIMBS (1); + + size = val != 0; + } + PTR (dest)[0] = val & GMP_NUMB_MASK; + + SIZ (dest) = size; +} diff --git a/gmp-6.3.0/mpz/jacobi.c b/gmp-6.3.0/mpz/jacobi.c new file mode 100644 index 0000000..cd556d7 --- /dev/null +++ b/gmp-6.3.0/mpz/jacobi.c @@ -0,0 +1,210 @@ +/* mpz_jacobi, mpz_legendre, mpz_kronecker -- mpz/mpz Jacobi symbols. + +Copyright 2000-2002, 2005, 2010-2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + + +/* This code does triple duty as mpz_jacobi, mpz_legendre and + mpz_kronecker. For ABI compatibility, the link symbol is + __gmpz_jacobi, not __gmpz_kronecker, even though the latter would + be more logical. + + mpz_jacobi could assume b is odd, but the improvements from that seem + small compared to other operations, and anything significant should be + checked at run-time since we'd like odd b to go fast in mpz_kronecker + too. + + mpz_legendre could assume b is an odd prime, but knowing this doesn't + present any obvious benefits. Result 0 wouldn't arise (unless "a" is a + multiple of b), but the checking for that takes little time compared to + other operations. + + Enhancements: + + mpn_bdiv_qr should be used instead of mpn_tdiv_qr. + +*/ + +int +mpz_jacobi (mpz_srcptr a, mpz_srcptr b) +{ + mp_srcptr asrcp, bsrcp; + mp_size_t asize, bsize; + mp_limb_t alow, blow; + mp_ptr ap, bp; + unsigned btwos; + int result_bit1; + int res; + TMP_DECL; + + asize = SIZ(a); + asrcp = PTR(a); + alow = asrcp[0]; + + bsize = SIZ(b); + bsrcp = PTR(b); + blow = bsrcp[0]; + + /* The MPN jacobi functions require positive a and b, and b odd. So + we must to handle the cases of a or b zero, then signs, and then + the case of even b. + */ + + if (bsize == 0) + /* (a/0) = [ a = 1 or a = -1 ] */ + return JACOBI_LS0 (alow, asize); + + if (asize == 0) + /* (0/b) = [ b = 1 or b = - 1 ] */ + return JACOBI_0LS (blow, bsize); + + if ( (((alow | blow) & 1) == 0)) + /* Common factor of 2 ==> (a/b) = 0 */ + return 0; + + if (bsize < 0) + { + /* (a/-1) = -1 if a < 0, +1 if a >= 0 */ + result_bit1 = (asize < 0) << 1; + bsize = -bsize; + } + else + result_bit1 = 0; + + JACOBI_STRIP_LOW_ZEROS (result_bit1, alow, bsrcp, bsize, blow); + + count_trailing_zeros (btwos, blow); + blow >>= btwos; + + if (bsize > 1 && btwos > 0) + { + mp_limb_t b1 = bsrcp[1]; + blow |= b1 << (GMP_NUMB_BITS - btwos); + if (bsize == 2 && (b1 >> btwos) == 0) + bsize = 1; + } + + if (asize < 0) + { + /* (-1/b) = -1 iff b = 3 (mod 4) */ + result_bit1 ^= JACOBI_N1B_BIT1(blow); + asize = -asize; + } + + JACOBI_STRIP_LOW_ZEROS (result_bit1, blow, asrcp, asize, alow); + + /* Ensure asize >= bsize. Take advantage of the generalized + reciprocity law (a/b*2^n) = (b*2^n / a) * RECIP(a,b) */ + + if (asize < bsize) + { + MPN_SRCPTR_SWAP (asrcp, asize, bsrcp, bsize); + MP_LIMB_T_SWAP (alow, blow); + + /* NOTE: The value of alow (old blow) is a bit subtle. For this code + path, we get alow as the low, always odd, limb of shifted A. Which is + what we need for the reciprocity update below. + + However, all other uses of alow assumes that it is *not* + shifted. Luckily, alow matters only when either + + + btwos > 0, in which case A is always odd + + + asize == bsize == 1, in which case this code path is never + taken. */ + + count_trailing_zeros (btwos, blow); + blow >>= btwos; + + if (bsize > 1 && btwos > 0) + { + mp_limb_t b1 = bsrcp[1]; + blow |= b1 << (GMP_NUMB_BITS - btwos); + if (bsize == 2 && (b1 >> btwos) == 0) + bsize = 1; + } + + result_bit1 ^= JACOBI_RECIP_UU_BIT1 (alow, blow); + } + + if (bsize == 1) + { + result_bit1 ^= JACOBI_TWOS_U_BIT1(btwos, alow); + + if (blow == 1) + return JACOBI_BIT1_TO_PN (result_bit1); + + if (asize > 1) + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, alow, asrcp, asize, blow); + + return mpn_jacobi_base (alow, blow, result_bit1); + } + + /* Allocation strategy: For A, we allocate a working copy only for A % B, but + when A is much larger than B, we have to allocate space for the large + quotient. We use the same area, pointed to by bp, for both the quotient + A/B and the working copy of B. */ + + TMP_MARK; + + if (asize >= 2*bsize) + TMP_ALLOC_LIMBS_2 (ap, bsize, bp, asize - bsize + 1); + else + TMP_ALLOC_LIMBS_2 (ap, bsize, bp, bsize); + + /* In the case of even B, we conceptually shift out the powers of two first, + and then divide A mod B. Hence, when taking those powers of two into + account, we must use alow *before* the division. Doing the actual division + first is ok, because the point is to remove multiples of B from A, and + multiples of 2^k B are good enough. */ + if (asize > bsize) + mpn_tdiv_qr (bp, ap, 0, asrcp, asize, bsrcp, bsize); + else + MPN_COPY (ap, asrcp, bsize); + + if (btwos > 0) + { + result_bit1 ^= JACOBI_TWOS_U_BIT1(btwos, alow); + + ASSERT_NOCARRY (mpn_rshift (bp, bsrcp, bsize, btwos)); + bsize -= (ap[bsize-1] | bp[bsize-1]) == 0; + } + else + MPN_COPY (bp, bsrcp, bsize); + + ASSERT (blow == bp[0]); + res = mpn_jacobi_n (ap, bp, bsize, + mpn_jacobi_init (ap[0], blow, (result_bit1>>1) & 1)); + + TMP_FREE; + return res; +} diff --git a/gmp-6.3.0/mpz/kronsz.c b/gmp-6.3.0/mpz/kronsz.c new file mode 100644 index 0000000..92cc971 --- /dev/null +++ b/gmp-6.3.0/mpz/kronsz.c @@ -0,0 +1,137 @@ +/* mpz_si_kronecker -- long+mpz Kronecker/Jacobi symbol. + +Copyright 1999-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +int +mpz_si_kronecker (long a, mpz_srcptr b) +{ + mp_srcptr b_ptr; + mp_limb_t b_low; + mp_size_t b_size; + mp_size_t b_abs_size; + mp_limb_t a_limb, b_rem; + unsigned twos; + int result_bit1; + +#if GMP_NUMB_BITS < BITS_PER_ULONG + if (a > GMP_NUMB_MAX || a < -GMP_NUMB_MAX) + { + mp_limb_t alimbs[2]; + mpz_t az; + ALLOC(az) = numberof (alimbs); + PTR(az) = alimbs; + mpz_set_si (az, a); + return mpz_kronecker (az, b); + } +#endif + + b_size = SIZ (b); + if (b_size == 0) + return JACOBI_S0 (a); /* (a/0) */ + + /* account for the effect of the sign of b, then ignore it */ + result_bit1 = JACOBI_BSGN_SS_BIT1 (a, b_size); + + b_ptr = PTR(b); + b_low = b_ptr[0]; + b_abs_size = ABS (b_size); + + if ((b_low & 1) != 0) + { + /* b odd */ + + result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low); + a_limb = ABS_CAST(mp_limb_t, a); + + if ((a_limb & 1) == 0) + { + /* (0/b)=1 for b=+/-1, 0 otherwise */ + if (a_limb == 0) + return (b_abs_size == 1 && b_low == 1); + + /* a even, b odd */ + count_trailing_zeros (twos, a_limb); + a_limb >>= twos; + /* (a*2^n/b) = (a/b) * twos(n,a) */ + result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, b_low); + } + } + else + { + /* (even/even)=0, and (0/b)=0 for b!=+/-1 */ + if ((a & 1) == 0) + return 0; + + /* a odd, b even + + Establish shifted b_low with valid bit1 for ASGN and RECIP below. + Zero limbs stripped are accounted for, but zero bits on b_low are + not because they remain in {b_ptr,b_abs_size} for the + JACOBI_MOD_OR_MODEXACT_1_ODD. */ + + JACOBI_STRIP_LOW_ZEROS (result_bit1, a, b_ptr, b_abs_size, b_low); + if ((b_low & 1) == 0) + { + if (UNLIKELY (b_low == GMP_NUMB_HIGHBIT)) + { + /* need b_ptr[1] to get bit1 in b_low */ + if (b_abs_size == 1) + { + /* (a/0x80000000) = (a/2)^(BPML-1) */ + if ((GMP_NUMB_BITS % 2) == 0) + result_bit1 ^= JACOBI_TWO_U_BIT1 (a); + return JACOBI_BIT1_TO_PN (result_bit1); + } + + /* b_abs_size > 1 */ + b_low = b_ptr[1] << 1; + } + else + { + count_trailing_zeros (twos, b_low); + b_low >>= twos; + } + } + + result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low); + a_limb = (unsigned long) ABS(a); + } + + if (a_limb == 1) + return JACOBI_BIT1_TO_PN (result_bit1); /* (1/b)=1 */ + + /* (a/b*2^n) = (b*2^n mod a / a) * recip(a,b) */ + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, b_rem, b_ptr, b_abs_size, a_limb); + result_bit1 ^= JACOBI_RECIP_UU_BIT1 (a_limb, b_low); + return mpn_jacobi_base (b_rem, a_limb, result_bit1); +} diff --git a/gmp-6.3.0/mpz/kronuz.c b/gmp-6.3.0/mpz/kronuz.c new file mode 100644 index 0000000..ba5c6dd --- /dev/null +++ b/gmp-6.3.0/mpz/kronuz.c @@ -0,0 +1,129 @@ +/* mpz_ui_kronecker -- ulong+mpz Kronecker/Jacobi symbol. + +Copyright 1999-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +int +mpz_ui_kronecker (unsigned long a, mpz_srcptr b) +{ + mp_srcptr b_ptr; + mp_limb_t b_low; + int b_abs_size; + mp_limb_t b_rem; + int twos; + int result_bit1; + + /* (a/-1)=1 when a>=0, so the sign of b is ignored */ + b_abs_size = ABSIZ (b); + + if (b_abs_size == 0) + return JACOBI_U0 (a); /* (a/0) */ + + if (a > GMP_NUMB_MAX) + { + mp_limb_t alimbs[2]; + mpz_t az; + ALLOC(az) = numberof (alimbs); + PTR(az) = alimbs; + mpz_set_ui (az, a); + return mpz_kronecker (az, b); + } + + b_ptr = PTR(b); + b_low = b_ptr[0]; + result_bit1 = 0; + + if (! (b_low & 1)) + { + /* (0/b)=0 for b!=+/-1; and (even/even)=0 */ + if (! (a & 1)) + return 0; + + /* a odd, b even + + Establish shifted b_low with valid bit1 for the RECIP below. Zero + limbs stripped are accounted for, but zero bits on b_low are not + because they remain in {b_ptr,b_abs_size} for + JACOBI_MOD_OR_MODEXACT_1_ODD. */ + + JACOBI_STRIP_LOW_ZEROS (result_bit1, a, b_ptr, b_abs_size, b_low); + if (! (b_low & 1)) + { + if (UNLIKELY (b_low == GMP_NUMB_HIGHBIT)) + { + /* need b_ptr[1] to get bit1 in b_low */ + if (b_abs_size == 1) + { + /* (a/0x80...00) == (a/2)^(NUMB-1) */ + if ((GMP_NUMB_BITS % 2) == 0) + { + /* JACOBI_STRIP_LOW_ZEROS does nothing to result_bit1 + when GMP_NUMB_BITS is even, so it's still 0. */ + ASSERT (result_bit1 == 0); + result_bit1 = JACOBI_TWO_U_BIT1 (a); + } + return JACOBI_BIT1_TO_PN (result_bit1); + } + + /* b_abs_size > 1 */ + b_low = b_ptr[1] << 1; + } + else + { + count_trailing_zeros (twos, b_low); + b_low >>= twos; + } + } + } + else + { + if (a == 0) /* (0/b)=1 for b=+/-1, 0 otherwise */ + return (b_abs_size == 1 && b_low == 1); + + if (! (a & 1)) + { + /* a even, b odd */ + count_trailing_zeros (twos, a); + a >>= twos; + /* (a*2^n/b) = (a/b) * (2/a)^n */ + result_bit1 = JACOBI_TWOS_U_BIT1 (twos, b_low); + } + } + + if (a == 1) + return JACOBI_BIT1_TO_PN (result_bit1); /* (1/b)=1 */ + + /* (a/b*2^n) = (b*2^n mod a / a) * RECIP(a,b) */ + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, b_rem, b_ptr, b_abs_size, a); + result_bit1 ^= JACOBI_RECIP_UU_BIT1 (a, b_low); + return mpn_jacobi_base (b_rem, (mp_limb_t) a, result_bit1); +} diff --git a/gmp-6.3.0/mpz/kronzs.c b/gmp-6.3.0/mpz/kronzs.c new file mode 100644 index 0000000..1f63f15 --- /dev/null +++ b/gmp-6.3.0/mpz/kronzs.c @@ -0,0 +1,92 @@ +/* mpz_kronecker_si -- mpz+long Kronecker/Jacobi symbol. + +Copyright 1999-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* After the absolute value of b is established it's treated as an unsigned + long, because 0x80..00 doesn't fit in a signed long. */ + +int +mpz_kronecker_si (mpz_srcptr a, long b) +{ + mp_srcptr a_ptr; + mp_size_t a_size; + mp_limb_t a_rem, b_limb; + int result_bit1; + + a_size = SIZ(a); + if (a_size == 0) + return JACOBI_0S (b); + +#if GMP_NUMB_BITS < BITS_PER_ULONG + if (b > GMP_NUMB_MAX || b < -GMP_NUMB_MAX) + { + mp_limb_t blimbs[2]; + mpz_t bz; + ALLOC(bz) = numberof (blimbs); + PTR(bz) = blimbs; + mpz_set_si (bz, b); + return mpz_kronecker (a, bz); + } +#endif + + result_bit1 = JACOBI_BSGN_SS_BIT1 (a_size, b); + b_limb = ABS_CAST (unsigned long, b); + a_ptr = PTR(a); + + if ((b_limb & 1) == 0) + { + mp_limb_t a_low = a_ptr[0]; + int twos; + + if (b_limb == 0) + return JACOBI_LS0 (a_low, a_size); /* (a/0) */ + + if (! (a_low & 1)) + return 0; /* (even/even)=0 */ + + /* (a/2)=(2/a) for a odd */ + count_trailing_zeros (twos, b_limb); + b_limb >>= twos; + result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, a_low); + } + + if (b_limb == 1) + return JACOBI_BIT1_TO_PN (result_bit1); /* (a/1)=1 for any a */ + + result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a_size, b_limb); + a_size = ABS(a_size); + + /* (a/b) = (a mod b / b) */ + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, a_rem, a_ptr, a_size, b_limb); + return mpn_jacobi_base (a_rem, b_limb, result_bit1); +} diff --git a/gmp-6.3.0/mpz/kronzu.c b/gmp-6.3.0/mpz/kronzu.c new file mode 100644 index 0000000..b4fbf79 --- /dev/null +++ b/gmp-6.3.0/mpz/kronzu.c @@ -0,0 +1,88 @@ +/* mpz_kronecker_ui -- mpz+ulong Kronecker/Jacobi symbol. + +Copyright 1999-2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +int +mpz_kronecker_ui (mpz_srcptr a, unsigned long b) +{ + mp_srcptr a_ptr; + mp_size_t a_size; + mp_limb_t a_rem; + int result_bit1; + + a_size = SIZ(a); + if (a_size == 0) + return JACOBI_0U (b); + + if (b > GMP_NUMB_MAX) + { + mp_limb_t blimbs[2]; + mpz_t bz; + ALLOC(bz) = numberof (blimbs); + PTR(bz) = blimbs; + mpz_set_ui (bz, b); + return mpz_kronecker (a, bz); + } + + a_ptr = PTR(a); + if ((b & 1) != 0) + { + result_bit1 = JACOBI_ASGN_SU_BIT1 (a_size, b); + } + else + { + mp_limb_t a_low = a_ptr[0]; + int twos; + + if (b == 0) + return JACOBI_LS0 (a_low, a_size); /* (a/0) */ + + if (! (a_low & 1)) + return 0; /* (even/even)=0 */ + + /* (a/2)=(2/a) for a odd */ + count_trailing_zeros (twos, b); + b >>= twos; + result_bit1 = (JACOBI_TWOS_U_BIT1 (twos, a_low) + ^ JACOBI_ASGN_SU_BIT1 (a_size, b)); + } + + if (b == 1) + return JACOBI_BIT1_TO_PN (result_bit1); /* (a/1)=1 for any a */ + + a_size = ABS(a_size); + + /* (a/b) = (a mod b / b) */ + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, a_rem, a_ptr, a_size, b); + return mpn_jacobi_base (a_rem, (mp_limb_t) b, result_bit1); +} diff --git a/gmp-6.3.0/mpz/lcm.c b/gmp-6.3.0/mpz/lcm.c new file mode 100644 index 0000000..2807ef7 --- /dev/null +++ b/gmp-6.3.0/mpz/lcm.c @@ -0,0 +1,87 @@ +/* mpz_lcm -- mpz/mpz least common multiple. + +Copyright 1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_lcm (mpz_ptr r, mpz_srcptr u, mpz_srcptr v) +{ + mpz_t g; + mp_size_t usize, vsize; + TMP_DECL; + + usize = SIZ (u); + vsize = SIZ (v); + if (usize == 0 || vsize == 0) + { + SIZ (r) = 0; + return; + } + usize = ABS (usize); + vsize = ABS (vsize); + + if (vsize == 1 || usize == 1) + { + mp_limb_t vl, gl, c; + mp_srcptr up; + mp_ptr rp; + + if (usize == 1) + { + usize = vsize; + MPZ_SRCPTR_SWAP (u, v); + } + + MPZ_REALLOC (r, usize+1); + + up = PTR(u); + vl = PTR(v)[0]; + gl = mpn_gcd_1 (up, usize, vl); + vl /= gl; + + rp = PTR(r); + c = mpn_mul_1 (rp, up, usize, vl); + rp[usize] = c; + usize += (c != 0); + SIZ(r) = usize; + return; + } + + TMP_MARK; + MPZ_TMP_INIT (g, usize); /* v != 0 implies |gcd(u,v)| <= |u| */ + + mpz_gcd (g, u, v); + mpz_divexact (g, u, g); + mpz_mul (r, g, v); + + SIZ (r) = ABS (SIZ (r)); /* result always positive */ + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/lcm_ui.c b/gmp-6.3.0/mpz/lcm_ui.c new file mode 100644 index 0000000..1f199b7 --- /dev/null +++ b/gmp-6.3.0/mpz/lcm_ui.c @@ -0,0 +1,78 @@ +/* mpz_lcm_ui -- least common multiple of mpz and ulong. + +Copyright 2001, 2002, 2004 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +void +mpz_lcm_ui (mpz_ptr r, mpz_srcptr u, unsigned long v) +{ + mp_size_t usize; + mp_srcptr up; + mp_ptr rp; + unsigned long g; + mp_limb_t c; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (v > GMP_NUMB_MAX) + { + mpz_t vz; + mp_limb_t vlimbs[2]; + vlimbs[0] = v & GMP_NUMB_MASK; + vlimbs[1] = v >> GMP_NUMB_BITS; + PTR(vz) = vlimbs; + SIZ(vz) = 2; + mpz_lcm (r, u, vz); + return; + } +#endif + + /* result zero if either operand zero */ + usize = SIZ(u); + if (usize == 0 || v == 0) + { + SIZ(r) = 0; + return; + } + usize = ABS(usize); + + MPZ_REALLOC (r, usize+1); + + up = PTR(u); + g = (unsigned long) mpn_gcd_1 (up, usize, (mp_limb_t) v); + v /= g; + + rp = PTR(r); + c = mpn_mul_1 (rp, up, usize, (mp_limb_t) v); + rp[usize] = c; + usize += (c != 0); + SIZ(r) = usize; +} diff --git a/gmp-6.3.0/mpz/limbs_finish.c b/gmp-6.3.0/mpz/limbs_finish.c new file mode 100644 index 0000000..a02839d --- /dev/null +++ b/gmp-6.3.0/mpz/limbs_finish.c @@ -0,0 +1,39 @@ +/* mpz_finish_limbs -- Update mpz after writing to the limb array. + +Copyright 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_limbs_finish (mpz_ptr x, mp_size_t xs) +{ + mp_size_t xn = ABS(xs); + MPN_NORMALIZE (PTR (x), xn); + SIZ (x) = xs < 0 ? -xn : xn; +} diff --git a/gmp-6.3.0/mpz/limbs_modify.c b/gmp-6.3.0/mpz/limbs_modify.c new file mode 100644 index 0000000..a778b6e --- /dev/null +++ b/gmp-6.3.0/mpz/limbs_modify.c @@ -0,0 +1,38 @@ +/* mpz_limbs_modify -- Read-and-modify access to the mpn-style limb array. + +Copyright 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +mp_ptr +mpz_limbs_modify (mpz_ptr x, mp_size_t n) +{ + ASSERT (n > 0); + return MPZ_REALLOC (x, n); +} diff --git a/gmp-6.3.0/mpz/limbs_read.c b/gmp-6.3.0/mpz/limbs_read.c new file mode 100644 index 0000000..705f0c1 --- /dev/null +++ b/gmp-6.3.0/mpz/limbs_read.c @@ -0,0 +1,37 @@ +/* mpz_limbs_read -- Read access to the mpn-style limb array. + +Copyright 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +mp_srcptr +mpz_limbs_read (mpz_srcptr x) +{ + return PTR(x); +} diff --git a/gmp-6.3.0/mpz/limbs_write.c b/gmp-6.3.0/mpz/limbs_write.c new file mode 100644 index 0000000..b116ad0 --- /dev/null +++ b/gmp-6.3.0/mpz/limbs_write.c @@ -0,0 +1,38 @@ +/* mpz_limbs_write -- Write access to the mpn-style limb array. + +Copyright 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +mp_ptr +mpz_limbs_write (mpz_ptr x, mp_size_t n) +{ + ASSERT (n > 0); + return MPZ_NEWALLOC (x, n); +} diff --git a/gmp-6.3.0/mpz/lucmod.c b/gmp-6.3.0/mpz/lucmod.c new file mode 100644 index 0000000..0dad48c --- /dev/null +++ b/gmp-6.3.0/mpz/lucmod.c @@ -0,0 +1,127 @@ +/* mpz_lucas_mod -- Helper function for the strong Lucas + primality test. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2018 Free Software Foundation, Inc. + +Contributed by Marco Bodrato. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +/* Computes V_{k+1}, Q^{k+1} (mod n) for the Lucas' sequence */ +/* with P=1, Q=Q; k = n>>b0. */ +/* Requires n > 4; b0 > 0; -2*Q must not overflow a long. */ +/* If U_{k+1}==0 (mod n) or V_{k+1}==0 (mod n), it returns 1, */ +/* otherwise it returns 0 and sets V=V_{k+1} and Qk=Q^{k+1}. */ +/* V will never grow beyond SIZ(n), Qk not beyond 2*SIZ(n). */ +int +mpz_lucas_mod (mpz_ptr V, mpz_ptr Qk, long Q, + mp_bitcnt_t b0, mpz_srcptr n, mpz_ptr T1, mpz_ptr T2) +{ + mp_bitcnt_t bs; + int res; + + ASSERT (b0 > 0); + ASSERT (SIZ (n) > 1 || SIZ (n) > 0 && PTR (n) [0] > 4); + + mpz_set_ui (V, 1); /* U1 = 1 */ + bs = mpz_sizeinbase (n, 2) - 2; + if (UNLIKELY (bs < b0)) + { + /* n = 2^b0 - 1, should we use Lucas-Lehmer instead? */ + ASSERT (bs == b0 - 2); + mpz_set_si (Qk, Q); + return 0; + } + mpz_set_ui (Qk, 1); /* U2 = 1 */ + + do + { + /* We use the iteration suggested in "Elementary Number Theory" */ + /* by Peter Hackman (November 1, 2009), section "L.XVII Scalar */ + /* Formulas", from http://hackmat.se/kurser/TATM54/booktot.pdf */ + /* U_{2k} = 2*U_{k+1}*U_k - P*U_k^2 */ + /* U_{2k+1} = U_{k+1}^2 - Q*U_k^2 */ + /* U_{2k+2} = P*U_{k+1}^2 - 2*Q*U_{k+1}*U_k */ + /* We note that U_{2k+2} = P*U_{2k+1} - Q*U_{2k} */ + /* The formulas are specialized for P=1, and only squares: */ + /* U_{2k} = U_{k+1}^2 - |U_{k+1} - U_k|^2 */ + /* U_{2k+1} = U_{k+1}^2 - Q*U_k^2 */ + /* U_{2k+2} = U_{2k+1} - Q*U_{2k} */ + mpz_mul (T1, Qk, Qk); /* U_{k+1}^2 */ + mpz_sub (Qk, V, Qk); /* |U_{k+1} - U_k| */ + mpz_mul (T2, Qk, Qk); /* |U_{k+1} - U_k|^2 */ + mpz_mul (Qk, V, V); /* U_k^2 */ + mpz_sub (T2, T1, T2); /* U_{k+1}^2 - (U_{k+1} - U_k)^2 */ + if (Q > 0) /* U_{k+1}^2 - Q U_k^2 = U_{2k+1} */ + mpz_submul_ui (T1, Qk, Q); + else + mpz_addmul_ui (T1, Qk, NEG_CAST (unsigned long, Q)); + + /* A step k->k+1 is performed if the bit in $n$ is 1 */ + if (mpz_tstbit (n, bs)) + { + /* U_{2k+2} = U_{2k+1} - Q*U_{2k} */ + mpz_mul_si (T2, T2, Q); + mpz_sub (T2, T1, T2); + mpz_swap (T1, T2); + } + mpz_tdiv_r (Qk, T1, n); + mpz_tdiv_r (V, T2, n); + } while (--bs >= b0); + + res = SIZ (Qk) == 0; + if (!res) { + mpz_mul_si (T1, V, -2*Q); + mpz_add (T1, Qk, T1); /* V_k = U_k - 2Q*U_{k-1} */ + mpz_tdiv_r (V, T1, n); + res = SIZ (V) == 0; + if (!res && b0 > 1) { + /* V_k and Q^k will be needed for further check, compute them. */ + /* FIXME: Here we compute V_k^2 and store V_k, but the former */ + /* will be recomputed by the calling function, shoul we store */ + /* that instead? */ + mpz_mul (T2, T1, T1); /* V_k^2 */ + mpz_mul (T1, Qk, Qk); /* P^2 U_k^2 = U_k^2 */ + mpz_sub (T2, T2, T1); + ASSERT (SIZ (T2) == 0 || PTR (T2) [0] % 4 == 0); + mpz_tdiv_q_2exp (T2, T2, 2); /* (V_k^2 - P^2 U_k^2) / 4 */ + if (Q > 0) /* (V_k^2 - (P^2 -4Q) U_k^2) / 4 = Q^k */ + mpz_addmul_ui (T2, T1, Q); + else + mpz_submul_ui (T2, T1, NEG_CAST (unsigned long, Q)); + mpz_tdiv_r (Qk, T2, n); + } + } + + return res; +} diff --git a/gmp-6.3.0/mpz/lucnum2_ui.c b/gmp-6.3.0/mpz/lucnum2_ui.c new file mode 100644 index 0000000..3cc3d7b --- /dev/null +++ b/gmp-6.3.0/mpz/lucnum2_ui.c @@ -0,0 +1,94 @@ +/* mpz_lucnum2_ui -- calculate Lucas numbers. + +Copyright 2001, 2003, 2005, 2012, 2015, 2016, 2018 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + + +void +mpz_lucnum2_ui (mpz_ptr ln, mpz_ptr lnsub1, unsigned long n) +{ + mp_ptr lp, l1p, f1p; + mp_size_t size; + mp_limb_t c; + TMP_DECL; + + ASSERT (ln != lnsub1); + + /* handle small n quickly, and hide the special case for L[-1]=-1 */ + if (n <= FIB_TABLE_LUCNUM_LIMIT) + { + mp_limb_t f = FIB_TABLE (n); + mp_limb_t f1 = FIB_TABLE ((int) n - 1); + + /* L[n] = F[n] + 2F[n-1] */ + MPZ_NEWALLOC (ln, 1)[0] = f + 2*f1; + SIZ(ln) = 1; + + /* L[n-1] = 2F[n] - F[n-1], but allow for L[-1]=-1 */ + MPZ_NEWALLOC (lnsub1, 1)[0] = (n == 0 ? 1 : 2*f - f1); + SIZ(lnsub1) = (n == 0 ? -1 : 1); + + return; + } + + TMP_MARK; + size = MPN_FIB2_SIZE (n); + f1p = TMP_ALLOC_LIMBS (size); + + lp = MPZ_NEWALLOC (ln, size+1); + l1p = MPZ_NEWALLOC (lnsub1, size+1); + + size = mpn_fib2_ui (l1p, f1p, n); + + /* L[n] = F[n] + 2F[n-1] */ +#if HAVE_NATIVE_mpn_addlsh1_n + c = mpn_addlsh1_n (lp, l1p, f1p, size); +#else + c = mpn_lshift (lp, f1p, size, 1); + c += mpn_add_n (lp, lp, l1p, size); +#endif + lp[size] = c; + SIZ(ln) = size + (c != 0); + + /* L[n-1] = 2F[n] - F[n-1] */ +#if HAVE_NATIVE_mpn_rsblsh1_n + c = mpn_rsblsh1_n (l1p, f1p, l1p, size); +#else + c = mpn_lshift (l1p, l1p, size, 1); + c -= mpn_sub_n (l1p, l1p, f1p, size); +#endif + ASSERT ((mp_limb_signed_t) c >= 0); + l1p[size] = c; + SIZ(lnsub1) = size + (c != 0); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/lucnum_ui.c b/gmp-6.3.0/mpz/lucnum_ui.c new file mode 100644 index 0000000..4213bb7 --- /dev/null +++ b/gmp-6.3.0/mpz/lucnum_ui.c @@ -0,0 +1,208 @@ +/* mpz_lucnum_ui -- calculate Lucas number. + +Copyright 2001, 2003, 2005, 2011, 2012, 2015, 2016 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" + + +/* change this to "#define TRACE(x) x" for diagnostics */ +#define TRACE(x) + + +/* Notes: + + For the +4 in L[2k+1] when k is even, all L[4m+3] == 4, 5 or 7 mod 8, so + there can't be an overflow applying +4 to just the low limb (since that + would leave 0, 1, 2 or 3 mod 8). + + For the -4 in L[2k+1] when k is even, it seems (no proof) that + L[3*2^(b-2)-3] == -4 mod 2^b, so for instance with a 32-bit limb + L[0xBFFFFFFD] == 0xFFFFFFFC mod 2^32, and this implies a borrow from the + low limb. Obviously L[0xBFFFFFFD] is a huge number, but it's at least + conceivable to calculate it, so it probably should be handled. + + For the -2 in L[2k] with k even, it seems (no proof) L[2^(b-1)] == -1 mod + 2^b, so for instance in 32-bits L[0x80000000] has a low limb of + 0xFFFFFFFF so there would have been a borrow. Again L[0x80000000] is + obviously huge, but probably should be made to work. */ + +void +mpz_lucnum_ui (mpz_ptr ln, unsigned long n) +{ + mp_size_t lalloc, xalloc, lsize, xsize; + mp_ptr lp, xp; + mp_limb_t c; + int zeros; + TMP_DECL; + + TRACE (printf ("mpn_lucnum_ui n=%lu\n", n)); + + if (n <= FIB_TABLE_LUCNUM_LIMIT) + { + /* L[n] = F[n] + 2F[n-1] */ + MPZ_NEWALLOC (ln, 1)[0] = FIB_TABLE(n) + 2 * FIB_TABLE ((int) n - 1); + SIZ(ln) = 1; + return; + } + + /* +1 since L[n]=F[n]+2F[n-1] might be 1 limb bigger than F[n], further +1 + since square or mul used below might need an extra limb over the true + size */ + lalloc = MPN_FIB2_SIZE (n) + 2; + lp = MPZ_NEWALLOC (ln, lalloc); + + TMP_MARK; + xalloc = lalloc; + xp = TMP_ALLOC_LIMBS (xalloc); + + /* Strip trailing zeros from n, until either an odd number is reached + where the L[2k+1] formula can be used, or until n fits within the + FIB_TABLE data. The table is preferred of course. */ + zeros = 0; + for (;;) + { + if (n & 1) + { + /* L[2k+1] = 5*F[k-1]*(2*F[k]+F[k-1]) - 4*(-1)^k */ + + mp_size_t yalloc, ysize; + mp_ptr yp; + + TRACE (printf (" initial odd n=%lu\n", n)); + + yalloc = MPN_FIB2_SIZE (n/2); + yp = TMP_ALLOC_LIMBS (yalloc); + ASSERT (xalloc >= yalloc); + + xsize = mpn_fib2_ui (xp, yp, n/2); + + /* possible high zero on F[k-1] */ + ysize = xsize; + ysize -= (yp[ysize-1] == 0); + ASSERT (yp[ysize-1] != 0); + + /* xp = 2*F[k] + F[k-1] */ +#if HAVE_NATIVE_mpn_addlsh1_n + c = mpn_addlsh1_n (xp, yp, xp, xsize); +#else + c = mpn_lshift (xp, xp, xsize, 1); + c += mpn_add_n (xp, xp, yp, xsize); +#endif + ASSERT (xalloc >= xsize+1); + xp[xsize] = c; + xsize += (c != 0); + ASSERT (xp[xsize-1] != 0); + + ASSERT (lalloc >= xsize + ysize); + c = mpn_mul (lp, xp, xsize, yp, ysize); + lsize = xsize + ysize; + lsize -= (c == 0); + + /* lp = 5*lp */ +#if HAVE_NATIVE_mpn_addlsh2_n + c = mpn_addlsh2_n (lp, lp, lp, lsize); +#else + /* FIXME: Is this faster than mpn_mul_1 ? */ + c = mpn_lshift (xp, lp, lsize, 2); + c += mpn_add_n (lp, lp, xp, lsize); +#endif + ASSERT (lalloc >= lsize+1); + lp[lsize] = c; + lsize += (c != 0); + + /* lp = lp - 4*(-1)^k */ + if (n & 2) + { + /* no overflow, see comments above */ + ASSERT (lp[0] <= MP_LIMB_T_MAX-4); + lp[0] += 4; + } + else + { + /* won't go negative */ + MPN_DECR_U (lp, lsize, CNST_LIMB(4)); + } + + TRACE (mpn_trace (" l",lp, lsize)); + break; + } + + MP_PTR_SWAP (xp, lp); /* balance the swaps wanted in the L[2k] below */ + zeros++; + n /= 2; + + if (n <= FIB_TABLE_LUCNUM_LIMIT) + { + /* L[n] = F[n] + 2F[n-1] */ + lp[0] = FIB_TABLE (n) + 2 * FIB_TABLE ((int) n - 1); + lsize = 1; + + TRACE (printf (" initial small n=%lu\n", n); + mpn_trace (" l",lp, lsize)); + break; + } + } + + for ( ; zeros != 0; zeros--) + { + /* L[2k] = L[k]^2 + 2*(-1)^k */ + + TRACE (printf (" zeros=%d\n", zeros)); + + ASSERT (xalloc >= 2*lsize); + mpn_sqr (xp, lp, lsize); + lsize *= 2; + lsize -= (xp[lsize-1] == 0); + + /* First time around the loop k==n determines (-1)^k, after that k is + always even and we set n=0 to indicate that. */ + if (n & 1) + { + /* L[n]^2 == 0 or 1 mod 4, like all squares, so +2 gives no carry */ + ASSERT (xp[0] <= MP_LIMB_T_MAX-2); + xp[0] += 2; + n = 0; + } + else + { + /* won't go negative */ + MPN_DECR_U (xp, lsize, CNST_LIMB(2)); + } + + MP_PTR_SWAP (xp, lp); + ASSERT (lp[lsize-1] != 0); + } + + /* should end up in the right spot after all the xp/lp swaps */ + ASSERT (lp == PTR(ln)); + SIZ(ln) = lsize; + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/mfac_uiui.c b/gmp-6.3.0/mpz/mfac_uiui.c new file mode 100644 index 0000000..8595a9b --- /dev/null +++ b/gmp-6.3.0/mpz/mfac_uiui.c @@ -0,0 +1,140 @@ +/* mpz_mfac_uiui(RESULT, N, M) -- Set RESULT to N!^(M) = N(N-M)(N-2M)... + +Contributed to the GNU project by Marco Bodrato. + +Copyright 2012, 2013, 2015, 2016 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +/*************************************************************/ +/* Section macros: common macros, for swing/fac/bin (&sieve) */ +/*************************************************************/ + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +/*********************************************************/ +/* Section oder factorials: */ +/*********************************************************/ + +/* mpz_mfac_uiui (x, n, m) computes x = n!^(m) = n*(n-m)*(n-2m)*... */ + +void +mpz_mfac_uiui (mpz_ptr x, unsigned long n, unsigned long m) +{ + ASSERT (n <= GMP_NUMB_MAX); + ASSERT (m != 0); + + if ((n < 3) | (n - 3 < m - 1)) { /* (n < 3 || n - 1 <= m || m == 0) */ + MPZ_NEWALLOC (x, 1)[0] = n + (n == 0); + SIZ (x) = 1; + } else { /* 0 < m < n - 1 < GMP_NUMB_MAX */ + mp_limb_t g, sn; + mpz_t t; + + sn = n; + g = mpn_gcd_1 (&sn, 1, m); + if (g > 1) { n/=g; m/=g; } + + if (m <= 2) { /* fac or 2fac */ + if (m == 1) { + if (g > 2) { + mpz_init (t); + mpz_fac_ui (t, n); + sn = n; + } else { + if (g == 2) + mpz_2fac_ui (x, n << 1); + else + mpz_fac_ui (x, n); + return; + } + } else { /* m == 2 */ + if (g > 1) { + mpz_init (t); + mpz_2fac_ui (t, n); + sn = n / 2 + 1; + } else { + mpz_2fac_ui (x, n); + return; + } + } + } else { /* m >= 3, gcd(n,m) = 1 */ + mp_limb_t *factors; + mp_limb_t prod, max_prod; + mp_size_t j; + TMP_DECL; + + sn = n / m + 1; + + j = 0; + prod = n; + n -= m; + max_prod = GMP_NUMB_MAX / n; + + if (g > 1) + factors = MPZ_NEWALLOC (x, sn / log_n_max (n) + 2); + else { + TMP_MARK; + factors = TMP_ALLOC_LIMBS (sn / log_n_max (n) + 2); + } + + for (; n > m; n -= m) + FACTOR_LIST_STORE (n, prod, max_prod, factors, j); + + factors[j++] = n; + factors[j++] = prod; + + if (g > 1) { + mpz_init (t); + mpz_prodlimbs (t, factors, j); + } else { + mpz_prodlimbs (x, factors, j); + TMP_FREE; + return; + } + } + + { + mpz_t p; + + mpz_init (p); + mpz_ui_pow_ui (p, g, sn); /* g^sn */ + mpz_mul (x, p, t); + mpz_clear (p); + mpz_clear (t); + } + } +} diff --git a/gmp-6.3.0/mpz/millerrabin.c b/gmp-6.3.0/mpz/millerrabin.c new file mode 100644 index 0000000..98c4d6a --- /dev/null +++ b/gmp-6.3.0/mpz/millerrabin.c @@ -0,0 +1,216 @@ +/* mpz_millerrabin(n,reps) -- An implementation of the probabilistic primality + test found in Knuth's Seminumerical Algorithms book. If the function + mpz_millerrabin() returns 0 then n is not prime. If it returns 1, then n is + 'probably' prime. The probability of a false positive is (1/4)**reps, where + reps is the number of internal passes of the probabilistic algorithm. Knuth + indicates that 25 passes are reasonable. + + With the current implementation, the first 24 MR-tests are substituted by a + Baillie-PSW probable prime test. + + This implementation of the Baillie-PSW test was checked up to 2463*10^12, + for smaller values no MR-test is performed, regardless of reps, and + 2 ("surely prime") is returned if the number was not proved composite. + + If GMP_BPSW_NOFALSEPOSITIVES_UPTO_64BITS is defined as non-zero, + the code assumes that the Baillie-PSW test was checked up to 2^64. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 1991, 1993, 1994, 1996-2002, 2005, 2014, 2018-2022 Free +Software Foundation, Inc. + +Contributed by John Amanatides. +Changed to "BPSW, then Miller Rabin if required" by Marco Bodrato. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +#ifndef GMP_BPSW_NOFALSEPOSITIVES_UPTO_64BITS +#define GMP_BPSW_NOFALSEPOSITIVES_UPTO_64BITS 0 +#endif + +static int millerrabin (mpz_srcptr, + mpz_ptr, mpz_ptr, + mpz_srcptr, unsigned long int); + +int +mpz_millerrabin (mpz_srcptr n, int reps) +{ + mpz_t nm, x, y, q; + mp_bitcnt_t k; + int is_prime; + TMP_DECL; + TMP_MARK; + + ASSERT (SIZ (n) > 0); + MPZ_TMP_INIT (nm, SIZ (n) + 1); + mpz_tdiv_q_2exp (nm, n, 1); + + MPZ_TMP_INIT (x, SIZ (n) + 1); + MPZ_TMP_INIT (y, 2 * SIZ (n)); /* mpz_powm_ui needs excessive memory!!! */ + MPZ_TMP_INIT (q, SIZ (n)); + + /* Find q and k, where q is odd and n = 1 + 2**k * q. */ + k = mpn_scan1 (PTR (nm), 0); + mpz_tdiv_q_2exp (q, nm, k); + ++k; + + /* BPSW test */ + mpz_set_ui (x, 2); + is_prime = millerrabin (n, x, y, q, k) && mpz_stronglucas (n, x, y); + + if (is_prime) + { + if ( +#if GMP_BPSW_NOFALSEPOSITIVES_UPTO_64BITS + /* Consider numbers up to 2^64 that pass the BPSW test as primes. */ +#if GMP_NUMB_BITS <= 64 + SIZ (n) <= 64 / GMP_NUMB_BITS +#else + 0 +#endif +#if 64 % GMP_NUMB_BITS != 0 + || SIZ (n) - 64 / GMP_NUMB_BITS == (PTR (n) [64 / GMP_NUMB_BITS] < CNST_LIMB(1) << 64 % GMP_NUMB_BITS) +#endif +#else + /* Consider numbers up to 35*2^46 that pass the BPSW test as primes. + This implementation was tested up to 2463*10^12 > 2^51+2^47+2^46 */ + /* 2^5 < 35 = 0b100011 < 2^6 */ +#define GMP_BPSW_LIMB_CONST CNST_LIMB(35) +#define GMP_BPSW_BITS_CONST (LOG2C(35) - 1) +#define GMP_BPSW_BITS_LIMIT (46 + GMP_BPSW_BITS_CONST) + +#define GMP_BPSW_LIMBS_LIMIT (GMP_BPSW_BITS_LIMIT / GMP_NUMB_BITS) +#define GMP_BPSW_BITS_MOD (GMP_BPSW_BITS_LIMIT % GMP_NUMB_BITS) + +#if GMP_NUMB_BITS <= GMP_BPSW_BITS_LIMIT + SIZ (n) <= GMP_BPSW_LIMBS_LIMIT +#else + 0 +#endif +#if GMP_BPSW_BITS_MOD >= GMP_BPSW_BITS_CONST + || SIZ (n) - GMP_BPSW_LIMBS_LIMIT == (PTR (n) [GMP_BPSW_LIMBS_LIMIT] < GMP_BPSW_LIMB_CONST << (GMP_BPSW_BITS_MOD - GMP_BPSW_BITS_CONST)) +#else +#if GMP_BPSW_BITS_MOD != 0 + || SIZ (n) - GMP_BPSW_LIMBS_LIMIT == (PTR (n) [GMP_BPSW_LIMBS_LIMIT] < GMP_BPSW_LIMB_CONST >> (GMP_BPSW_BITS_CONST - GMP_BPSW_BITS_MOD)) +#else +#if GMP_NUMB_BITS > GMP_BPSW_BITS_CONST + || SIZ (nm) - GMP_BPSW_LIMBS_LIMIT + 1 == (PTR (nm) [GMP_BPSW_LIMBS_LIMIT - 1] < GMP_BPSW_LIMB_CONST << (GMP_NUMB_BITS - 1 - GMP_BPSW_BITS_CONST)) +#endif +#endif +#endif + +#undef GMP_BPSW_BITS_LIMIT +#undef GMP_BPSW_LIMB_CONST +#undef GMP_BPSW_BITS_CONST +#undef GMP_BPSW_LIMBS_LIMIT +#undef GMP_BPSW_BITS_MOD + +#endif + ) + is_prime = 2; + else + { + reps -= 24; + if (reps > 0) + { + gmp_randstate_t rstate; + /* (n-5)/2 */ + mpz_sub_ui (nm, nm, 2L); + ASSERT (mpz_cmp_ui (nm, 1L) >= 0); + + gmp_randinit_default (rstate); + + do + { + /* 3 to (n-1)/2 inclusive, don't want 1, 0 or 2 */ + mpz_urandomm (x, rstate, nm); + mpz_add_ui (x, x, 3L); + + is_prime = millerrabin (n, x, y, q, k); + } while (--reps > 0 && is_prime); + + gmp_randclear (rstate); + } + } + } + TMP_FREE; + return is_prime; +} + +static int +mod_eq_m1 (mpz_srcptr x, mpz_srcptr m) +{ + mp_size_t ms; + mp_srcptr mp, xp; + + ms = SIZ (m); + if (SIZ (x) != ms) + return 0; + ASSERT (ms > 0); + + mp = PTR (m); + xp = PTR (x); + ASSERT ((mp[0] - 1) == (mp[0] ^ 1)); /* n is odd */ + + if ((*xp ^ CNST_LIMB(1) ^ *mp) != CNST_LIMB(0)) /* xp[0] != mp[0] - 1 */ + return 0; + else + { + int cmp; + + --ms; + ++xp; + ++mp; + + MPN_CMP (cmp, xp, mp, ms); + + return cmp == 0; + } +} + +static int +millerrabin (mpz_srcptr n, mpz_ptr x, mpz_ptr y, + mpz_srcptr q, mp_bitcnt_t k) +{ + mpz_powm (y, x, q, n); + + if (mpz_cmp_ui (y, 1L) == 0 || mod_eq_m1 (y, n)) + return 1; + + for (mp_bitcnt_t i = 1; i < k; ++i) + { + mpz_powm_ui (y, y, 2L, n); + if (mod_eq_m1 (y, n)) + return 1; + } + return 0; +} diff --git a/gmp-6.3.0/mpz/mod.c b/gmp-6.3.0/mpz/mod.c new file mode 100644 index 0000000..ab5cdb1 --- /dev/null +++ b/gmp-6.3.0/mpz/mod.c @@ -0,0 +1,67 @@ +/* mpz_mod -- The mathematical mod function. + +Copyright 1991, 1993-1996, 2001, 2002, 2005, 2010, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_mod (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) +{ + mp_size_t rn, bn; + mpz_t temp_divisor; + TMP_DECL; + + TMP_MARK; + + bn = ABSIZ(divisor); + + /* We need the original value of the divisor after the remainder has been + preliminary calculated. We have to copy it to temporary space if it's + the same variable as REM. */ + if (rem == divisor) + { + PTR(temp_divisor) = TMP_ALLOC_LIMBS (bn); + MPN_COPY (PTR(temp_divisor), PTR(divisor), bn); + } + else + { + PTR(temp_divisor) = PTR(divisor); + } + SIZ(temp_divisor) = bn; + divisor = temp_divisor; + + mpz_tdiv_r (rem, dividend, divisor); + + rn = SIZ (rem); + if (rn < 0) + mpz_add (rem, rem, divisor); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/mul.c b/gmp-6.3.0/mpz/mul.c new file mode 100644 index 0000000..a70df9f --- /dev/null +++ b/gmp-6.3.0/mpz/mul.c @@ -0,0 +1,159 @@ +/* mpz_mul -- Multiply two integers. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2009, 2011, 2012, +2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + + +void +mpz_mul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) +{ + mp_size_t usize; + mp_size_t vsize; + mp_size_t wsize; + mp_size_t sign_product; + mp_ptr up, vp; + mp_ptr wp; + mp_ptr free_me; + size_t free_me_size; + mp_limb_t cy_limb; + TMP_DECL; + + usize = SIZ (u); + vsize = SIZ (v); + sign_product = usize ^ vsize; + usize = ABS (usize); + vsize = ABS (vsize); + + if (usize < vsize) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (usize, vsize); + } + + if (vsize == 0) + { + SIZ (w) = 0; + return; + } + +#if HAVE_NATIVE_mpn_mul_2 + if (vsize <= 2) + { + wp = MPZ_REALLOC (w, usize+vsize); + if (vsize == 1) + cy_limb = mpn_mul_1 (wp, PTR (u), usize, PTR (v)[0]); + else + { + cy_limb = mpn_mul_2 (wp, PTR (u), usize, PTR (v)); + usize++; + } + wp[usize] = cy_limb; + usize += (cy_limb != 0); + SIZ (w) = (sign_product >= 0 ? usize : -usize); + return; + } +#else + if (vsize == 1) + { + wp = MPZ_REALLOC (w, usize+1); + cy_limb = mpn_mul_1 (wp, PTR (u), usize, PTR (v)[0]); + wp[usize] = cy_limb; + usize += (cy_limb != 0); + SIZ (w) = (sign_product >= 0 ? usize : -usize); + return; + } +#endif + + TMP_MARK; + free_me = NULL; + up = PTR (u); + vp = PTR (v); + wp = PTR (w); + + /* Ensure W has space enough to store the result. */ + wsize = usize + vsize; + if (ALLOC (w) < wsize) + { + if (ALLOC (w) != 0) + { + if (wp == up || wp == vp) + { + free_me = wp; + free_me_size = ALLOC (w); + } + else + (*__gmp_free_func) (wp, (size_t) ALLOC (w) * GMP_LIMB_BYTES); + } + + ALLOC (w) = wsize; + wp = __GMP_ALLOCATE_FUNC_LIMBS (wsize); + PTR (w) = wp; + } + else + { + /* Make U and V not overlap with W. */ + if (wp == up) + { + /* W and U are identical. Allocate temporary space for U. */ + up = TMP_ALLOC_LIMBS (usize); + /* Is V identical too? Keep it identical with U. */ + if (wp == vp) + vp = up; + /* Copy to the temporary space. */ + MPN_COPY (up, wp, usize); + } + else if (wp == vp) + { + /* W and V are identical. Allocate temporary space for V. */ + vp = TMP_ALLOC_LIMBS (vsize); + /* Copy to the temporary space. */ + MPN_COPY (vp, wp, vsize); + } + } + + if (up == vp) + { + mpn_sqr (wp, up, usize); + cy_limb = wp[wsize - 1]; + } + else + { + cy_limb = mpn_mul (wp, up, usize, vp, vsize); + } + + wsize -= cy_limb == 0; + + SIZ (w) = sign_product < 0 ? -wsize : wsize; + if (free_me != NULL) + (*__gmp_free_func) (free_me, free_me_size * GMP_LIMB_BYTES); + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/mul_2exp.c b/gmp-6.3.0/mpz/mul_2exp.c new file mode 100644 index 0000000..6144d0d --- /dev/null +++ b/gmp-6.3.0/mpz/mul_2exp.c @@ -0,0 +1,72 @@ +/* mpz_mul_2exp -- Multiply a bignum by 2**CNT + +Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_mul_2exp (mpz_ptr r, mpz_srcptr u, mp_bitcnt_t cnt) +{ + mp_size_t un, rn; + mp_size_t limb_cnt; + mp_ptr rp; + mp_srcptr up; + mp_limb_t rlimb; + + un = ABSIZ (u); + limb_cnt = cnt / GMP_NUMB_BITS; + rn = un + limb_cnt; + + if (un == 0) + rn = 0; + else + { + rp = MPZ_REALLOC (r, rn + 1); + up = PTR(u); + + cnt %= GMP_NUMB_BITS; + if (cnt != 0) + { + rlimb = mpn_lshift (rp + limb_cnt, up, un, cnt); + rp[rn] = rlimb; + rn += (rlimb != 0); + } + else + { + MPN_COPY_DECR (rp + limb_cnt, up, un); + } + + /* Zero all whole limbs at low end. Do it here and not before calling + mpn_lshift, not to lose for U == R. */ + MPN_ZERO (rp, limb_cnt); + } + + SIZ(r) = SIZ(u) >= 0 ? rn : -rn; +} diff --git a/gmp-6.3.0/mpz/mul_i.h b/gmp-6.3.0/mpz/mul_i.h new file mode 100644 index 0000000..65c9c2f --- /dev/null +++ b/gmp-6.3.0/mpz/mul_i.h @@ -0,0 +1,106 @@ +/* mpz_mul_ui/si (product, multiplier, small_multiplicand) -- Set PRODUCT to + MULTIPLICATOR times SMALL_MULTIPLICAND. + +Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2008, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +#ifdef OPERATION_mul_si +#define FUNCTION mpz_mul_si +#define MULTIPLICAND_UNSIGNED +#define MULTIPLICAND_ABS(x) ABS_CAST(unsigned long, (x)) +#endif + +#ifdef OPERATION_mul_ui +#define FUNCTION mpz_mul_ui +#define MULTIPLICAND_UNSIGNED unsigned +#define MULTIPLICAND_ABS(x) x +#endif + +#ifndef FUNCTION +Error, error, unrecognised OPERATION +#endif + + +void +FUNCTION (mpz_ptr prod, mpz_srcptr mult, + MULTIPLICAND_UNSIGNED long int small_mult) +{ + mp_size_t size; + mp_size_t sign_product; + mp_limb_t sml; + mp_limb_t cy; + mp_ptr pp; + + sign_product = SIZ(mult); + if (sign_product == 0 || small_mult == 0) + { + SIZ(prod) = 0; + return; + } + + size = ABS (sign_product); + + sml = MULTIPLICAND_ABS (small_mult); + + if (sml <= GMP_NUMB_MAX) + { + pp = MPZ_REALLOC (prod, size + 1); + cy = mpn_mul_1 (pp, PTR(mult), size, sml); + pp[size] = cy; + size += cy != 0; + } +#if GMP_NAIL_BITS != 0 + else + { + /* Operand too large for the current nails size. Use temporary for + intermediate products, to allow prod and mult being identical. */ + mp_ptr tp; + TMP_DECL; + TMP_MARK; + + tp = TMP_ALLOC_LIMBS (size + 2); + + /* Use, maybe, mpn_mul_2? */ + cy = mpn_mul_1 (tp, PTR(mult), size, sml & GMP_NUMB_MASK); + tp[size] = cy; + cy = mpn_addmul_1 (tp + 1, PTR(mult), size, sml >> GMP_NUMB_BITS); + tp[size + 1] = cy; + size += 2; + MPN_NORMALIZE_NOT_ZERO (tp, size); /* too general, need to trim one or two limb */ + pp = MPZ_NEWALLOC (prod, size); + MPN_COPY (pp, tp, size); + TMP_FREE; + } +#endif + + SIZ(prod) = ((sign_product < 0) ^ (small_mult < 0)) ? -size : size; +} diff --git a/gmp-6.3.0/mpz/mul_si.c b/gmp-6.3.0/mpz/mul_si.c new file mode 100644 index 0000000..9f29f60 --- /dev/null +++ b/gmp-6.3.0/mpz/mul_si.c @@ -0,0 +1,34 @@ +/* mpz_mul_si (product, multiplier, small_multiplicand) -- Set PRODUCT to + MULTIPLICATOR times SMALL_MULTIPLICAND. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_mul_si +#include "mul_i.h" diff --git a/gmp-6.3.0/mpz/mul_ui.c b/gmp-6.3.0/mpz/mul_ui.c new file mode 100644 index 0000000..d398c4f --- /dev/null +++ b/gmp-6.3.0/mpz/mul_ui.c @@ -0,0 +1,34 @@ +/* mpz_mul_ui (product, multiplier, small_multiplicand) -- Set PRODUCT to + MULTIPLICATOR times SMALL_MULTIPLICAND. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_mul_ui +#include "mul_i.h" diff --git a/gmp-6.3.0/mpz/n_pow_ui.c b/gmp-6.3.0/mpz/n_pow_ui.c new file mode 100644 index 0000000..cf293f5 --- /dev/null +++ b/gmp-6.3.0/mpz/n_pow_ui.c @@ -0,0 +1,532 @@ +/* mpz_n_pow_ui -- mpn raised to ulong. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2001, 2002, 2005, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* Change this to "#define TRACE(x) x" for some traces. */ +#define TRACE(x) + + +/* Use this to test the mul_2 code on a CPU without a native version of that + routine. */ +#if 0 +#define mpn_mul_2 refmpn_mul_2 +#define HAVE_NATIVE_mpn_mul_2 1 +#endif + + +/* mpz_pow_ui and mpz_ui_pow_ui want to share almost all of this code. + ui_pow_ui doesn't need the mpn_mul based powering loop or the tests on + bsize==2 or >2, but separating that isn't easy because there's shared + code both before and after (the size calculations and the powers of 2 + handling). + + Alternatives: + + It would work to just use the mpn_mul powering loop for 1 and 2 limb + bases, but the current separate loop allows mul_1 and mul_2 to be done + in-place, which might help cache locality a bit. If mpn_mul was relaxed + to allow source==dest when vn==1 or 2 then some pointer twiddling might + let us get the same effect in one loop. + + The initial powering for bsize==1 into blimb or blimb:blimb_low doesn't + form the biggest possible power of b that fits, only the biggest power of + 2 power, ie. b^(2^n). It'd be possible to choose a bigger power, perhaps + using mp_bases[b].big_base for small b, and thereby get better value + from mpn_mul_1 or mpn_mul_2 in the bignum powering. It's felt that doing + so would be more complicated than it's worth, and could well end up being + a slowdown for small e. For big e on the other hand the algorithm is + dominated by mpn_sqr so there wouldn't much of a saving. The current + code can be viewed as simply doing the first few steps of the powering in + a single or double limb where possible. + + If r==b, and blow_twos==0, and r must be realloc'ed, then the temporary + copy made of b is unnecessary. We could just use the old alloc'ed block + and free it at the end. But arranging this seems like a lot more trouble + than it's worth. */ + + +/* floor(sqrt(GMP_NUMB_MAX)), ie. the biggest value that can be squared in + a limb without overflowing. + FIXME: This formula is an underestimate when GMP_NUMB_BITS is odd. */ + +#define GMP_NUMB_HALFMAX (((mp_limb_t) 1 << GMP_NUMB_BITS/2) - 1) + + +/* The following are for convenience, they update the size and check the + alloc. */ + +#define MPN_SQR(dst, alloc, src, size) \ + do { \ + ASSERT (2*(size) <= (alloc)); \ + mpn_sqr (dst, src, size); \ + (size) *= 2; \ + (size) -= ((dst)[(size)-1] == 0); \ + } while (0) + +#define MPN_MUL(dst, alloc, src, size, src2, size2) \ + do { \ + mp_limb_t cy; \ + ASSERT ((size) + (size2) <= (alloc)); \ + cy = mpn_mul (dst, src, size, src2, size2); \ + (size) += (size2) - (cy == 0); \ + } while (0) + +#define MPN_MUL_2(ptr, size, alloc, mult) \ + do { \ + mp_limb_t cy; \ + ASSERT ((size)+2 <= (alloc)); \ + cy = mpn_mul_2 (ptr, ptr, size, mult); \ + (size)++; \ + (ptr)[(size)] = cy; \ + (size) += (cy != 0); \ + } while (0) + +#define MPN_MUL_1(ptr, size, alloc, limb) \ + do { \ + mp_limb_t cy; \ + ASSERT ((size)+1 <= (alloc)); \ + cy = mpn_mul_1 (ptr, ptr, size, limb); \ + (ptr)[size] = cy; \ + (size) += (cy != 0); \ + } while (0) + +#define MPN_LSHIFT(ptr, size, alloc, shift) \ + do { \ + mp_limb_t cy; \ + ASSERT ((size)+1 <= (alloc)); \ + cy = mpn_lshift (ptr, ptr, size, shift); \ + (ptr)[size] = cy; \ + (size) += (cy != 0); \ + } while (0) + +#define MPN_RSHIFT_OR_COPY(dst, src, size, shift) \ + do { \ + if ((shift) == 0) \ + MPN_COPY (dst, src, size); \ + else \ + { \ + mpn_rshift (dst, src, size, shift); \ + (size) -= ((dst)[(size)-1] == 0); \ + } \ + } while (0) + + +/* ralloc and talloc are only wanted for ASSERTs, after the initial space + allocations. Avoid writing values to them in a normal build, to ensure + the compiler lets them go dead. gcc already figures this out itself + actually. */ + +#define SWAP_RP_TP \ + do { \ + MP_PTR_SWAP (rp, tp); \ + ASSERT_CODE (MP_SIZE_T_SWAP (ralloc, talloc)); \ + } while (0) + + +void +mpz_n_pow_ui (mpz_ptr r, mp_srcptr bp, mp_size_t bsize, unsigned long int e) +{ + mp_ptr rp; + mp_size_t rtwos_limbs, ralloc, rsize; + int rneg, i, cnt, btwos, r_bp_overlap; + mp_limb_t blimb, rl; + mp_bitcnt_t rtwos_bits; +#if HAVE_NATIVE_mpn_mul_2 + mp_limb_t blimb_low, rl_high; +#else + mp_limb_t b_twolimbs[2]; +#endif + TMP_DECL; + + TRACE (printf ("mpz_n_pow_ui rp=0x%lX bp=0x%lX bsize=%ld e=%lu (0x%lX)\n", + PTR(r), bp, bsize, e, e); + mpn_trace ("b", bp, bsize)); + + ASSERT (bsize == 0 || bp[ABS(bsize)-1] != 0); + ASSERT (MPN_SAME_OR_SEPARATE2_P (PTR(r), ALLOC(r), bp, ABS(bsize))); + + /* b^0 == 1, including 0^0 == 1 */ + if (e == 0) + { + MPZ_NEWALLOC (r, 1)[0] = 1; + SIZ(r) = 1; + return; + } + + /* 0^e == 0 apart from 0^0 above */ + if (bsize == 0) + { + SIZ(r) = 0; + return; + } + + /* Sign of the final result. */ + rneg = (bsize < 0 && (e & 1) != 0); + bsize = ABS (bsize); + TRACE (printf ("rneg %d\n", rneg)); + + r_bp_overlap = (PTR(r) == bp); + + /* Strip low zero limbs from b. */ + rtwos_limbs = 0; + for (blimb = *bp; blimb == 0; blimb = *++bp) + { + rtwos_limbs += e; + bsize--; ASSERT (bsize >= 1); + } + TRACE (printf ("trailing zero rtwos_limbs=%ld\n", rtwos_limbs)); + + /* Strip low zero bits from b. */ + count_trailing_zeros (btwos, blimb); + blimb >>= btwos; + rtwos_bits = e * btwos; + rtwos_limbs += rtwos_bits / GMP_NUMB_BITS; + rtwos_bits %= GMP_NUMB_BITS; + TRACE (printf ("trailing zero btwos=%d rtwos_limbs=%ld rtwos_bits=%lu\n", + btwos, rtwos_limbs, rtwos_bits)); + + TMP_MARK; + + rl = 1; +#if HAVE_NATIVE_mpn_mul_2 + rl_high = 0; +#endif + + if (bsize == 1) + { + bsize_1: + /* Power up as far as possible within blimb. We start here with e!=0, + but if e is small then we might reach e==0 and the whole b^e in rl. + Notice this code works when blimb==1 too, reaching e==0. */ + + while (blimb <= GMP_NUMB_HALFMAX) + { + TRACE (printf ("small e=0x%lX blimb=0x%lX rl=0x%lX\n", + e, blimb, rl)); + ASSERT (e != 0); + if ((e & 1) != 0) + rl *= blimb; + e >>= 1; + if (e == 0) + goto got_rl; + blimb *= blimb; + } + +#if HAVE_NATIVE_mpn_mul_2 + TRACE (printf ("single power, e=0x%lX b=0x%lX rl=0x%lX\n", + e, blimb, rl)); + + /* Can power b once more into blimb:blimb_low */ + bsize = 2; + ASSERT (e != 0); + if ((e & 1) != 0) + { + umul_ppmm (rl_high, rl, rl, blimb << GMP_NAIL_BITS); + rl >>= GMP_NAIL_BITS; + } + e >>= 1; + umul_ppmm (blimb, blimb_low, blimb, blimb << GMP_NAIL_BITS); + blimb_low >>= GMP_NAIL_BITS; + + got_rl: + TRACE (printf ("double power e=0x%lX blimb=0x%lX:0x%lX rl=0x%lX:%lX\n", + e, blimb, blimb_low, rl_high, rl)); + + /* Combine left-over rtwos_bits into rl_high:rl to be handled by the + final mul_1 or mul_2 rather than a separate lshift. + - rl_high:rl mustn't be 1 (since then there's no final mul) + - rl_high mustn't overflow + - rl_high mustn't change to non-zero, since mul_1+lshift is + probably faster than mul_2 (FIXME: is this true?) */ + + if (rtwos_bits != 0 + && ! (rl_high == 0 && rl == 1) + && (rl_high >> (GMP_NUMB_BITS-rtwos_bits)) == 0) + { + mp_limb_t new_rl_high = (rl_high << rtwos_bits) + | (rl >> (GMP_NUMB_BITS-rtwos_bits)); + if (! (rl_high == 0 && new_rl_high != 0)) + { + rl_high = new_rl_high; + rl <<= rtwos_bits; + rtwos_bits = 0; + TRACE (printf ("merged rtwos_bits, rl=0x%lX:%lX\n", + rl_high, rl)); + } + } +#else + got_rl: + TRACE (printf ("small power e=0x%lX blimb=0x%lX rl=0x%lX\n", + e, blimb, rl)); + + /* Combine left-over rtwos_bits into rl to be handled by the final + mul_1 rather than a separate lshift. + - rl mustn't be 1 (since then there's no final mul) + - rl mustn't overflow */ + + if (rtwos_bits != 0 + && rl != 1 + && (rl >> (GMP_NUMB_BITS-rtwos_bits)) == 0) + { + rl <<= rtwos_bits; + rtwos_bits = 0; + TRACE (printf ("merged rtwos_bits, rl=0x%lX\n", rl)); + } +#endif + } + else if (bsize == 2) + { + mp_limb_t bsecond = bp[1]; + if (btwos != 0) + blimb |= (bsecond << (GMP_NUMB_BITS - btwos)) & GMP_NUMB_MASK; + bsecond >>= btwos; + if (bsecond == 0) + { + /* Two limbs became one after rshift. */ + bsize = 1; + goto bsize_1; + } + + TRACE (printf ("bsize==2 using b=0x%lX:%lX", bsecond, blimb)); +#if HAVE_NATIVE_mpn_mul_2 + blimb_low = blimb; +#else + bp = b_twolimbs; + b_twolimbs[0] = blimb; + b_twolimbs[1] = bsecond; +#endif + blimb = bsecond; + } + else + { + if (r_bp_overlap || btwos != 0) + { + mp_ptr tp = TMP_ALLOC_LIMBS (bsize); + MPN_RSHIFT_OR_COPY (tp, bp, bsize, btwos); + bp = tp; + TRACE (printf ("rshift or copy bp,bsize, new bsize=%ld\n", bsize)); + } +#if HAVE_NATIVE_mpn_mul_2 + /* in case 3 limbs rshift to 2 and hence use the mul_2 loop below */ + blimb_low = bp[0]; +#endif + blimb = bp[bsize-1]; + + TRACE (printf ("big bsize=%ld ", bsize); + mpn_trace ("b", bp, bsize)); + } + + /* At this point blimb is the most significant limb of the base to use. + + Each factor of b takes (bsize*BPML-cnt) bits and there's e of them; +1 + limb to round up the division; +1 for multiplies all using an extra + limb over the true size; +2 for rl at the end; +1 for lshift at the + end. + + The size calculation here is reasonably accurate. The base is at least + half a limb, so in 32 bits the worst case is 2^16+1 treated as 17 bits + when it will power up as just over 16, an overestimate of 17/16 = + 6.25%. For a 64-bit limb it's half that. + + If e==0 then blimb won't be anything useful (though it will be + non-zero), but that doesn't matter since we just end up with ralloc==5, + and that's fine for 2 limbs of rl and 1 of lshift. */ + + ASSERT (blimb != 0); + count_leading_zeros (cnt, blimb); + ralloc = (bsize*GMP_NUMB_BITS - cnt + GMP_NAIL_BITS) * e / GMP_NUMB_BITS + 5; + TRACE (printf ("ralloc %ld, from bsize=%ld blimb=0x%lX cnt=%d\n", + ralloc, bsize, blimb, cnt)); + rp = MPZ_NEWALLOC (r, ralloc + rtwos_limbs); + + /* Low zero limbs resulting from powers of 2. */ + MPN_ZERO (rp, rtwos_limbs); + rp += rtwos_limbs; + + if (e == 0) + { + /* Any e==0 other than via bsize==1 or bsize==2 is covered at the + start. */ + rp[0] = rl; + rsize = 1; +#if HAVE_NATIVE_mpn_mul_2 + rp[1] = rl_high; + rsize += (rl_high != 0); +#endif + ASSERT (rp[rsize-1] != 0); + } + else + { + mp_ptr tp; + mp_size_t talloc; + + /* In the mpn_mul_1 or mpn_mul_2 loops or in the mpn_mul loop when the + low bit of e is zero, tp only has to hold the second last power + step, which is half the size of the final result. There's no need + to round up the divide by 2, since ralloc includes a +2 for rl + which not needed by tp. In the mpn_mul loop when the low bit of e + is 1, tp must hold nearly the full result, so just size it the same + as rp. */ + + talloc = ralloc; +#if HAVE_NATIVE_mpn_mul_2 + if (bsize <= 2 || (e & 1) == 0) + talloc /= 2; +#else + if (bsize <= 1 || (e & 1) == 0) + talloc /= 2; +#endif + TRACE (printf ("talloc %ld\n", talloc)); + tp = TMP_ALLOC_LIMBS (talloc); + + /* Go from high to low over the bits of e, starting with i pointing at + the bit below the highest 1 (which will mean i==-1 if e==1). */ + count_leading_zeros (cnt, (mp_limb_t) e); + i = GMP_LIMB_BITS - cnt - 2; + +#if HAVE_NATIVE_mpn_mul_2 + if (bsize <= 2) + { + mp_limb_t mult[2]; + + /* Any bsize==1 will have been powered above to be two limbs. */ + ASSERT (bsize == 2); + ASSERT (blimb != 0); + + /* Arrange the final result ends up in r, not in the temp space */ + if ((i & 1) == 0) + SWAP_RP_TP; + + rp[0] = blimb_low; + rp[1] = blimb; + rsize = 2; + + mult[0] = blimb_low; + mult[1] = blimb; + + for ( ; i >= 0; i--) + { + TRACE (printf ("mul_2 loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n", + i, e, rsize, ralloc, talloc); + mpn_trace ("r", rp, rsize)); + + MPN_SQR (tp, talloc, rp, rsize); + SWAP_RP_TP; + if ((e & (1L << i)) != 0) + MPN_MUL_2 (rp, rsize, ralloc, mult); + } + + TRACE (mpn_trace ("mul_2 before rl, r", rp, rsize)); + if (rl_high != 0) + { + mult[0] = rl; + mult[1] = rl_high; + MPN_MUL_2 (rp, rsize, ralloc, mult); + } + else if (rl != 1) + MPN_MUL_1 (rp, rsize, ralloc, rl); + } +#else + if (bsize == 1) + { + /* Arrange the final result ends up in r, not in the temp space */ + if ((i & 1) == 0) + SWAP_RP_TP; + + rp[0] = blimb; + rsize = 1; + + for ( ; i >= 0; i--) + { + TRACE (printf ("mul_1 loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n", + i, e, rsize, ralloc, talloc); + mpn_trace ("r", rp, rsize)); + + MPN_SQR (tp, talloc, rp, rsize); + SWAP_RP_TP; + if ((e & (1L << i)) != 0) + MPN_MUL_1 (rp, rsize, ralloc, blimb); + } + + TRACE (mpn_trace ("mul_1 before rl, r", rp, rsize)); + if (rl != 1) + MPN_MUL_1 (rp, rsize, ralloc, rl); + } +#endif + else + { + int parity; + + /* Arrange the final result ends up in r, not in the temp space */ + ULONG_PARITY (parity, e); + if (((parity ^ i) & 1) != 0) + SWAP_RP_TP; + + MPN_COPY (rp, bp, bsize); + rsize = bsize; + + for ( ; i >= 0; i--) + { + TRACE (printf ("mul loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n", + i, e, rsize, ralloc, talloc); + mpn_trace ("r", rp, rsize)); + + MPN_SQR (tp, talloc, rp, rsize); + SWAP_RP_TP; + if ((e & (1L << i)) != 0) + { + MPN_MUL (tp, talloc, rp, rsize, bp, bsize); + SWAP_RP_TP; + } + } + } + } + + ASSERT (rp == PTR(r) + rtwos_limbs); + TRACE (mpn_trace ("end loop r", rp, rsize)); + TMP_FREE; + + /* Apply any partial limb factors of 2. */ + if (rtwos_bits != 0) + { + MPN_LSHIFT (rp, rsize, ralloc, (unsigned) rtwos_bits); + TRACE (mpn_trace ("lshift r", rp, rsize)); + } + + rsize += rtwos_limbs; + SIZ(r) = (rneg ? -rsize : rsize); +} diff --git a/gmp-6.3.0/mpz/neg.c b/gmp-6.3.0/mpz/neg.c new file mode 100644 index 0000000..7f3fbcf --- /dev/null +++ b/gmp-6.3.0/mpz/neg.c @@ -0,0 +1,56 @@ +/* mpz_neg(mpz_ptr dst, mpz_ptr src) -- Assign the negated value of SRC to DST. + +Copyright 1991, 1993-1995, 2001, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_neg 1 + +#include "gmp-impl.h" + +void +mpz_neg (mpz_ptr w, mpz_srcptr u) +{ + mp_ptr wp; + mp_srcptr up; + mp_size_t usize, size; + + usize = SIZ (u); + + if (u != w) + { + size = ABS (usize); + + wp = MPZ_NEWALLOC (w, size); + + up = PTR (u); + + MPN_COPY (wp, up, size); + } + + SIZ (w) = -usize; +} diff --git a/gmp-6.3.0/mpz/nextprime.c b/gmp-6.3.0/mpz/nextprime.c new file mode 100644 index 0000000..2fe2616 --- /dev/null +++ b/gmp-6.3.0/mpz/nextprime.c @@ -0,0 +1,291 @@ +/* mpz_nextprime(p,t) - compute the next prime > t and store that in p. + +Copyright 1999-2001, 2008, 2009, 2012, 2020-2022 Free Software +Foundation, Inc. + +Contributed to the GNU project by Niels Möller and Torbjorn Granlund. +Improved by Seth Troisi. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include + +#include "gmp-impl.h" +#include "longlong.h" + +/*********************************************************/ +/* Section sieve: sieving functions and tools for primes */ +/*********************************************************/ + +static mp_limb_t +n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; } + +static mp_size_t +primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; } + + +static const unsigned char primegap_small[] = +{ + 2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6, + 2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2, + 4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6, + 12,2,18,6,10 +}; + +#define NUMBER_OF_PRIMES 100 +#define LAST_PRIME 557 +/* NP_SMALL_LIMIT = prevprime (LAST_PRIME ^ 2) */ +#define NP_SMALL_LIMIT 310243 + +static unsigned long +calculate_sievelimit(mp_bitcnt_t nbits) { + unsigned long sieve_limit; + + /* Estimate a good sieve bound. Based on derivative of + * Merten's 3rd theorem * avg gap * cost of mod + * vs + * Cost of PRP test O(N^2.55) + */ + if (nbits < 12818) + { + mpz_t tmp; + /* sieve_limit ~= nbits ^ (5/2) / 124 */ + mpz_init (tmp); + mpz_ui_pow_ui (tmp, nbits, 5); + mpz_tdiv_q_ui(tmp, tmp, 124*124); + /* tmp < 12818^5/(124*124) < 2^55 < 2^64 */ + mpz_sqrt (tmp, tmp); + + sieve_limit = mpz_get_ui(tmp); + mpz_clear (tmp); + } + else + { + /* Larger threshold is faster but takes (n/ln(n) + n/24) memory. + * For 33,000 bits limitting to 150M is ~12% slower than using the + * optimal 1.5G sieve_limit. + */ + sieve_limit = 150000001; + } + + ASSERT (1000 < sieve_limit && sieve_limit <= 150000001); + return sieve_limit; +} + +static unsigned +findnext_small (unsigned t, short diff) +{ + /* For diff= 2, expect t = 1 if operand was negative. + * For diff=-2, expect t >= 3 + */ + ASSERT (t >= 3 || (diff > 0 && t >= 1)); + ASSERT (t < NP_SMALL_LIMIT); + + /* Start from next candidate (2 or odd) */ + t = diff > 0 ? + (t + 1) | (t != 1) : + ((t - 2) | 1) + (t == 3); + + for (; ; t += diff) + { + unsigned prime = 3; + for (int i = 0; ; prime += primegap_small[i++]) + { + unsigned q, r; + q = t / prime; + r = t - q * prime; /* r = t % prime; */ + if (q < prime) + return t; + if (r == 0) + break; + ASSERT (i < NUMBER_OF_PRIMES); + } + } +} + +static int +findnext (mpz_ptr p, + unsigned long(*negative_mod_ui)(const mpz_t, unsigned long), + void(*increment_ui)(mpz_t, const mpz_t, unsigned long)) +{ + char *composite; + const unsigned char *primegap; + unsigned long prime_limit; + mp_size_t pn; + mp_bitcnt_t nbits; + int i, m; + unsigned odds_in_composite_sieve; + TMP_DECL; + + TMP_MARK; + pn = SIZ(p); + MPN_SIZEINBASE_2EXP(nbits, PTR(p), pn, 1); + /* Smaller numbers handled earlier */ + ASSERT (nbits >= 3); + /* Make p odd */ + PTR(p)[0] |= 1; + + if (nbits / 2 <= NUMBER_OF_PRIMES) + { + primegap = primegap_small; + prime_limit = nbits / 2; + } + else + { + unsigned long sieve_limit; + mp_limb_t *sieve; + unsigned char *primegap_tmp; + unsigned long last_prime; + + /* sieve numbers up to sieve_limit and save prime count */ + sieve_limit = calculate_sievelimit(nbits); + sieve = TMP_ALLOC_LIMBS (primesieve_size (sieve_limit)); + prime_limit = gmp_primesieve(sieve, sieve_limit); + + /* TODO: Storing (prime - last_prime)/2 would allow this to go + up to the gap 304599508537+514=304599509051 . + With the current code our limit is 436273009+282=436273291 */ + ASSERT (sieve_limit < 436273291); + /* THINK: Memory used by both sieve and primegap_tmp is kept + allocated, but they may overlap if primegap is filled from + larger down to smaller primes... + */ + + /* Needed to avoid assignment of read-only location */ + primegap_tmp = TMP_ALLOC_TYPE (prime_limit, unsigned char); + primegap = primegap_tmp; + + i = 0; + last_prime = 3; + /* THINK: should we get rid of sieve_limit and use (i < prime_limit)? */ + for (mp_limb_t j = 4, *sp = sieve; j < sieve_limit; j += GMP_LIMB_BITS * 3) + for (mp_limb_t b = j, x = ~ *(sp++); x != 0; b += 3, x >>= 1) + if (x & 1) + { + mp_limb_t prime = b | 1; + primegap_tmp[i++] = prime - last_prime; + last_prime = prime; + } + + /* Both primesieve and prime_limit ignore the first two primes. */ + ASSERT(i == prime_limit); + } + + if (nbits <= 32) + odds_in_composite_sieve = 336 / 2; + else if (nbits <= 64) + odds_in_composite_sieve = 1550 / 2; + else + /* Corresponds to a merit 14 prime_gap, which is rare. */ + odds_in_composite_sieve = 5 * nbits; + + /* composite[2*i] stores if p+2*i is a known composite */ + composite = TMP_ALLOC_TYPE (odds_in_composite_sieve, char); + + for (;;) + { + unsigned long difference; + unsigned long incr, prime; + int primetest; + + memset (composite, 0, odds_in_composite_sieve); + prime = 3; + for (i = 0; i < prime_limit; i++) + { + /* Distance to next multiple of prime */ + m = negative_mod_ui(p, prime); + /* Only care about odd multiplies of prime. */ + if (m & 1) + m += prime; + m >>= 1; + + /* Mark off any composites in sieve */ + for (; m < odds_in_composite_sieve; m += prime) + composite[m] = 1; + prime += primegap[i]; + } + + difference = 0; + for (incr = 0; incr < odds_in_composite_sieve; difference += 2, incr += 1) + { + if (composite[incr]) + continue; + + increment_ui(p, p, difference); + difference = 0; + + /* Miller-Rabin test */ + primetest = mpz_millerrabin (p, 25); + if (primetest) + { + TMP_FREE; + return primetest; + } + } + + /* Sieve next segment, very rare */ + increment_ui(p, p, difference); + } +} + +void +mpz_nextprime (mpz_ptr p, mpz_srcptr n) +{ + /* Handle negative and small numbers */ + if (mpz_cmp_ui (n, NP_SMALL_LIMIT) < 0) + { + ASSERT (NP_SMALL_LIMIT < UINT_MAX); + mpz_set_ui (p, findnext_small (SIZ (n) > 0 ? mpz_get_ui (n) : 1, +2)); + return; + } + + /* First odd greater than n */ + mpz_add_ui (p, n, 1); + + findnext(p, mpz_cdiv_ui, mpz_add_ui); +} + +int +mpz_prevprime (mpz_ptr p, mpz_srcptr n) +{ + /* Handle negative and small numbers */ + if (mpz_cmp_ui (n, 2) <= 0) + return 0; + + if (mpz_cmp_ui (n, NP_SMALL_LIMIT) < 0) + { + ASSERT (NP_SMALL_LIMIT < UINT_MAX); + mpz_set_ui (p, findnext_small (mpz_get_ui (n), -2)); + return 2; + } + + /* First odd less than n */ + mpz_sub_ui (p, n, 2); + + return findnext(p, mpz_tdiv_ui, mpz_sub_ui); +} + diff --git a/gmp-6.3.0/mpz/oddfac_1.c b/gmp-6.3.0/mpz/oddfac_1.c new file mode 100644 index 0000000..3f4c085 --- /dev/null +++ b/gmp-6.3.0/mpz/oddfac_1.c @@ -0,0 +1,435 @@ +/* mpz_oddfac_1(RESULT, N) -- Set RESULT to the odd factor of N!. + +Contributed to the GNU project by Marco Bodrato. + +THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. +IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. +IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR +DISAPPEAR IN A FUTURE GNU MP RELEASE. + +Copyright 2010-2012, 2015-2017, 2020, 2021 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +/* TODO: + - split this file in smaller parts with functions that can be recycled for different computations. + */ + +/**************************************************************/ +/* Section macros: common macros, for mswing/fac/bin (&sieve) */ +/**************************************************************/ + +#define FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I) \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = 1; \ + } + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +#define LOOP_ON_SIEVE_CONTINUE(prime,end) \ + __max_i = (end); \ + \ + do { \ + ++__i; \ + if ((*__sieve & __mask) == 0) \ + { \ + mp_limb_t prime; \ + prime = id_to_n(__i) + +#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \ + do { \ + mp_limb_t __mask, *__sieve, __max_i, __i; \ + \ + __i = (start)-(off); \ + __sieve = (sieve) + __i / GMP_LIMB_BITS; \ + __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \ + __i += (off); \ + \ + LOOP_ON_SIEVE_CONTINUE(prime,end) + +#define LOOP_ON_SIEVE_STOP \ + } \ + __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \ + __sieve += __mask & 1; \ + } while (__i <= __max_i) + +#define LOOP_ON_SIEVE_END \ + LOOP_ON_SIEVE_STOP; \ + } while (0) + +/*********************************************************/ +/* Section sieve: sieving functions and tools for primes */ +/*********************************************************/ + +#if WANT_ASSERT +static mp_limb_t +bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; } +#endif + +/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/ +static mp_limb_t +id_to_n (mp_limb_t id) { return id*3+1+(id&1); } + +/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */ +static mp_limb_t +n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; } + +#if WANT_ASSERT +static mp_size_t +primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; } +#endif + +/*********************************************************/ +/* Section mswing: 2-multiswing factorial */ +/*********************************************************/ + +/* Returns an approximation of the sqare root of x. + * It gives: + * limb_apprsqrt (x) ^ 2 <= x < (limb_apprsqrt (x)+1) ^ 2 + * or + * x <= limb_apprsqrt (x) ^ 2 <= x * 9/8 + */ +static mp_limb_t +limb_apprsqrt (mp_limb_t x) +{ + int s; + + ASSERT (x > 2); + count_leading_zeros (s, x); + s = (GMP_LIMB_BITS - s) >> 1; + return ((CNST_LIMB(1) << (s - 1)) + (x >> 1 >> s)); +} + +#if 0 +/* A count-then-exponentiate variant for SWING_A_PRIME */ +#define SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \ + do { \ + mp_limb_t __q, __prime; \ + int __exp; \ + __prime = (P); \ + __exp = 0; \ + __q = (N); \ + do { \ + __q /= __prime; \ + __exp += __q & 1; \ + } while (__q >= __prime); \ + if (__exp) { /* Store $prime^{exp}$ */ \ + for (__q = __prime; --__exp; __q *= __prime); \ + FACTOR_LIST_STORE(__q, PR, MAX_PR, VEC, I); \ + }; \ + } while (0) +#else +#define SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \ + do { \ + mp_limb_t __q, __prime; \ + __prime = (P); \ + FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I); \ + __q = (N); \ + do { \ + __q /= __prime; \ + if ((__q & 1) != 0) (PR) *= __prime; \ + } while (__q >= __prime); \ + } while (0) +#endif + +#define SH_SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \ + do { \ + mp_limb_t __prime; \ + __prime = (P); \ + if ((((N) / __prime) & 1) != 0) \ + FACTOR_LIST_STORE(__prime, PR, MAX_PR, VEC, I); \ + } while (0) + +/* mpz_2multiswing_1 computes the odd part of the 2-multiswing + factorial of the parameter n. The result x is an odd positive + integer so that multiswing(n,2) = x 2^a. + + Uses the algorithm described by Peter Luschny in "Divide, Swing and + Conquer the Factorial!". + + The pointer sieve points to primesieve_size(n) limbs containing a + bit-array where primes are marked as 0. + Enough (FIXME: explain :-) limbs must be pointed by factors. + */ + +static void +mpz_2multiswing_1 (mpz_ptr x, mp_limb_t n, mp_ptr sieve, mp_ptr factors) +{ + mp_limb_t prod, max_prod; + mp_size_t j; + + ASSERT (n > 25); + + j = 0; + prod = -(n & 1); + n &= ~ CNST_LIMB(1); /* n-1, if n is odd */ + + prod = (prod & n) + 1; /* the original n, if it was odd, 1 otherwise */ + max_prod = GMP_NUMB_MAX / (n-1); + + /* Handle prime = 3 separately. */ + SWING_A_PRIME (3, n, prod, max_prod, factors, j); + + /* Swing primes from 5 to n/3 */ + { + mp_limb_t s, l_max_prod; + + s = limb_apprsqrt(n); + ASSERT (s >= 5); + s = n_to_bit (s); + ASSERT (bit_to_n (s+1) * bit_to_n (s+1) > n); + ASSERT (s < n_to_bit (n / 3)); + LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), s, 0,sieve); + SWING_A_PRIME (prime, n, prod, max_prod, factors, j); + LOOP_ON_SIEVE_STOP; + + ASSERT (max_prod <= GMP_NUMB_MAX / 3); + + l_max_prod = max_prod * 3; + + LOOP_ON_SIEVE_CONTINUE (prime, n_to_bit (n/3)); + SH_SWING_A_PRIME (prime, n, prod, l_max_prod, factors, j); + LOOP_ON_SIEVE_END; + } + + /* Store primes from (n+1)/2 to n */ + LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (n >> 1) + 1, n_to_bit (n), 0,sieve); + FACTOR_LIST_STORE (prime, prod, max_prod, factors, j); + LOOP_ON_SIEVE_END; + + if (LIKELY (j != 0)) + { + factors[j++] = prod; + mpz_prodlimbs (x, factors, j); + } + else + { + ASSERT (ALLOC (x) > 0); + PTR (x)[0] = prod; + SIZ (x) = 1; + } +} + +#undef SWING_A_PRIME +#undef SH_SWING_A_PRIME +#undef LOOP_ON_SIEVE_END +#undef LOOP_ON_SIEVE_STOP +#undef LOOP_ON_SIEVE_BEGIN +#undef LOOP_ON_SIEVE_CONTINUE +#undef FACTOR_LIST_APPEND + +/*********************************************************/ +/* Section oddfac: odd factorial, needed also by binomial*/ +/*********************************************************/ + +/* FIXME: refine che following estimate. */ + +#if TUNE_PROGRAM_BUILD +#define FACTORS_PER_LIMB (GMP_NUMB_BITS * 2 / (LOG2C(FAC_DSC_THRESHOLD_LIMIT*FAC_DSC_THRESHOLD_LIMIT-1)+1) - 1) +#else +#define FACTORS_PER_LIMB (GMP_NUMB_BITS * 2 / (LOG2C(FAC_DSC_THRESHOLD*FAC_DSC_THRESHOLD-1)+1) - 1) +#endif + +/* mpz_oddfac_1 computes the odd part of the factorial of the + parameter n. I.e. n! = x 2^a, where x is the returned value: an + odd positive integer. + + If flag != 0 a square is skipped in the DSC part, e.g. + if n is odd, n > FAC_DSC_THRESHOLD and flag = 1, x is set to n!!. + + If n is too small, flag is ignored, and an ASSERT can be triggered. + + TODO: FAC_DSC_THRESHOLD is used here with two different roles: + - to decide when prime factorisation is needed, + - to stop the recursion, once sieving is done. + Maybe two thresholds can do a better job. + */ +void +mpz_oddfac_1 (mpz_ptr x, mp_limb_t n, unsigned flag) +{ + ASSERT (n <= GMP_NUMB_MAX); + ASSERT (flag == 0 || (flag == 1 && n > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1 && ABOVE_THRESHOLD (n, FAC_DSC_THRESHOLD))); + + if (n <= ODD_FACTORIAL_TABLE_LIMIT) + { + MPZ_NEWALLOC (x, 1)[0] = __gmp_oddfac_table[n]; + SIZ (x) = 1; + } + else if (n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1) + { + mp_ptr px; + + px = MPZ_NEWALLOC (x, 2); + umul_ppmm (px[1], px[0], __gmp_odd2fac_table[(n - 1) >> 1], __gmp_oddfac_table[n >> 1]); + SIZ (x) = 2; + } + else + { + unsigned s; + mp_ptr factors; + + s = 0; + { + mp_limb_t tn; + mp_limb_t prod, max_prod; + mp_size_t j; + TMP_SDECL; + +#if TUNE_PROGRAM_BUILD + ASSERT (FAC_DSC_THRESHOLD_LIMIT >= FAC_DSC_THRESHOLD); + ASSERT (FAC_DSC_THRESHOLD >= 2 * (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2)); +#endif + + /* Compute the number of recursive steps for the DSC algorithm. */ + for (tn = n; ABOVE_THRESHOLD (tn, FAC_DSC_THRESHOLD); s++) + tn >>= 1; + + j = 0; + + TMP_SMARK; + factors = TMP_SALLOC_LIMBS (1 + tn / FACTORS_PER_LIMB); + ASSERT (tn >= FACTORS_PER_LIMB); + + prod = 1; +#if TUNE_PROGRAM_BUILD + max_prod = GMP_NUMB_MAX / (FAC_DSC_THRESHOLD_LIMIT * FAC_DSC_THRESHOLD_LIMIT); +#else + max_prod = GMP_NUMB_MAX / (FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD); +#endif + + ASSERT (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1); + do { + factors[j++] = ODD_DOUBLEFACTORIAL_TABLE_MAX; + mp_limb_t diff = (tn - ODD_DOUBLEFACTORIAL_TABLE_LIMIT) & -CNST_LIMB (2); + if ((diff & 2) != 0) + { + FACTOR_LIST_STORE (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff, prod, max_prod, factors, j); + diff -= 2; + } + if (diff != 0) + { + mp_limb_t fac = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2) * + (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff); + do { + FACTOR_LIST_STORE (fac, prod, max_prod, factors, j); + diff -= 4; + fac += diff * 2; + } while (diff != 0); + } + max_prod <<= 2; + tn >>= 1; + } while (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1); + + factors[j++] = prod; + factors[j++] = __gmp_odd2fac_table[(tn - 1) >> 1]; + factors[j++] = __gmp_oddfac_table[tn >> 1]; + mpz_prodlimbs (x, factors, j); + + TMP_SFREE; + } + + if (s != 0) + /* Use the algorithm described by Peter Luschny in "Divide, + Swing and Conquer the Factorial!". + + Improvement: there are two temporary buffers, factors and + square, that are never used together; with a good estimate + of the maximal needed size, they could share a single + allocation. + */ + { + mpz_t mswing; + mp_ptr sieve; + mp_size_t size; + TMP_DECL; + + TMP_MARK; + + flag--; + size = n / GMP_NUMB_BITS + 4; + ASSERT (primesieve_size (n - 1) <= size - (size / 2 + 1)); + /* 2-multiswing(n) < 2^(n-1)*sqrt(n/pi) < 2^(n+GMP_NUMB_BITS); + one more can be overwritten by mul, another for the sieve */ + MPZ_TMP_INIT (mswing, size); + /* Initialize size, so that ASSERT can check it correctly. */ + ASSERT_CODE (SIZ (mswing) = 0); + + /* Put the sieve on the second half, it will be overwritten by the last mswing. */ + sieve = PTR (mswing) + size / 2 + 1; + + size = (gmp_primesieve (sieve, n - 1) + 1) / log_n_max (n) + 1; + + factors = TMP_ALLOC_LIMBS (size); + do { + mp_ptr square, px; + mp_size_t nx, ns; + mp_limb_t cy; + TMP_DECL; + + s--; + ASSERT (ABSIZ (mswing) < ALLOC (mswing) / 2); /* Check: sieve has not been overwritten */ + mpz_2multiswing_1 (mswing, n >> s, sieve, factors); + + TMP_MARK; + nx = SIZ (x); + if (s == flag) { + size = nx; + square = TMP_ALLOC_LIMBS (size); + MPN_COPY (square, PTR (x), nx); + } else { + size = nx << 1; + square = TMP_ALLOC_LIMBS (size); + mpn_sqr (square, PTR (x), nx); + size -= (square[size - 1] == 0); + } + ns = SIZ (mswing); + nx = size + ns; + px = MPZ_NEWALLOC (x, nx); + ASSERT (ns <= size); + cy = mpn_mul (px, square, size, PTR(mswing), ns); /* n!= n$ * floor(n/2)!^2 */ + + SIZ(x) = nx - (cy == 0); + TMP_FREE; + } while (s != 0); + TMP_FREE; + } + } +} + +#undef FACTORS_PER_LIMB +#undef FACTOR_LIST_STORE diff --git a/gmp-6.3.0/mpz/out_raw.c b/gmp-6.3.0/mpz/out_raw.c new file mode 100644 index 0000000..b9fd086 --- /dev/null +++ b/gmp-6.3.0/mpz/out_raw.c @@ -0,0 +1,172 @@ +/* mpz_out_raw -- write an mpz_t in raw format. + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + + +/* HTON_LIMB_STORE takes a normal host byte order limb and stores it as + network byte order (ie. big endian). */ + +#if HAVE_LIMB_BIG_ENDIAN +#define HTON_LIMB_STORE(dst, limb) do { *(dst) = (limb); } while (0) +#endif + +#if HAVE_LIMB_LITTLE_ENDIAN +#define HTON_LIMB_STORE(dst, limb) BSWAP_LIMB_STORE (dst, limb) +#endif + +#ifndef HTON_LIMB_STORE +#define HTON_LIMB_STORE(dst, limb) \ + do { \ + mp_limb_t __limb = (limb); \ + char *__p = (char *) (dst); \ + int __i; \ + for (__i = 0; __i < GMP_LIMB_BYTES; __i++) \ + __p[__i] = (char) (__limb >> ((GMP_LIMB_BYTES-1 - __i) * 8)); \ + } while (0) +#endif + + +size_t +mpz_out_raw (FILE *fp, mpz_srcptr x) +{ + mp_size_t xsize, abs_xsize, bytes, i; + mp_srcptr xp; + char *tp, *bp; + mp_limb_t xlimb; + int zeros; + size_t tsize, ssize; + + xsize = SIZ(x); + abs_xsize = ABS (xsize); + bytes = (abs_xsize * GMP_NUMB_BITS + 7) / 8; + tsize = ROUND_UP_MULTIPLE ((unsigned) 4, GMP_LIMB_BYTES) + bytes; + + tp = __GMP_ALLOCATE_FUNC_TYPE (tsize, char); + bp = tp + ROUND_UP_MULTIPLE ((unsigned) 4, GMP_LIMB_BYTES); + + if (bytes != 0) + { + bp += bytes; + xp = PTR (x); + i = abs_xsize; + + if (GMP_NAIL_BITS == 0) + { + /* reverse limb order, and byte swap if necessary */ +#ifdef _CRAY + _Pragma ("_CRI ivdep"); +#endif + do + { + bp -= GMP_LIMB_BYTES; + xlimb = *xp; + HTON_LIMB_STORE ((mp_ptr) bp, xlimb); + xp++; + } + while (--i > 0); + + /* strip high zero bytes (without fetching from bp) */ + count_leading_zeros (zeros, xlimb); + zeros /= 8; + bp += zeros; + bytes -= zeros; + } + else + { + mp_limb_t new_xlimb; + int bits; + ASSERT_CODE (char *bp_orig = bp - bytes); + + ASSERT_ALWAYS (GMP_NUMB_BITS >= 8); + + bits = 0; + xlimb = 0; + for (;;) + { + while (bits >= 8) + { + ASSERT (bp > bp_orig); + *--bp = xlimb & 0xFF; + xlimb >>= 8; + bits -= 8; + } + + if (i == 0) + break; + + new_xlimb = *xp++; + i--; + ASSERT (bp > bp_orig); + *--bp = (xlimb | (new_xlimb << bits)) & 0xFF; + xlimb = new_xlimb >> (8 - bits); + bits += GMP_NUMB_BITS - 8; + } + + if (bits != 0) + { + ASSERT (bp > bp_orig); + *--bp = xlimb; + } + + ASSERT (bp == bp_orig); + while (*bp == 0) + { + bp++; + bytes--; + } + } + } + + /* total bytes to be written */ + ssize = 4 + bytes; + + /* twos complement negative for the size value */ + bytes = (xsize >= 0 ? bytes : -bytes); + + /* so we don't rely on sign extension in ">>" */ + ASSERT_ALWAYS (sizeof (bytes) >= 4); + + bp[-4] = bytes >> 24; + bp[-3] = bytes >> 16; + bp[-2] = bytes >> 8; + bp[-1] = bytes; + bp -= 4; + + if (fp == 0) + fp = stdout; + if (fwrite (bp, ssize, 1, fp) != 1) + ssize = 0; + + (*__gmp_free_func) (tp, tsize); + return ssize; +} diff --git a/gmp-6.3.0/mpz/out_str.c b/gmp-6.3.0/mpz/out_str.c new file mode 100644 index 0000000..b1d8ae8 --- /dev/null +++ b/gmp-6.3.0/mpz/out_str.c @@ -0,0 +1,108 @@ +/* mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec. + integer INTEGER in base BASE. + +Copyright 1991, 1993, 1994, 1996, 2001, 2005, 2011, 2012, 2017 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include "gmp-impl.h" +#include "longlong.h" + +size_t +mpz_out_str (FILE *stream, int base, mpz_srcptr x) +{ + mp_ptr xp; + mp_size_t x_size = SIZ (x); + unsigned char *str; + size_t str_size; + size_t i; + size_t written; + const char *num_to_text; + TMP_DECL; + + if (stream == 0) + stream = stdout; + + num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + if (base > 1) + { + if (base <= 36) + num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz"; + else if (UNLIKELY (base > 62)) + return 0; + } + else if (base > -2) + { + base = 10; + } + else + { + base = -base; + if (UNLIKELY (base > 36)) + return 0; + } + + written = 0; + + if (x_size < 0) + { + fputc ('-', stream); + x_size = -x_size; + written = 1; + } + + TMP_MARK; + + DIGITS_IN_BASE_PER_LIMB (str_size, x_size, base); + str_size += 3; + str = (unsigned char *) TMP_ALLOC (str_size); + + xp = PTR (x); + if (! POW2_P (base)) + { + xp = TMP_ALLOC_LIMBS (x_size | 1); /* |1 in case x_size==0 */ + MPN_COPY (xp, PTR (x), x_size); + } + + str_size = mpn_get_str (str, base, xp, x_size); + + /* Convert result to printable chars. */ + for (i = 0; i < str_size; i++) + str[i] = num_to_text[str[i]]; + str[str_size] = 0; + + { + size_t fwret; + fwret = fwrite ((char *) str, 1, str_size, stream); + written += fwret; + } + + TMP_FREE; + return ferror (stream) ? 0 : written; +} diff --git a/gmp-6.3.0/mpz/perfpow.c b/gmp-6.3.0/mpz/perfpow.c new file mode 100644 index 0000000..9bbb497 --- /dev/null +++ b/gmp-6.3.0/mpz/perfpow.c @@ -0,0 +1,38 @@ +/* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power, + zero otherwise. + +Copyright 1998-2001, 2005, 2008, 2009 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +int +mpz_perfect_power_p (mpz_srcptr u) +{ + return mpn_perfect_power_p (PTR (u), SIZ (u)); +} diff --git a/gmp-6.3.0/mpz/perfsqr.c b/gmp-6.3.0/mpz/perfsqr.c new file mode 100644 index 0000000..c2ac924 --- /dev/null +++ b/gmp-6.3.0/mpz/perfsqr.c @@ -0,0 +1,34 @@ +/* mpz_perfect_square_p(arg) -- Return non-zero if ARG is a perfect square, + zero otherwise. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_perfect_square_p 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/popcount.c b/gmp-6.3.0/mpz/popcount.c new file mode 100644 index 0000000..e9a85bb --- /dev/null +++ b/gmp-6.3.0/mpz/popcount.c @@ -0,0 +1,34 @@ +/* mpz_popcount(mpz_ptr op) -- Population count of OP. If the operand is + negative, return ~0 (a novel representation of infinity). + +Copyright 1994, 1996, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_popcount 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/pow_ui.c b/gmp-6.3.0/mpz/pow_ui.c new file mode 100644 index 0000000..8bafaa7 --- /dev/null +++ b/gmp-6.3.0/mpz/pow_ui.c @@ -0,0 +1,52 @@ +/* mpz_pow_ui -- mpz raised to ulong. + +Copyright 2001, 2008 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_pow_ui (mpz_ptr r, mpz_srcptr b, unsigned long int e) +{ + /* We test some small exponents here, mainly to avoid the overhead of + mpz_n_pow_ui for small bases and exponents. */ + switch (e) + { + case 0: + mpz_set_ui (r, 1); + break; + case 1: + mpz_set (r, b); + break; + case 2: + mpz_mul (r, b, b); + break; + default: + mpz_n_pow_ui (r, PTR(b), (mp_size_t) SIZ(b), e); + } +} diff --git a/gmp-6.3.0/mpz/powm.c b/gmp-6.3.0/mpz/powm.c new file mode 100644 index 0000000..f1bf8e3 --- /dev/null +++ b/gmp-6.3.0/mpz/powm.c @@ -0,0 +1,282 @@ +/* mpz_powm(res,base,exp,mod) -- Set R to (U^E) mod M. + + Contributed to the GNU project by Torbjorn Granlund. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, +2011, 2012, 2015, 2019 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#include "gmp-impl.h" +#include "longlong.h" + + +/* TODO + + * Improve handling of buffers. It is pretty ugly now. + + * For even moduli, we compute a binvert of its odd part both here and in + mpn_powm. How can we avoid this recomputation? +*/ + +/* + b ^ e mod m res + 0 0 0 ? + 0 e 0 ? + 0 0 m ? + 0 e m 0 + b 0 0 ? + b e 0 ? + b 0 m 1 mod m + b e m b^e mod m +*/ + +#define HANDLE_NEGATIVE_EXPONENT 1 + +void +mpz_powm (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m) +{ + mp_size_t n, nodd, ncnt; + int cnt; + mp_ptr rp, tp; + mp_srcptr bp, ep, mp; + mp_size_t rn, bn, es, en, itch; + mpz_t new_b; /* note: value lives long via 'b' */ + TMP_DECL; + + n = ABSIZ(m); + if (UNLIKELY (n == 0)) + DIVIDE_BY_ZERO; + + mp = PTR(m); + + TMP_MARK; + + es = SIZ(e); + if (UNLIKELY (es <= 0)) + { + if (es == 0) + { + /* b^0 mod m, b is anything and m is non-zero. + Result is 1 mod m, i.e., 1 or 0 depending on if m = 1. */ + SIZ(r) = n != 1 || mp[0] != 1; + MPZ_NEWALLOC (r, 1)[0] = 1; + TMP_FREE; /* we haven't really allocated anything here */ + return; + } +#if HANDLE_NEGATIVE_EXPONENT + MPZ_TMP_INIT (new_b, n + 1); + + if (UNLIKELY (! mpz_invert (new_b, b, m))) + DIVIDE_BY_ZERO; + b = new_b; + es = -es; +#else + DIVIDE_BY_ZERO; +#endif + } + en = es; + + bn = ABSIZ(b); + + if (UNLIKELY (bn == 0)) + { + SIZ(r) = 0; + TMP_FREE; + return; + } + + ep = PTR(e); + + /* Handle (b^1 mod m) early, since mpn_pow* do not handle that case. */ + if (UNLIKELY (en == 1 && ep[0] == 1)) + { + rp = TMP_ALLOC_LIMBS (n); + bp = PTR(b); + if (bn >= n) + { + mp_ptr qp = TMP_ALLOC_LIMBS (bn - n + 1); + mpn_tdiv_qr (qp, rp, 0L, bp, bn, mp, n); + rn = n; + MPN_NORMALIZE (rp, rn); + + if (rn != 0 && SIZ(b) < 0) + { + mpn_sub (rp, mp, n, rp, rn); + rn = n; + MPN_NORMALIZE_NOT_ZERO (rp, rn); + } + } + else + { + if (SIZ(b) < 0) + { + mpn_sub (rp, mp, n, bp, bn); + rn = n; + MPN_NORMALIZE_NOT_ZERO (rp, rn); + } + else + { + MPN_COPY (rp, bp, bn); + rn = bn; + } + } + goto ret; + } + + /* Remove low zero limbs from M. This loop will terminate for correctly + represented mpz numbers. */ + ncnt = 0; + while (UNLIKELY (mp[0] == 0)) + { + mp++; + ncnt++; + } + nodd = n - ncnt; + cnt = 0; + if (mp[0] % 2 == 0) + { + mp_ptr newmp = TMP_ALLOC_LIMBS (nodd); + count_trailing_zeros (cnt, mp[0]); + mpn_rshift (newmp, mp, nodd, cnt); + nodd -= newmp[nodd - 1] == 0; + mp = newmp; + ncnt++; + } + + if (ncnt != 0) + { + /* We will call both mpn_powm and mpn_powlo. */ + /* rp needs n, mpn_powlo needs 4n, the 2 mpn_binvert might need more */ + mp_size_t n_largest_binvert = MAX (ncnt, nodd); + mp_size_t itch_binvert = mpn_binvert_itch (n_largest_binvert); + itch = 3 * n + MAX (itch_binvert, 2 * n); + } + else + { + /* We will call just mpn_powm. */ + mp_size_t itch_binvert = mpn_binvert_itch (nodd); + itch = n + MAX (itch_binvert, 2 * n); + } + tp = TMP_ALLOC_LIMBS (itch); + + rp = tp; tp += n; + + bp = PTR(b); + mpn_powm (rp, bp, bn, ep, en, mp, nodd, tp); + + rn = n; + + if (ncnt != 0) + { + mp_ptr r2, xp, yp, odd_inv_2exp; + unsigned long t; + int bcnt; + + if (bn < ncnt) + { + mp_ptr newbp = TMP_ALLOC_LIMBS (ncnt); + MPN_COPY (newbp, bp, bn); + MPN_ZERO (newbp + bn, ncnt - bn); + bp = newbp; + } + + r2 = tp; + + if (bp[0] % 2 == 0) + { + if (en > 1) + { + MPN_ZERO (r2, ncnt); + goto zero; + } + + ASSERT (en == 1); + t = (ncnt - (cnt != 0)) * GMP_NUMB_BITS + cnt; + + /* Count number of low zero bits in B, up to 3. */ + bcnt = (0x1213 >> ((bp[0] & 7) << 1)) & 0x3; + /* Note that ep[0] * bcnt might overflow, but that just results + in a missed optimization. */ + if (ep[0] * bcnt >= t) + { + MPN_ZERO (r2, ncnt); + goto zero; + } + } + + mpn_powlo (r2, bp, ep, en, ncnt, tp + ncnt); + + zero: + if (nodd < ncnt) + { + mp_ptr newmp = TMP_ALLOC_LIMBS (ncnt); + MPN_COPY (newmp, mp, nodd); + MPN_ZERO (newmp + nodd, ncnt - nodd); + mp = newmp; + } + + odd_inv_2exp = tp + n; + mpn_binvert (odd_inv_2exp, mp, ncnt, tp + 2 * n); + + mpn_sub (r2, r2, ncnt, rp, nodd > ncnt ? ncnt : nodd); + + xp = tp + 2 * n; + mpn_mullo_n (xp, odd_inv_2exp, r2, ncnt); + + if (cnt != 0) + xp[ncnt - 1] &= (CNST_LIMB(1) << cnt) - 1; + + yp = tp; + if (ncnt > nodd) + mpn_mul (yp, xp, ncnt, mp, nodd); + else + mpn_mul (yp, mp, nodd, xp, ncnt); + + mpn_add (rp, yp, n, rp, nodd); + + ASSERT (nodd + ncnt >= n); + ASSERT (nodd + ncnt <= n + 1); + } + + MPN_NORMALIZE (rp, rn); + + if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0) + { + mpn_sub (rp, PTR(m), n, rp, rn); + rn = n; + MPN_NORMALIZE (rp, rn); + } + + ret: + MPZ_NEWALLOC (r, rn); + SIZ(r) = rn; + MPN_COPY (PTR(r), rp, rn); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/powm_sec.c b/gmp-6.3.0/mpz/powm_sec.c new file mode 100644 index 0000000..a2581a8 --- /dev/null +++ b/gmp-6.3.0/mpz/powm_sec.c @@ -0,0 +1,102 @@ +/* mpz_powm_sec(res,base,exp,mod) -- Set R to (U^E) mod M. + + Contributed to the GNU project by Torbjorn Granlund. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, +2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#include "gmp-impl.h" + + +void +mpz_powm_sec (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m) +{ + mp_size_t n; + mp_ptr rp, tp; + mp_srcptr bp, ep, mp; + mp_size_t rn, bn, es, en; + TMP_DECL; + + n = ABSIZ(m); + + mp = PTR(m); + + if (UNLIKELY ((n == 0) || (mp[0] % 2 == 0))) + DIVIDE_BY_ZERO; + + es = SIZ(e); + if (UNLIKELY (es <= 0)) + { + if (es == 0) + { + /* b^0 mod m, b is anything and m is non-zero. + Result is 1 mod m, i.e., 1 or 0 depending on if m = 1. */ + SIZ(r) = n != 1 || mp[0] != 1; + MPZ_NEWALLOC (r, 1)[0] = 1; + return; + } + DIVIDE_BY_ZERO; + } + en = es; + + bn = ABSIZ(b); + + if (UNLIKELY (bn == 0)) + { + SIZ(r) = 0; + return; + } + + TMP_MARK; + TMP_ALLOC_LIMBS_2 (rp, n, + tp, mpn_sec_powm_itch (bn, en * GMP_NUMB_BITS, n)); + + bp = PTR(b); + ep = PTR(e); + + mpn_sec_powm (rp, bp, bn, ep, en * GMP_NUMB_BITS, mp, n, tp); + + rn = n; + + MPN_NORMALIZE (rp, rn); + + if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0) + { + mpn_sub (rp, PTR(m), n, rp, rn); + rn = n; + MPN_NORMALIZE (rp, rn); + } + + MPZ_NEWALLOC (r, rn); + SIZ(r) = rn; + MPN_COPY (PTR(r), rp, rn); + + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/powm_ui.c b/gmp-6.3.0/mpz/powm_ui.c new file mode 100644 index 0000000..23d3ed8 --- /dev/null +++ b/gmp-6.3.0/mpz/powm_ui.c @@ -0,0 +1,281 @@ +/* mpz_powm_ui(res,base,exp,mod) -- Set R to (B^E) mod M. + + Contributed to the GNU project by Torbjörn Granlund. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, +2011-2013, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#include "gmp-impl.h" +#include "longlong.h" + + +/* This code is very old, and should be rewritten to current GMP standard. It + is slower than mpz_powm for large exponents, but also for small exponents + when the mod argument is small. + + As an intermediate solution, we now deflect to mpz_powm for exponents >= 20. +*/ + +/* + b ^ e mod m res + 0 0 0 ? + 0 e 0 ? + 0 0 m ? + 0 e m 0 + b 0 0 ? + b e 0 ? + b 0 m 1 mod m + b e m b^e mod m +*/ + +static void +mod (mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn, gmp_pi1_t *dinv, mp_ptr tp) +{ + mp_ptr qp = tp; + + if (dn == 1) + { + np[0] = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, dp[0]); + } + else if (dn == 2) + { + mpn_div_qr_2n_pi1 (qp, np, np, nn, dp[1], dp[0], dinv->inv32); + } + else if (BELOW_THRESHOLD (dn, DC_DIV_QR_THRESHOLD) || + BELOW_THRESHOLD (nn - dn, DC_DIV_QR_THRESHOLD)) + { + mpn_sbpi1_div_qr (qp, np, nn, dp, dn, dinv->inv32); + } + else if (BELOW_THRESHOLD (dn, MUPI_DIV_QR_THRESHOLD) || /* fast condition */ + BELOW_THRESHOLD (nn, 2 * MU_DIV_QR_THRESHOLD) || /* fast condition */ + (double) (2 * (MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD)) * dn /* slow... */ + + (double) MUPI_DIV_QR_THRESHOLD * nn > (double) dn * nn) /* ...condition */ + { + mpn_dcpi1_div_qr (qp, np, nn, dp, dn, dinv); + } + else + { + /* We need to allocate separate remainder area, since mpn_mu_div_qr does + not handle overlap between the numerator and remainder areas. + FIXME: Make it handle such overlap. */ + mp_ptr rp, scratch; + mp_size_t itch; + TMP_DECL; + TMP_MARK; + + itch = mpn_mu_div_qr_itch (nn, dn, 0); + rp = TMP_BALLOC_LIMBS (dn); + scratch = TMP_BALLOC_LIMBS (itch); + + mpn_mu_div_qr (qp, rp, np, nn, dp, dn, scratch); + MPN_COPY (np, rp, dn); + + TMP_FREE; + } +} + +/* Compute t = a mod m, a is defined by (ap,an), m is defined by (mp,mn), and + t is defined by (tp,mn). */ +static void +reduce (mp_ptr tp, mp_srcptr ap, mp_size_t an, mp_srcptr mp, mp_size_t mn, gmp_pi1_t *dinv) +{ + mp_ptr rp, scratch; + TMP_DECL; + TMP_MARK; + + TMP_ALLOC_LIMBS_2 (rp, an, scratch, an - mn + 1); + MPN_COPY (rp, ap, an); + mod (rp, an, mp, mn, dinv, scratch); + MPN_COPY (tp, rp, mn); + + TMP_FREE; +} + +void +mpz_powm_ui (mpz_ptr r, mpz_srcptr b, unsigned long int el, mpz_srcptr m) +{ + if (el < 20) + { + mp_ptr xp, tp, mp, bp, scratch; + mp_size_t xn, tn, mn, bn; + int m_zero_cnt; + int c; + mp_limb_t e, m2; + gmp_pi1_t dinv; + TMP_DECL; + + mp = PTR(m); + mn = ABSIZ(m); + if (UNLIKELY (mn == 0)) + DIVIDE_BY_ZERO; + + if (el <= 1) + { + if (el == 1) + { + mpz_mod (r, b, m); + return; + } + /* Exponent is zero, result is 1 mod M, i.e., 1 or 0 depending on if + M equals 1. */ + SIZ(r) = mn != 1 || mp[0] != 1; + MPZ_NEWALLOC (r, 1)[0] = 1; + return; + } + + TMP_MARK; + + /* Normalize m (i.e. make its most significant bit set) as required by + division functions below. */ + count_leading_zeros (m_zero_cnt, mp[mn - 1]); + m_zero_cnt -= GMP_NAIL_BITS; + if (m_zero_cnt != 0) + { + mp_ptr new_mp = TMP_ALLOC_LIMBS (mn); + mpn_lshift (new_mp, mp, mn, m_zero_cnt); + mp = new_mp; + } + + m2 = mn == 1 ? 0 : mp[mn - 2]; + invert_pi1 (dinv, mp[mn - 1], m2); + + bn = ABSIZ(b); + bp = PTR(b); + if (bn > mn) + { + /* Reduce possibly huge base. Use a function call to reduce, since we + don't want the quotient allocation to live until function return. */ + mp_ptr new_bp = TMP_ALLOC_LIMBS (mn); + reduce (new_bp, bp, bn, mp, mn, &dinv); + bp = new_bp; + bn = mn; + /* Canonicalize the base, since we are potentially going to multiply with + it quite a few times. */ + MPN_NORMALIZE (bp, bn); + } + + if (bn == 0) + { + SIZ(r) = 0; + TMP_FREE; + return; + } + + TMP_ALLOC_LIMBS_3 (xp, mn, scratch, mn + 1, tp, 2 * mn + 1); + + MPN_COPY (xp, bp, bn); + xn = bn; + + e = el; + count_leading_zeros (c, e); + e = (e << c) << 1; /* shift the exp bits to the left, lose msb */ + c = GMP_LIMB_BITS - 1 - c; + + ASSERT (c != 0); /* el > 1 */ + { + /* Main loop. */ + do + { + mpn_sqr (tp, xp, xn); + tn = 2 * xn; tn -= tp[tn - 1] == 0; + if (tn < mn) + { + MPN_COPY (xp, tp, tn); + xn = tn; + } + else + { + mod (tp, tn, mp, mn, &dinv, scratch); + MPN_COPY (xp, tp, mn); + xn = mn; + } + + if ((mp_limb_signed_t) e < 0) + { + mpn_mul (tp, xp, xn, bp, bn); + tn = xn + bn; tn -= tp[tn - 1] == 0; + if (tn < mn) + { + MPN_COPY (xp, tp, tn); + xn = tn; + } + else + { + mod (tp, tn, mp, mn, &dinv, scratch); + MPN_COPY (xp, tp, mn); + xn = mn; + } + } + e <<= 1; + c--; + } + while (c != 0); + } + + /* We shifted m left m_zero_cnt steps. Adjust the result by reducing it + with the original M. */ + if (m_zero_cnt != 0) + { + mp_limb_t cy; + cy = mpn_lshift (tp, xp, xn, m_zero_cnt); + tp[xn] = cy; xn += cy != 0; + + if (xn >= mn) + { + mod (tp, xn, mp, mn, &dinv, scratch); + xn = mn; + } + mpn_rshift (xp, tp, xn, m_zero_cnt); + } + MPN_NORMALIZE (xp, xn); + + if ((el & 1) != 0 && SIZ(b) < 0 && xn != 0) + { + mp = PTR(m); /* want original, unnormalized m */ + mpn_sub (xp, mp, mn, xp, xn); + xn = mn; + MPN_NORMALIZE (xp, xn); + } + MPZ_NEWALLOC (r, xn); + SIZ (r) = xn; + MPN_COPY (PTR(r), xp, xn); + + TMP_FREE; + } + else + { + /* For large exponents, fake an mpz_t exponent and deflect to the more + sophisticated mpz_powm. */ + mpz_t e; + mp_limb_t ep[LIMBS_PER_ULONG]; + MPZ_FAKE_UI (e, ep, el); + mpz_powm (r, b, e, m); + } +} diff --git a/gmp-6.3.0/mpz/pprime_p.c b/gmp-6.3.0/mpz/pprime_p.c new file mode 100644 index 0000000..b8a21c2 --- /dev/null +++ b/gmp-6.3.0/mpz/pprime_p.c @@ -0,0 +1,166 @@ +/* mpz_probab_prime_p -- + An implementation of the probabilistic primality test found in Knuth's + Seminumerical Algorithms book. If the function mpz_probab_prime_p() + returns 0 then n is not prime. If it returns 1, then n is 'probably' + prime. If it returns 2, n is surely prime. The probability of a false + positive is (1/4)**reps, where reps is the number of internal passes of the + probabilistic algorithm. Knuth indicates that 25 passes are reasonable. + +Copyright 1991, 1993, 1994, 1996-2002, 2005, 2015, 2016 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +static int isprime (unsigned long int); + + +/* MPN_MOD_OR_MODEXACT_1_ODD can be used instead of mpn_mod_1 for the trial + division. It gives a result which is not the actual remainder r but a + value congruent to r*2^n mod d. Since all the primes being tested are + odd, r*2^n mod p will be 0 if and only if r mod p is 0. */ + +int +mpz_probab_prime_p (mpz_srcptr n, int reps) +{ + mp_limb_t r; + mpz_t n2; + + /* Handle small and negative n. */ + if (mpz_cmp_ui (n, 1000000L) <= 0) + { + if (mpz_cmpabs_ui (n, 1000000L) <= 0) + { + int is_prime; + unsigned long n0; + n0 = mpz_get_ui (n); + is_prime = n0 & (n0 > 1) ? isprime (n0) : n0 == 2; + return is_prime ? 2 : 0; + } + /* Negative number. Negate and fall out. */ + PTR(n2) = PTR(n); + SIZ(n2) = -SIZ(n); + n = n2; + } + + /* If n is now even, it is not a prime. */ + if (mpz_even_p (n)) + return 0; + +#if defined (PP) + /* Check if n has small factors. */ +#if defined (PP_INVERTED) + r = MPN_MOD_OR_PREINV_MOD_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP, + (mp_limb_t) PP_INVERTED); +#else + r = mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP); +#endif + if (r % 3 == 0 +#if GMP_LIMB_BITS >= 4 + || r % 5 == 0 +#endif +#if GMP_LIMB_BITS >= 8 + || r % 7 == 0 +#endif +#if GMP_LIMB_BITS >= 16 + || r % 11 == 0 || r % 13 == 0 +#endif +#if GMP_LIMB_BITS >= 32 + || r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0 +#endif +#if GMP_LIMB_BITS >= 64 + || r % 31 == 0 || r % 37 == 0 || r % 41 == 0 || r % 43 == 0 + || r % 47 == 0 || r % 53 == 0 +#endif + ) + { + return 0; + } +#endif /* PP */ + + /* Do more dividing. We collect small primes, using umul_ppmm, until we + overflow a single limb. We divide our number by the small primes product, + and look for factors in the remainder. */ + { + unsigned long int ln2; + unsigned long int q; + mp_limb_t p1, p0, p; + unsigned int primes[15]; + int nprimes; + + nprimes = 0; + p = 1; + ln2 = mpz_sizeinbase (n, 2); /* FIXME: tune this limit */ + for (q = PP_FIRST_OMITTED; q < ln2; q += 2) + { + if (isprime (q)) + { + umul_ppmm (p1, p0, p, q); + if (p1 != 0) + { + r = MPN_MOD_OR_MODEXACT_1_ODD (PTR(n), (mp_size_t) SIZ(n), p); + while (--nprimes >= 0) + if (r % primes[nprimes] == 0) + { + ASSERT_ALWAYS (mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) primes[nprimes]) == 0); + return 0; + } + p = q; + nprimes = 0; + } + else + { + p = p0; + } + primes[nprimes++] = q; + } + } + } + + /* Perform a number of Miller-Rabin tests. */ + return mpz_millerrabin (n, reps); +} + +static int +isprime (unsigned long int t) +{ + unsigned long int q, r, d; + + ASSERT (t >= 3 && (t & 1) != 0); + + d = 3; + do { + q = t / d; + r = t - q * d; + if (q < d) + return 1; + d += 2; + } while (r != 0); + return 0; +} diff --git a/gmp-6.3.0/mpz/primorial_ui.c b/gmp-6.3.0/mpz/primorial_ui.c new file mode 100644 index 0000000..b1176c7 --- /dev/null +++ b/gmp-6.3.0/mpz/primorial_ui.c @@ -0,0 +1,131 @@ +/* mpz_primorial_ui(RES, N) -- Set RES to N# the product of primes <= N. + +Contributed to the GNU project by Marco Bodrato. + +Copyright 2012, 2015, 2016, 2021 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +/* TODO: Remove duplicated constants / macros / static functions... + */ + +/*************************************************************/ +/* Section macros: common macros, for swing/fac/bin (&sieve) */ +/*************************************************************/ + +#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \ + do { \ + if ((PR) > (MAX_PR)) { \ + (VEC)[(I)++] = (PR); \ + (PR) = (P); \ + } else \ + (PR) *= (P); \ + } while (0) + +/*********************************************************/ +/* Section sieve: sieving functions and tools for primes */ +/*********************************************************/ + +#if WANT_ASSERT +/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */ +static mp_limb_t +n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; } + +static mp_size_t +primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; } +#endif + +/*********************************************************/ +/* Section primorial: implementation */ +/*********************************************************/ + +void +mpz_primorial_ui (mpz_ptr res, unsigned long n) +{ + ASSERT (n <= GMP_NUMB_MAX); + + if (n < 5) + { + /* The smallest 5 results for primorial are stored */ + /* in a 15-bits constant (five octal digits) */ + MPZ_NEWALLOC (res, 1)[0] = (066211 >> (n * 3)) & 7; + SIZ (res) = 1; + } + else + { + mp_limb_t *sieve, *factors; + mp_size_t size, j; + mp_limb_t prod; + TMP_DECL; + + /* Try to estimate the result size, to avoid */ + /* resizing, and to initially store the sieve. */ + size = n / GMP_NUMB_BITS; + size = size + (size >> 1) + 1; + ASSERT (size >= primesieve_size (n)); + sieve = MPZ_NEWALLOC (res, size); + size = (gmp_primesieve (sieve, n) + 1) / log_n_max (n) + 1; + + TMP_MARK; + factors = TMP_ALLOC_LIMBS (size); + + j = 0; + + prod = 6; + + /* Store primes from 5 to n */ + { + mp_limb_t max_prod; + + max_prod = GMP_NUMB_MAX / n; + + /* Loop on sieved primes. */ + for (mp_limb_t i = 4, *sp = sieve; i < n; i += GMP_LIMB_BITS * 3) + for (mp_limb_t b = i, x = ~ *(sp++); x != 0; b += 3, x >>= 1) + if (x & 1) + { + mp_limb_t prime = b | 1; + FACTOR_LIST_STORE (prime, prod, max_prod, factors, j); + } + } + + if (j != 0) + { + factors[j++] = prod; + mpz_prodlimbs (res, factors, j); + } + else + { + PTR (res)[0] = prod; + SIZ (res) = 1; + } + + TMP_FREE; + } +} diff --git a/gmp-6.3.0/mpz/prodlimbs.c b/gmp-6.3.0/mpz/prodlimbs.c new file mode 100644 index 0000000..23f06a1 --- /dev/null +++ b/gmp-6.3.0/mpz/prodlimbs.c @@ -0,0 +1,108 @@ +/* mpz_prodlimbs(RESULT, V, LEN) -- Set RESULT to V[0]*V[1]*...*V[LEN-1]. + +Contributed to the GNU project by Marco Bodrato. + +THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. +IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. +IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR +DISAPPEAR IN A FUTURE GNU MP RELEASE. + +Copyright 2010-2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +/*********************************************************/ +/* Section list-prod: product of a list -> mpz_t */ +/*********************************************************/ + +/* FIXME: should be tuned */ +#ifndef RECURSIVE_PROD_THRESHOLD +#define RECURSIVE_PROD_THRESHOLD (MUL_TOOM22_THRESHOLD) +#endif + +/* Computes the product of the j>1 limbs pointed by factors, puts the + * result in x. It assumes that all limbs are non-zero. Above + * Karatsuba's threshold it uses a binary splitting strategy, to gain + * speed by the asymptotically fast multiplication algorithms. + * + * The list in {factors, j} is overwritten. + * Returns the size of the result + */ + +mp_size_t +mpz_prodlimbs (mpz_ptr x, mp_ptr factors, mp_size_t j) +{ + mp_limb_t cy; + mp_size_t size, i; + mp_ptr prod; + + ASSERT (j > 1); + ASSERT (RECURSIVE_PROD_THRESHOLD > 3); + + if (BELOW_THRESHOLD (j, RECURSIVE_PROD_THRESHOLD)) { + j--; + size = 1; + + for (i = 1; i < j; i++) + { + cy = mpn_mul_1 (factors, factors, size, factors[i]); + factors[size] = cy; + size += cy != 0; + }; + + prod = MPZ_NEWALLOC (x, size + 1); + + cy = mpn_mul_1 (prod, factors, size, factors[i]); + prod[size] = cy; + return SIZ (x) = size + (cy != 0); + } else { + mpz_t x1, x2; + TMP_DECL; + + i = j >> 1; + j -= i; + TMP_MARK; + + MPZ_TMP_INIT (x2, j); + + PTR (x1) = factors + i; + ALLOC (x1) = j; + j = mpz_prodlimbs (x2, factors + i, j); + i = mpz_prodlimbs (x1, factors, i); + size = i + j; + prod = MPZ_NEWALLOC (x, size); + if (i >= j) + cy = mpn_mul (prod, PTR(x1), i, PTR(x2), j); + else + cy = mpn_mul (prod, PTR(x2), j, PTR(x1), i); + TMP_FREE; + + return SIZ (x) = size - (cy == 0); + } +} diff --git a/gmp-6.3.0/mpz/random.c b/gmp-6.3.0/mpz/random.c new file mode 100644 index 0000000..1a1e515 --- /dev/null +++ b/gmp-6.3.0/mpz/random.c @@ -0,0 +1,39 @@ +/* mpz_random -- Generate a random mpz_t of specified size in limbs. + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_random (mpz_ptr x, mp_size_t size) +{ + mpz_urandomb (x, RANDS, (unsigned long) (ABS (size) * GMP_NUMB_BITS)); + if (size < 0) + SIZ(x) = -SIZ(x); +} diff --git a/gmp-6.3.0/mpz/random2.c b/gmp-6.3.0/mpz/random2.c new file mode 100644 index 0000000..2c72540 --- /dev/null +++ b/gmp-6.3.0/mpz/random2.c @@ -0,0 +1,51 @@ +/* mpz_random2 -- Generate a positive random mpz_t of specified size, with + long runs of consecutive ones and zeros in the binary representation. + Meant for testing of other MP routines. + +Copyright 1991, 1993, 1994, 1996, 2001, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_random2 (mpz_ptr x, mp_size_t size) +{ + mp_size_t abs_size; + mp_ptr xp; + + abs_size = ABS (size); + if (abs_size != 0) + { + xp = MPZ_NEWALLOC (x, abs_size); + + mpn_random2 (xp, abs_size); + } + + SIZ (x) = size; +} diff --git a/gmp-6.3.0/mpz/realloc.c b/gmp-6.3.0/mpz/realloc.c new file mode 100644 index 0000000..4288ef1 --- /dev/null +++ b/gmp-6.3.0/mpz/realloc.c @@ -0,0 +1,70 @@ +/* _mpz_realloc -- make the mpz_t have NEW_ALLOC digits allocated. + +Copyright 1991, 1993-1995, 2000, 2001, 2008, 2015, 2021, 2022 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void * +_mpz_realloc (mpz_ptr m, mp_size_t new_alloc) +{ + mp_ptr mp; + + /* Never allocate zero space. */ + new_alloc = MAX (new_alloc, 1); + + if (sizeof (mp_size_t) == sizeof (int)) + { + if (UNLIKELY (new_alloc > ULONG_MAX / GMP_NUMB_BITS)) + MPZ_OVERFLOW; + } + else + { + if (UNLIKELY (new_alloc > INT_MAX)) + MPZ_OVERFLOW; + } + + if (ALLOC (m) == 0) + { + mp = __GMP_ALLOCATE_FUNC_LIMBS (new_alloc); + } + else + { + mp = __GMP_REALLOCATE_FUNC_LIMBS (PTR (m), ALLOC (m), new_alloc); + + /* Don't create an invalid number; if the current value doesn't fit after + reallocation, clear it to 0. */ + if (UNLIKELY (ABSIZ (m) > new_alloc)) + SIZ (m) = 0; + } + + PTR (m) = mp; + ALLOC(m) = new_alloc; + return (void *) mp; +} diff --git a/gmp-6.3.0/mpz/realloc2.c b/gmp-6.3.0/mpz/realloc2.c new file mode 100644 index 0000000..633077e --- /dev/null +++ b/gmp-6.3.0/mpz/realloc2.c @@ -0,0 +1,63 @@ +/* mpz_realloc2 -- change allocated data size. + +Copyright 2001, 2002, 2008, 2015, 2021, 2022 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_realloc2 (mpz_ptr m, mp_bitcnt_t bits) +{ + mp_size_t new_alloc; + + bits -= (bits != 0); /* Round down, except if 0 */ + new_alloc = 1 + bits / GMP_NUMB_BITS; + + if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */ + { + if (UNLIKELY (new_alloc > INT_MAX)) + MPZ_OVERFLOW; + } + + if (ALLOC (m) == 0) + { + PTR (m) = __GMP_ALLOCATE_FUNC_LIMBS (new_alloc); + } + else + { + PTR (m) = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc); + + /* Don't create an invalid number; if the current value doesn't fit after + reallocation, clear it to 0. */ + if (ABSIZ(m) > new_alloc) + SIZ(m) = 0; + } + + ALLOC(m) = new_alloc; +} diff --git a/gmp-6.3.0/mpz/remove.c b/gmp-6.3.0/mpz/remove.c new file mode 100644 index 0000000..a655121 --- /dev/null +++ b/gmp-6.3.0/mpz/remove.c @@ -0,0 +1,146 @@ +/* mpz_remove -- divide out a factor and return its multiplicity. + +Copyright 1998-2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +mp_bitcnt_t +mpz_remove (mpz_ptr dest, mpz_srcptr src, mpz_srcptr f) +{ + mp_bitcnt_t pwr; + mp_srcptr fp; + mp_size_t sn, fn, afn; + mp_limb_t fp0; + + sn = SIZ (src); + fn = SIZ (f); + fp = PTR (f); + afn = ABS (fn); + fp0 = fp[0]; + + if (UNLIKELY ((afn <= (fp0 == 1)) /* mpz_cmpabs_ui (f, 1) <= 0 */ + | (sn == 0))) + { + /* f = 0 or f = +- 1 or src = 0 */ + if (afn == 0) + DIVIDE_BY_ZERO; + mpz_set (dest, src); + return 0; + } + + if ((fp0 & 1) != 0) + { /* f is odd */ + mp_ptr dp; + mp_size_t dn; + + dn = ABS (sn); + dp = MPZ_REALLOC (dest, dn); + + pwr = mpn_remove (dp, &dn, PTR(src), dn, PTR(f), afn, ~(mp_bitcnt_t) 0); + + SIZ (dest) = ((pwr & (fn < 0)) ^ (sn < 0)) ? -dn : dn; + } + else if (afn == (fp0 == 2)) + { /* mpz_cmpabs_ui (f, 2) == 0 */ + pwr = mpz_scan1 (src, 0); + mpz_div_2exp (dest, src, pwr); + if (pwr & (fn < 0)) /*((pwr % 2 == 1) && (SIZ (f) < 0))*/ + mpz_neg (dest, dest); + } + else + { /* f != +-2 */ + mpz_t x, rem; + + mpz_init (rem); + mpz_init (x); + + pwr = 0; + mpz_tdiv_qr (x, rem, src, f); + if (SIZ (rem) == 0) + { + mpz_t fpow[GMP_LIMB_BITS]; /* Really MP_SIZE_T_BITS */ + int p; + +#if WANT_ORIGINAL_DEST + mp_ptr dp; + dp = PTR (dest); +#endif + /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an + upper bound of the result we're seeking. We could also shift down the + operands so that they become odd, to make intermediate values + smaller. */ + mpz_init_set (fpow[0], f); + mpz_swap (dest, x); + + p = 1; + /* Divide by f, f^2 ... f^(2^k) until we get a remainder for f^(2^k). */ + while (ABSIZ (dest) >= 2 * ABSIZ (fpow[p - 1]) - 1) + { + mpz_init (fpow[p]); + mpz_mul (fpow[p], fpow[p - 1], fpow[p - 1]); + mpz_tdiv_qr (x, rem, dest, fpow[p]); + if (SIZ (rem) != 0) { + mpz_clear (fpow[p]); + break; + } + mpz_swap (dest, x); + p++; + } + + pwr = ((mp_bitcnt_t)1 << p) - 1; + + /* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give + a zero remainder. */ + while (--p >= 0) + { + mpz_tdiv_qr (x, rem, dest, fpow[p]); + if (SIZ (rem) == 0) + { + pwr += (mp_bitcnt_t)1 << p; + mpz_swap (dest, x); + } + mpz_clear (fpow[p]); + } + +#if WANT_ORIGINAL_DEST + if (PTR (x) == dp) { + mpz_swap (dest, x); + mpz_set (dest, x); + } +#endif + } + else + mpz_set (dest, src); + + mpz_clear (x); + mpz_clear (rem); + } + + return pwr; +} diff --git a/gmp-6.3.0/mpz/roinit_n.c b/gmp-6.3.0/mpz/roinit_n.c new file mode 100644 index 0000000..9125466 --- /dev/null +++ b/gmp-6.3.0/mpz/roinit_n.c @@ -0,0 +1,43 @@ +/* mpz_roinit_n -- Initialize mpz with read-only limb array. + +Copyright 2013 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +mpz_srcptr +mpz_roinit_n (mpz_ptr x, mp_srcptr xp, mp_size_t xs) +{ + mp_size_t xn = ABS(xs); + MPN_NORMALIZE (xp, xn); + + ALLOC (x) = 0; + SIZ (x) = xs < 0 ? -xn : xn; + PTR (x) = (mp_ptr) xp; + return x; +} diff --git a/gmp-6.3.0/mpz/root.c b/gmp-6.3.0/mpz/root.c new file mode 100644 index 0000000..7c8d368 --- /dev/null +++ b/gmp-6.3.0/mpz/root.c @@ -0,0 +1,90 @@ +/* mpz_root(root, u, nth) -- Set ROOT to floor(U^(1/nth)). + Return an indication if the result is exact. + +Copyright 1999-2003, 2005, 2012, 2020 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + +int +mpz_root (mpz_ptr root, mpz_srcptr u, unsigned long int nth) +{ + mp_ptr rootp, up; + mp_size_t us, un, rootn, remn; + TMP_DECL; + + us = SIZ(u); + + /* even roots of negatives provoke an exception */ + if (UNLIKELY (us < 0 && (nth & 1) == 0)) + SQRT_OF_NEGATIVE; + + if (UNLIKELY (nth <= 1)) + { + /* root extraction interpreted as c^(1/nth) means a zeroth root should + provoke a divide by zero, do this even if c==0 */ + if (UNLIKELY (nth == 0)) + DIVIDE_BY_ZERO; + /* nth == 1 */ + if (root != NULL && u != root) + mpz_set (root, u); + return 1; /* exact result */ + } + + if (us == 0) + { + if (root != NULL) + SIZ(root) = 0; + return 1; /* exact result */ + } + + un = ABS (us); + rootn = (un - 1) / nth + 1; + + TMP_MARK; + + /* FIXME: Perhaps disallow root == NULL */ + if (root != NULL && u != root) + rootp = MPZ_NEWALLOC (root, rootn); + else + rootp = TMP_ALLOC_LIMBS (rootn); + + up = PTR(u); + remn = mpn_rootrem (rootp, NULL, up, un, (mp_limb_t) nth); + + if (root != NULL) + { + SIZ(root) = us >= 0 ? rootn : -rootn; + if (u == root) + MPN_COPY (up, rootp, rootn); + } + + TMP_FREE; + return remn == 0; +} diff --git a/gmp-6.3.0/mpz/rootrem.c b/gmp-6.3.0/mpz/rootrem.c new file mode 100644 index 0000000..67953db --- /dev/null +++ b/gmp-6.3.0/mpz/rootrem.c @@ -0,0 +1,100 @@ +/* mpz_rootrem(root, rem, u, nth) -- Set ROOT to trunc(U^(1/nth)) and + set REM to the remainder. + +Copyright 1999-2003, 2005, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + +void +mpz_rootrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr u, unsigned long int nth) +{ + mp_ptr rootp, up, remp; + mp_size_t us, un, rootn, remn; + TMP_DECL; + + us = SIZ(u); + + /* even roots of negatives provoke an exception */ + if (UNLIKELY (us < 0 && (nth & 1) == 0)) + SQRT_OF_NEGATIVE; + + /* root extraction interpreted as c^(1/nth) means a zeroth root should + provoke a divide by zero, do this even if c==0 */ + if (UNLIKELY (nth == 0)) + DIVIDE_BY_ZERO; + + if (us == 0) + { + if (root != NULL) + SIZ(root) = 0; + SIZ(rem) = 0; + return; + } + + un = ABS (us); + rootn = (un - 1) / nth + 1; + + TMP_MARK; + + /* FIXME: Perhaps disallow root == NULL */ + if (root != NULL && u != root) + rootp = MPZ_NEWALLOC (root, rootn); + else + rootp = TMP_ALLOC_LIMBS (rootn); + + if (u != rem) + remp = MPZ_NEWALLOC (rem, un); + else + remp = TMP_ALLOC_LIMBS (un); + + up = PTR(u); + + if (nth == 1) + { + MPN_COPY (rootp, up, un); + remn = 0; + } + else + { + remn = mpn_rootrem (rootp, remp, up, un, (mp_limb_t) nth); + } + + if (root != NULL) + { + SIZ(root) = us >= 0 ? rootn : -rootn; + if (u == root) + MPN_COPY (up, rootp, rootn); + } + + if (u == rem) + MPN_COPY (up, remp, remn); + SIZ(rem) = us >= 0 ? remn : -remn; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/rrandomb.c b/gmp-6.3.0/mpz/rrandomb.c new file mode 100644 index 0000000..ae0c9e8 --- /dev/null +++ b/gmp-6.3.0/mpz/rrandomb.c @@ -0,0 +1,102 @@ +/* mpz_rrandomb -- Generate a positive random mpz_t of specified bit size, with + long runs of consecutive ones and zeros in the binary representation. + Meant for testing of other MP routines. + +Copyright 2000-2002, 2004, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +static void gmp_rrandomb (mp_ptr, gmp_randstate_ptr, mp_bitcnt_t); + +void +mpz_rrandomb (mpz_ptr x, gmp_randstate_ptr rstate, mp_bitcnt_t nbits) +{ + mp_size_t nl; + mp_ptr xp; + + nl = BITS_TO_LIMBS (nbits); + if (nbits != 0) + { + xp = MPZ_NEWALLOC (x, nl); + gmp_rrandomb (xp, rstate, nbits); + } + + SIZ(x) = nl; +} + +/* Ask _gmp_rand for 32 bits per call unless that's more than a limb can hold. + Thus, we get the same random number sequence in the common cases. + FIXME: We should always generate the same random number sequence! */ +#if GMP_NUMB_BITS < 32 +#define BITS_PER_RANDCALL GMP_NUMB_BITS +#else +#define BITS_PER_RANDCALL 32 +#endif + +static void +gmp_rrandomb (mp_ptr rp, gmp_randstate_ptr rstate, mp_bitcnt_t nbits) +{ + mp_bitcnt_t bi; + mp_limb_t ranm; /* buffer for random bits */ + unsigned cap_chunksize, chunksize; + mp_size_t i; + + /* Set entire result to 111..1 */ + i = BITS_TO_LIMBS (nbits) - 1; + rp[i] = GMP_NUMB_MAX >> (GMP_NUMB_BITS - (nbits % GMP_NUMB_BITS)) % GMP_NUMB_BITS; + for (i = i - 1; i >= 0; i--) + rp[i] = GMP_NUMB_MAX; + + _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL); + cap_chunksize = nbits / (ranm % 4 + 1); + cap_chunksize += cap_chunksize == 0; /* make it at least 1 */ + + bi = nbits; + + for (;;) + { + _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL); + chunksize = 1 + ranm % cap_chunksize; + bi = (bi < chunksize) ? 0 : bi - chunksize; + + if (bi == 0) + break; /* low chunk is ...1 */ + + rp[bi / GMP_NUMB_BITS] ^= CNST_LIMB (1) << bi % GMP_NUMB_BITS; + + _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL); + chunksize = 1 + ranm % cap_chunksize; + bi = (bi < chunksize) ? 0 : bi - chunksize; + + mpn_incr_u (rp + bi / GMP_NUMB_BITS, CNST_LIMB (1) << bi % GMP_NUMB_BITS); + + if (bi == 0) + break; /* low chunk is ...0 */ + } +} diff --git a/gmp-6.3.0/mpz/scan0.c b/gmp-6.3.0/mpz/scan0.c new file mode 100644 index 0000000..4b0f1ef --- /dev/null +++ b/gmp-6.3.0/mpz/scan0.c @@ -0,0 +1,129 @@ +/* mpz_scan0 -- search for a 0 bit. + +Copyright 2000-2002, 2004, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* mpn_scan0 can't be used for the u>0 search since there might not be a 0 + bit before the end of the data. mpn_scan1 could be used for the inverted + search under u<0, but usually the search won't go very far so it seems + reasonable to inline that code. */ + +mp_bitcnt_t +mpz_scan0 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW +{ + mp_srcptr u_ptr = PTR(u); + mp_size_t size = SIZ(u); + mp_size_t abs_size = ABS(size); + mp_srcptr u_end = u_ptr + abs_size; + mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS; + mp_srcptr p = u_ptr + starting_limb; + mp_limb_t limb; + int cnt; + + /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for + u<0. Notice this test picks up all cases of u==0 too. */ + if (starting_limb >= abs_size) + return (size >= 0 ? starting_bit : ~(mp_bitcnt_t) 0); + + limb = *p; + + if (size >= 0) + { + /* Mask to 1 all bits before starting_bit, thus ignoring them. */ + limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1; + + /* Search for a limb which isn't all ones. If the end is reached then + the zero bit immediately past the end is returned. */ + while (limb == GMP_NUMB_MAX) + { + p++; + if (p == u_end) + return (mp_bitcnt_t) abs_size * GMP_NUMB_BITS; + limb = *p; + } + + /* Now seek low 1 bit. */ + limb = ~limb; + } + else + { + mp_srcptr q; + + /* If there's a non-zero limb before ours then we're in the ones + complement region. Search from *(p-1) downwards since that might + give better cache locality, and since a non-zero in the middle of a + number is perhaps a touch more likely than at the end. */ + q = p; + while (q != u_ptr) + { + q--; + if (*q != 0) + goto inverted; + } + + /* Adjust so ~limb implied by searching for 1 bit below becomes -limb. + If limb==0 here then this isn't the beginning of twos complement + inversion, but that doesn't matter because limb==0 is a zero bit + immediately (-1 is all ones for below). */ + limb--; + + inverted: + /* Now seeking a 1 bit. */ + + /* Mask to 0 all bits before starting_bit, thus ignoring them. */ + limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS)); + + if (limb == 0) + { + /* If the high limb is zero after masking, then no 1 bits past + starting_bit. */ + p++; + if (p == u_end) + return ~(mp_bitcnt_t) 0; + + /* Search further for a non-zero limb. The high limb is non-zero, + if nothing else. */ + for (;;) + { + limb = *p; + if (limb != 0) + break; + p++; + ASSERT (p < u_end); + } + } + } + + ASSERT (limb != 0); + count_trailing_zeros (cnt, limb); + return (mp_bitcnt_t) (p - u_ptr) * GMP_NUMB_BITS + cnt; +} diff --git a/gmp-6.3.0/mpz/scan1.c b/gmp-6.3.0/mpz/scan1.c new file mode 100644 index 0000000..d096147 --- /dev/null +++ b/gmp-6.3.0/mpz/scan1.c @@ -0,0 +1,123 @@ +/* mpz_scan1 -- search for a 1 bit. + +Copyright 2000-2002, 2004, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* mpn_scan0 can't be used for the inverted u<0 search since there might not + be a 0 bit before the end of the data. mpn_scan1 could be used under u>0 + (except when in the high limb), but usually the search won't go very far + so it seems reasonable to inline that code. */ + +mp_bitcnt_t +mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW +{ + mp_srcptr u_ptr = PTR(u); + mp_size_t size = SIZ(u); + mp_size_t abs_size = ABS(size); + mp_srcptr u_end = u_ptr + abs_size - 1; + mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS; + mp_srcptr p = u_ptr + starting_limb; + mp_limb_t limb; + int cnt; + + /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit for u<0. + Notice this test picks up any u==0 too. */ + if (starting_limb >= abs_size) + return (size >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit); + + /* This is an important case, where sign is not relevant! */ + if (starting_bit == 0) + goto short_cut; + + limb = *p; + + if (size >= 0) + { + /* Mask to 0 all bits before starting_bit, thus ignoring them. */ + limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS)); + + if (limb == 0) + { + /* If it's the high limb which is zero after masking, then there's + no 1 bits after starting_bit. */ + if (p == u_end) + return ~(mp_bitcnt_t) 0; + + /* Otherwise search further for a non-zero limb. The high limb is + non-zero, if nothing else. */ + search_nonzero: + do + { + ASSERT (p != u_end); + p++; + short_cut: + limb = *p; + } + while (limb == 0); + } + } + else + { + /* If there's a non-zero limb before ours then we're in the ones + complement region. */ + if (starting_limb == 0 || mpn_zero_p (u_ptr, starting_limb)) { + if (limb == 0) + /* Seeking for the first non-zero bit, it is the same for u and -u. */ + goto search_nonzero; + + /* Adjust so ~limb implied by searching for 0 bit becomes -limb. */ + limb--; + } + + /* Now seeking a 0 bit. */ + + /* Mask to 1 all bits before starting_bit, thus ignoring them. */ + limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1; + + /* Search for a limb which is not all ones. If the end is reached + then the zero immediately past the end is the result. */ + while (limb == GMP_NUMB_MAX) + { + if (p == u_end) + return (mp_bitcnt_t) abs_size * GMP_NUMB_BITS; + p++; + limb = *p; + } + + /* Now seeking low 1 bit. */ + limb = ~limb; + } + + ASSERT (limb != 0); + count_trailing_zeros (cnt, limb); + return (mp_bitcnt_t) (p - u_ptr) * GMP_NUMB_BITS + cnt; +} diff --git a/gmp-6.3.0/mpz/set.c b/gmp-6.3.0/mpz/set.c new file mode 100644 index 0000000..7789af3 --- /dev/null +++ b/gmp-6.3.0/mpz/set.c @@ -0,0 +1,49 @@ +/* mpz_set (dest_integer, src_integer) -- Assign DEST_INTEGER from SRC_INTEGER. + +Copyright 1991, 1993-1995, 2000, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +void +mpz_set (mpz_ptr w, mpz_srcptr u) +{ + mp_ptr wp, up; + mp_size_t usize, size; + + usize = SIZ(u); + size = ABS (usize); + + wp = MPZ_NEWALLOC (w, size); + + up = PTR(u); + + MPN_COPY (wp, up, size); + SIZ(w) = usize; +} diff --git a/gmp-6.3.0/mpz/set_d.c b/gmp-6.3.0/mpz/set_d.c new file mode 100644 index 0000000..8cbda11 --- /dev/null +++ b/gmp-6.3.0/mpz/set_d.c @@ -0,0 +1,113 @@ +/* mpz_set_d(integer, val) -- Assign INTEGER with a double value VAL. + +Copyright 1995, 1996, 2000-2003, 2006, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#if HAVE_FLOAT_H +#include /* for DBL_MAX */ +#endif + +#include "gmp-impl.h" + + +/* We used to have a special case for d < MP_BASE_AS_DOUBLE, just casting + double -> limb. Unfortunately gcc 3.3 on powerpc970-apple-darwin6.8.5 + got this wrong. (It assumed __fixunsdfdi returned its result in a single + 64-bit register, where instead that function followed the calling + conventions and gave the result in two parts r3 and r4.) Hence the use + of __gmp_extract_double in all cases. */ + +void +mpz_set_d (mpz_ptr r, double d) +{ + int negative; + mp_limb_t tp[LIMBS_PER_DOUBLE]; + mp_ptr rp; + mp_size_t rn; + + DOUBLE_NAN_INF_ACTION (d, + __gmp_invalid_operation (), + __gmp_invalid_operation ()); + + negative = d < 0; + d = ABS (d); + + rn = __gmp_extract_double (tp, d); + + if (rn <= 0) + rn = 0; + + rp = MPZ_NEWALLOC (r, rn); + + switch (rn) + { + default: + MPN_ZERO (rp, rn - LIMBS_PER_DOUBLE); + rp += rn - LIMBS_PER_DOUBLE; + /* fall through */ +#if LIMBS_PER_DOUBLE == 2 + case 2: + rp[1] = tp[1], rp[0] = tp[0]; + break; + case 1: + rp[0] = tp[1]; + break; +#endif +#if LIMBS_PER_DOUBLE == 3 + case 3: + rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0]; + break; + case 2: + rp[1] = tp[2], rp[0] = tp[1]; + break; + case 1: + rp[0] = tp[2]; + break; +#endif +#if LIMBS_PER_DOUBLE == 4 + case 4: + rp[3] = tp[3], rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0]; + break; + case 3: + rp[2] = tp[3], rp[1] = tp[2], rp[0] = tp[1]; + break; + case 2: + rp[1] = tp[3], rp[0] = tp[2]; + break; + case 1: + rp[0] = tp[3]; + break; +#endif + case 0: + break; + } + + SIZ(r) = negative ? -rn : rn; +} diff --git a/gmp-6.3.0/mpz/set_f.c b/gmp-6.3.0/mpz/set_f.c new file mode 100644 index 0000000..b3ecc0b --- /dev/null +++ b/gmp-6.3.0/mpz/set_f.c @@ -0,0 +1,71 @@ +/* mpz_set_f (dest_integer, src_float) -- Assign DEST_INTEGER from SRC_FLOAT. + +Copyright 1996, 2001, 2012, 2016 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +void +mpz_set_f (mpz_ptr w, mpf_srcptr u) +{ + mp_ptr wp, up; + mp_size_t size; + mp_exp_t exp; + + /* abs(u)<1 truncates to zero */ + exp = EXP (u); + if (exp <= 0) + { + SIZ(w) = 0; + return; + } + + wp = MPZ_NEWALLOC (w, exp); + up = PTR(u); + + size = SIZ (u); + SIZ(w) = (size >= 0 ? exp : -exp); + size = ABS (size); + + if (exp > size) + { + /* pad with low zeros to get a total "exp" many limbs */ + mp_size_t zeros = exp - size; + MPN_ZERO (wp, zeros); + wp += zeros; + } + else + { + /* exp<=size, truncate to the high "exp" many limbs */ + up += (size - exp); + size = exp; + } + + MPN_COPY (wp, up, size); +} diff --git a/gmp-6.3.0/mpz/set_q.c b/gmp-6.3.0/mpz/set_q.c new file mode 100644 index 0000000..2280247 --- /dev/null +++ b/gmp-6.3.0/mpz/set_q.c @@ -0,0 +1,34 @@ +/* mpz_set_q (dest_integer, src_rational) -- Assign DEST_INTEGER from + SRC_rational. + +Copyright 1996, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_set_q 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/set_si.c b/gmp-6.3.0/mpz/set_si.c new file mode 100644 index 0000000..973aef8 --- /dev/null +++ b/gmp-6.3.0/mpz/set_si.c @@ -0,0 +1,55 @@ +/* mpz_set_si(dest,val) -- Assign DEST with a small value VAL. + +Copyright 1991, 1993-1995, 2000-2002, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_set_si (mpz_ptr dest, signed long int val) +{ + mp_size_t size; + mp_limb_t vl; + + vl = (mp_limb_t) ABS_CAST (unsigned long int, val); + + MPZ_NEWALLOC (dest, 1)[0] = vl & GMP_NUMB_MASK; + size = vl != 0; + +#if GMP_NAIL_BITS != 0 + if (vl > GMP_NUMB_MAX) + { + MPZ_REALLOC (dest, 2); + PTR (dest)[1] = vl >> GMP_NUMB_BITS; + size = 2; + } +#endif + + SIZ (dest) = val >= 0 ? size : -size; +} diff --git a/gmp-6.3.0/mpz/set_str.c b/gmp-6.3.0/mpz/set_str.c new file mode 100644 index 0000000..26c102b --- /dev/null +++ b/gmp-6.3.0/mpz/set_str.c @@ -0,0 +1,144 @@ +/* mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated + string STRING in base BASE to multiple precision integer in + MP_DEST. Allow white space in the string. If BASE == 0 determine + the base in the C standard way, i.e. 0xhh...h means base 16, + 0oo...o means base 8, otherwise assume base 10. + +Copyright 1991, 1993, 1994, 1996-1998, 2000-2003, 2005, 2011-2013 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include +#include +#include "gmp-impl.h" +#include "longlong.h" + +#define digit_value_tab __gmp_digit_value_tab + +int +mpz_set_str (mpz_ptr x, const char *str, int base) +{ + size_t str_size; + char *s, *begs; + size_t i; + mp_size_t xsize; + int c; + int negative; + const unsigned char *digit_value; + TMP_DECL; + + digit_value = digit_value_tab; + if (base > 36) + { + /* For bases > 36, use the collating sequence + 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */ + digit_value += 208; + if (UNLIKELY (base > 62)) + return -1; /* too large base */ + } + + /* Skip whitespace. */ + do + c = (unsigned char) *str++; + while (isspace (c)); + + negative = 0; + if (c == '-') + { + negative = 1; + c = (unsigned char) *str++; + } + + if (digit_value[c] >= (base == 0 ? 10 : base)) + return -1; /* error if no valid digits */ + + /* If BASE is 0, try to find out the base by looking at the initial + characters. */ + if (base == 0) + { + base = 10; + if (c == '0') + { + base = 8; + c = (unsigned char) *str++; + if (c == 'x' || c == 'X') + { + base = 16; + c = (unsigned char) *str++; + } + else if (c == 'b' || c == 'B') + { + base = 2; + c = (unsigned char) *str++; + } + } + } + + /* Skip leading zeros and white space. */ + while (c == '0' || isspace (c)) + c = (unsigned char) *str++; + /* Make sure the string does not become empty, mpn_set_str would fail. */ + if (c == 0) + { + SIZ (x) = 0; + return 0; + } + + TMP_MARK; + str_size = strlen (str - 1); + s = begs = (char *) TMP_ALLOC (str_size + 1); + + /* Remove spaces from the string and convert the result from ASCII to a + byte array. */ + for (i = 0; i < str_size; i++) + { + if (!isspace (c)) + { + int dig = digit_value[c]; + if (UNLIKELY (dig >= base)) + { + TMP_FREE; + return -1; + } + *s++ = dig; + } + c = (unsigned char) *str++; + } + + str_size = s - begs; + + LIMBS_PER_DIGIT_IN_BASE (xsize, str_size, base); + MPZ_NEWALLOC (x, xsize); + + /* Convert the byte array in base BASE to our bignum format. */ + xsize = mpn_set_str (PTR (x), (unsigned char *) begs, str_size, base); + SIZ (x) = negative ? -xsize : xsize; + + TMP_FREE; + return 0; +} diff --git a/gmp-6.3.0/mpz/set_ui.c b/gmp-6.3.0/mpz/set_ui.c new file mode 100644 index 0000000..12e95d1 --- /dev/null +++ b/gmp-6.3.0/mpz/set_ui.c @@ -0,0 +1,52 @@ +/* mpz_set_ui(integer, val) -- Assign INTEGER with a small value VAL. + +Copyright 1991, 1993-1995, 2001, 2002, 2004, 2012, 2015 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_set_ui (mpz_ptr dest, unsigned long int val) +{ + mp_size_t size; + + MPZ_NEWALLOC (dest, 1)[0] = val & GMP_NUMB_MASK; + size = val != 0; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (val > GMP_NUMB_MAX) + { + MPZ_REALLOC (dest, 2); + PTR (dest)[1] = val >> GMP_NUMB_BITS; + size = 2; + } +#endif + + SIZ (dest) = size; +} diff --git a/gmp-6.3.0/mpz/setbit.c b/gmp-6.3.0/mpz/setbit.c new file mode 100644 index 0000000..228a564 --- /dev/null +++ b/gmp-6.3.0/mpz/setbit.c @@ -0,0 +1,104 @@ +/* mpz_setbit -- set a specified bit. + +Copyright 1991, 1993-1995, 1997, 1999, 2001, 2002, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_setbit (mpz_ptr d, mp_bitcnt_t bit_idx) +{ + mp_size_t dsize = SIZ (d); + mp_ptr dp = PTR (d); + mp_size_t limb_idx; + mp_limb_t mask; + + limb_idx = bit_idx / GMP_NUMB_BITS; + mask = CNST_LIMB(1) << (bit_idx % GMP_NUMB_BITS); + if (dsize >= 0) + { + if (limb_idx < dsize) + { + dp[limb_idx] |= mask; + } + else + { + /* Ugh. The bit should be set outside of the end of the + number. We have to increase the size of the number. */ + dp = MPZ_REALLOC (d, limb_idx + 1); + SIZ (d) = limb_idx + 1; + MPN_ZERO (dp + dsize, limb_idx - dsize); + dp[limb_idx] = mask; + } + } + else + { + /* Simulate two's complement arithmetic, i.e. simulate + 1. Set OP = ~(OP - 1) [with infinitely many leading ones]. + 2. Set the bit. + 3. Set OP = ~OP + 1. */ + + dsize = -dsize; + + if (limb_idx < dsize) + { + mp_size_t zero_bound; + /* No index upper bound on this loop, we're sure there's a non-zero limb + sooner or later. */ + zero_bound = 0; + while (dp[zero_bound] == 0) + zero_bound++; + + if (limb_idx > zero_bound) + { + mp_limb_t dlimb; + dlimb = dp[limb_idx] & ~mask; + dp[limb_idx] = dlimb; + + if (UNLIKELY ((dlimb == 0) + limb_idx == dsize)) /* dsize == limb_idx + 1 */ + { + /* high limb became zero, must normalize */ + MPN_NORMALIZE (dp, limb_idx); + SIZ (d) = -limb_idx; + } + } + else if (limb_idx == zero_bound) + { + dp[limb_idx] = ((dp[limb_idx] - 1) & ~mask) + 1; + ASSERT (dp[limb_idx] != 0); + } + else + { + MPN_DECR_U (dp + limb_idx, dsize - limb_idx, mask); + dsize -= dp[dsize - 1] == 0; + SIZ (d) = -dsize; + } + } + } +} diff --git a/gmp-6.3.0/mpz/size.c b/gmp-6.3.0/mpz/size.c new file mode 100644 index 0000000..b8aa59e --- /dev/null +++ b/gmp-6.3.0/mpz/size.c @@ -0,0 +1,34 @@ +/* mpz_size(x) -- return the number of lims currently used by the + value of integer X. + +Copyright 1991, 1993-1995, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#define __GMP_FORCE_mpz_size 1 + +#include "gmp-impl.h" diff --git a/gmp-6.3.0/mpz/sizeinbase.c b/gmp-6.3.0/mpz/sizeinbase.c new file mode 100644 index 0000000..7a1bd01 --- /dev/null +++ b/gmp-6.3.0/mpz/sizeinbase.c @@ -0,0 +1,42 @@ +/* mpz_sizeinbase(x, base) -- return an approximation to the number of + character the integer X would have printed in base BASE. The + approximation is never too small. + +Copyright 1991, 1993-1995, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +size_t +mpz_sizeinbase (mpz_srcptr x, int base) __GMP_NOTHROW +{ + size_t result; + MPN_SIZEINBASE (result, PTR(x), ABSIZ(x), base); + return result; +} diff --git a/gmp-6.3.0/mpz/sqrt.c b/gmp-6.3.0/mpz/sqrt.c new file mode 100644 index 0000000..74d2f75 --- /dev/null +++ b/gmp-6.3.0/mpz/sqrt.c @@ -0,0 +1,76 @@ +/* mpz_sqrt(root, u) -- Set ROOT to floor(sqrt(U)). + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2012, 2015 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include /* for NULL */ +#include "gmp-impl.h" + +void +mpz_sqrt (mpz_ptr root, mpz_srcptr op) +{ + mp_size_t op_size, root_size; + mp_ptr root_ptr, op_ptr; + + op_size = SIZ (op); + if (UNLIKELY (op_size <= 0)) + { + if (UNLIKELY (op_size < 0)) + SQRT_OF_NEGATIVE; + SIZ(root) = 0; + return; + } + + /* The size of the root is accurate after this simple calculation. */ + root_size = (op_size + 1) / 2; + SIZ (root) = root_size; + + op_ptr = PTR (op); + + if (root == op) + { + /* Allocate temp space for the root, which we then copy to the + shared OP/ROOT variable. */ + TMP_DECL; + TMP_MARK; + + root_ptr = TMP_ALLOC_LIMBS (root_size); + mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size); + + MPN_COPY (op_ptr, root_ptr, root_size); + + TMP_FREE; + } + else + { + root_ptr = MPZ_NEWALLOC (root, root_size); + + mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size); + } +} diff --git a/gmp-6.3.0/mpz/sqrtrem.c b/gmp-6.3.0/mpz/sqrtrem.c new file mode 100644 index 0000000..a580d95 --- /dev/null +++ b/gmp-6.3.0/mpz/sqrtrem.c @@ -0,0 +1,85 @@ +/* mpz_sqrtrem(root,rem,x) -- Set ROOT to floor(sqrt(X)) and REM + to the remainder, i.e. X - ROOT**2. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2011, 2012, 2015 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_sqrtrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr op) +{ + mp_size_t op_size, root_size, rem_size; + mp_ptr root_ptr, op_ptr, rem_ptr; + + op_size = SIZ (op); + if (UNLIKELY (op_size <= 0)) + { + if (UNLIKELY (op_size < 0)) + SQRT_OF_NEGATIVE; + SIZ(root) = 0; + SIZ(rem) = 0; + return; + } + + /* No-op if rem == op */ + rem_ptr = MPZ_NEWALLOC (rem, op_size); + + /* The size of the root is accurate after this simple calculation. */ + root_size = (op_size + 1) / 2; + SIZ (root) = root_size; + + op_ptr = PTR (op); + + if (root == op) + { + /* Allocate temp space for the root, which we then copy to the + shared OP/ROOT variable. */ + TMP_DECL; + TMP_MARK; + + root_ptr = TMP_ALLOC_LIMBS (root_size); + rem_size = mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size); + + if (rem != root) /* Don't overwrite remainder */ + MPN_COPY (op_ptr, root_ptr, root_size); + + TMP_FREE; + } + else + { + root_ptr = MPZ_NEWALLOC (root, root_size); + + rem_size = mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size); + } + + /* Write remainder size last, to make this function give only the square root + remainder, when passed ROOT == REM. */ + SIZ (rem) = rem_size; +} diff --git a/gmp-6.3.0/mpz/stronglucas.c b/gmp-6.3.0/mpz/stronglucas.c new file mode 100644 index 0000000..0bf1ce0 --- /dev/null +++ b/gmp-6.3.0/mpz/stronglucas.c @@ -0,0 +1,214 @@ +/* mpz_stronglucas(n, t1, t2) -- An implementation of the strong Lucas + primality test on n, using parameters as suggested by the BPSW test. + + THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST + CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN + FUTURE GNU MP RELEASES. + +Copyright 2018, 2020 Free Software Foundation, Inc. + +Contributed by Marco Bodrato. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +/* Returns an approximation of the sqare root of x. + * It gives: + * limb_apprsqrt (x) ^ 2 <= x < (limb_apprsqrt (x)+1) ^ 2 + * or + * x <= limb_apprsqrt (x) ^ 2 <= x * 9/8 + */ +static mp_limb_t +limb_apprsqrt (mp_limb_t x) +{ + int s; + + ASSERT (x > 2); + count_leading_zeros (s, x); + s = (GMP_LIMB_BITS - s) >> 1; + return ((CNST_LIMB(1) << (s - 1)) + (x >> 1 >> s)); +} + +static int +mpz_oddjacobi_ui (mpz_t b, mp_limb_t a) +{ + mp_limb_t b_rem; + int result_bit1; + + ASSERT (a & 1); + ASSERT (a > 1); + ASSERT (SIZ (b) > 0); + ASSERT ((*PTR (b) & 1) == 1); + + result_bit1 = 0; + JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, b_rem, PTR (b), SIZ (b), a); + if (UNLIKELY (b_rem == 0)) + return 0; + else + return mpn_jacobi_base (b_rem, a, result_bit1); +} + + +/* Performs strong Lucas' test on x, with parameters suggested */ +/* for the BPSW test. Qk and V are passed to recycle variables. */ +/* Requires GCD (x,6) = 1.*/ +int +mpz_stronglucas (mpz_srcptr x, mpz_ptr V, mpz_ptr Qk) +{ + mp_bitcnt_t b0; + mpz_t n; + mp_limb_t D; /* The absolute value is stored. */ + mp_limb_t g; + long Q; + mpz_t T1, T2; + + /* Test on the absolute value. */ + mpz_roinit_n (n, PTR (x), ABSIZ (x)); + + ASSERT (mpz_odd_p (n)); + /* ASSERT (mpz_gcd_ui (NULL, n, 6) == 1); */ +#if GMP_NUMB_BITS % 16 == 0 + /* (2^12 - 1) | (2^{GMP_NUMB_BITS*3/4} - 1) */ + g = mpn_mod_34lsub1 (PTR (n), SIZ (n)); + /* (2^12 - 1) = 3^2 * 5 * 7 * 13 */ + ASSERT (g % 3 != 0 && g % 5 != 0 && g % 7 != 0); + if ((g % 5 & 2) != 0) + /* (5/n) = -1, iff n = 2 or 3 (mod 5) */ + /* D = 5; Q = -1 */ + return mpn_strongfibo (PTR (n), SIZ (n), PTR (V)); + else if (! POW2_P (g % 7)) + /* (-7/n) = -1, iff n = 3,5 or 6 (mod 7) */ + D = 7; /* Q = 2 */ + /* (9/n) = -1, never: 9 = 3^2 */ + else if (mpz_oddjacobi_ui (n, 11) == -1) + /* (-11/n) = (n/11) */ + D = 11; /* Q = 3 */ + else if ((((g % 13 - (g % 13 >> 3)) & 7) > 4) || + (((g % 13 - (g % 13 >> 3)) & 7) == 2)) + /* (13/n) = -1, iff n = 2,5,6,7,8 or 11 (mod 13) */ + D = 13; /* Q = -3 */ + else if (g % 3 == 2) + /* (-15/n) = (n/15) = (n/5)*(n/3) */ + /* Here, (n/5) = 1, and */ + /* (n/3) = -1, iff n = 2 (mod 3) */ + D = 15; /* Q = 4 */ +#if GMP_NUMB_BITS % 32 == 0 + /* (2^24 - 1) | (2^{GMP_NUMB_BITS*3/4} - 1) */ + /* (2^24 - 1) = (2^12 - 1) * 17 * 241 */ + else if (! POW2_P (g % 17) && ! POW2_P (17 - g % 17)) + /* (17/n) = -1, iff n != +-1,+-2,+-4,+-8 (mod 17) */ + D = 17; /* Q = -4 */ +#endif +#else + if (mpz_oddjacobi_ui (n, 5) == -1) + return mpn_strongfibo (PTR (n), SIZ (n), PTR (V)); +#endif + else + { + mp_limb_t maxD; + int jac; + + /* n is odd, to possibly be a square, n % 8 = 1 is needed. */ + if (((*PTR (n) & 6) == 0) && UNLIKELY (mpz_perfect_square_p (n))) + return 0; /* A square is composite. */ + + /* Check Ds up to square root (in case, n is prime) + or avoid overflows */ + if (SIZ (n) == 1) + maxD = limb_apprsqrt (* PTR (n)); + else if (BITS_PER_ULONG >= GMP_NUMB_BITS && SIZ (n) == 2) + mpn_sqrtrem (&maxD, (mp_ptr) NULL, PTR (n), 2); + else + maxD = GMP_NUMB_MAX; + maxD = MIN (maxD, ULONG_MAX); + + unsigned Ddiff = 2; +#if GMP_NUMB_BITS % 16 == 0 + const unsigned D2 = 6; +#if GMP_NUMB_BITS % 32 == 0 + D = 19; + Ddiff = 4; +#else + D = 17; +#endif +#else + const unsigned D2 = 4; + D = 7; +#endif + + /* Search a D such that (D/n) = -1 in the sequence 5,-7,9,-11,.. */ + /* For those Ds we have (D/n) = (n/|D|) */ + /* FIXME: Should we loop only on prime Ds? */ + /* The only interesting composite D is 15, because 3 is not tested. */ + for (;;) + { + jac = mpz_oddjacobi_ui (n, D); + if (jac != 1) + break; + if (UNLIKELY (D >= maxD)) + return 1; + D += Ddiff; + Ddiff = D2 - Ddiff; + } + + if (UNLIKELY (jac == 0)) + return 0; + } + + /* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */ + Q = (D & 2) ? (D >> 2) + 1 : -(long) (D >> 2); + /* ASSERT (mpz_si_kronecker ((D & 2) ? NEG_CAST (long, D) : D, n) == -1); */ + + /* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */ + b0 = mpz_scan0 (n, 0); + + mpz_init (T1); + mpz_init (T2); + + /* If Ud != 0 && Vd != 0 */ + if (mpz_lucas_mod (V, Qk, Q, b0, n, T1, T2) == 0) + if (LIKELY (--b0 != 0)) + for (;;) + { + /* V_{2k} <- V_k ^ 2 - 2Q^k */ + mpz_mul (T2, V, V); + mpz_submul_ui (T2, Qk, 2); + mpz_tdiv_r (V, T2, n); + if (SIZ (V) == 0 || UNLIKELY (--b0 == 0)) + break; + /* Q^{2k} = (Q^k)^2 */ + mpz_mul (T2, Qk, Qk); + mpz_tdiv_r (Qk, T2, n); + } + + mpz_clear (T1); + mpz_clear (T2); + + return (b0 != 0); +} diff --git a/gmp-6.3.0/mpz/sub.c b/gmp-6.3.0/mpz/sub.c new file mode 100644 index 0000000..7cb022e --- /dev/null +++ b/gmp-6.3.0/mpz/sub.c @@ -0,0 +1,33 @@ +/* mpz_sub -- subtract integers. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_sub +#include "aors.h" diff --git a/gmp-6.3.0/mpz/sub_ui.c b/gmp-6.3.0/mpz/sub_ui.c new file mode 100644 index 0000000..3ce23d3 --- /dev/null +++ b/gmp-6.3.0/mpz/sub_ui.c @@ -0,0 +1,33 @@ +/* mpz_sub_ui -- Subtract an mpz_t and an unsigned one-word integer. + +Copyright 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + + +#define OPERATION_sub_ui +#include "aors_ui.h" diff --git a/gmp-6.3.0/mpz/swap.c b/gmp-6.3.0/mpz/swap.c new file mode 100644 index 0000000..255fac0 --- /dev/null +++ b/gmp-6.3.0/mpz/swap.c @@ -0,0 +1,39 @@ +/* mpz_swap (dest_integer, src_integer) -- Swap U and V. + +Copyright 1997, 1998, 2001, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_swap (mpz_ptr u, mpz_ptr v) __GMP_NOTHROW +{ + MP_SIZE_T_SWAP (ALLOC(u), ALLOC(v)); + MP_SIZE_T_SWAP (SIZ(u), SIZ(v)); + MP_PTR_SWAP (PTR(v), PTR(u)); +} diff --git a/gmp-6.3.0/mpz/tdiv_q.c b/gmp-6.3.0/mpz/tdiv_q.c new file mode 100644 index 0000000..8c5001d --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_q.c @@ -0,0 +1,87 @@ +/* mpz_tdiv_q -- divide two integers and produce a quotient. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2010, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +void +mpz_tdiv_q (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den) +{ + mp_size_t ql; + mp_size_t ns, ds, nl, dl; + mp_ptr np, dp, qp, tp; + TMP_DECL; + + ns = SIZ (num); + ds = SIZ (den); + nl = ABS (ns); + dl = ABS (ds); + ql = nl - dl + 1; + + if (UNLIKELY (dl == 0)) + DIVIDE_BY_ZERO; + + if (ql <= 0) + { + SIZ (quot) = 0; + return; + } + + qp = MPZ_REALLOC (quot, ql); + + TMP_MARK; + dp = PTR (den); + + /* Copy denominator to temporary space if it overlaps with the quotient. */ + if (dp == qp) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (dl); + MPN_COPY (tp, dp, dl); + dp = tp; + } + + tp = TMP_ALLOC_LIMBS (nl + 1); + np = PTR (num); + /* Copy numerator to temporary space if it overlaps with the quotient. */ + if (np == qp) + { + MPN_COPY (tp, np, nl); + /* Overlap dividend and scratch. */ + np = tp; + } + mpn_div_q (qp, np, nl, dp, dl, tp); + + ql -= qp[ql - 1] == 0; + + SIZ (quot) = (ns ^ ds) >= 0 ? ql : -ql; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/tdiv_q_2exp.c b/gmp-6.3.0/mpz/tdiv_q_2exp.c new file mode 100644 index 0000000..c6b9bd0 --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_q_2exp.c @@ -0,0 +1,67 @@ +/* mpz_tdiv_q_2exp -- Divide an integer by 2**CNT. Round the quotient + towards -infinity. + +Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2012 Free Software Foundation, +Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_tdiv_q_2exp (mpz_ptr r, mpz_srcptr u, mp_bitcnt_t cnt) +{ + mp_size_t un, rn; + mp_size_t limb_cnt; + mp_ptr rp; + mp_srcptr up; + + un = SIZ(u); + limb_cnt = cnt / GMP_NUMB_BITS; + rn = ABS (un) - limb_cnt; + + if (rn <= 0) + rn = 0; + else + { + rp = MPZ_REALLOC (r, rn); + up = PTR(u) + limb_cnt; + + cnt %= GMP_NUMB_BITS; + if (cnt != 0) + { + mpn_rshift (rp, up, rn, cnt); + rn -= rp[rn - 1] == 0; + } + else + { + MPN_COPY_INCR (rp, up, rn); + } + } + + SIZ(r) = un >= 0 ? rn : -rn; +} diff --git a/gmp-6.3.0/mpz/tdiv_q_ui.c b/gmp-6.3.0/mpz/tdiv_q_ui.c new file mode 100644 index 0000000..a11c51e --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_q_ui.c @@ -0,0 +1,83 @@ +/* mpz_tdiv_q_ui(quot, dividend, divisor_limb) + -- Divide DIVIDEND by DIVISOR_LIMB and store the result in QUOT. + +Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2012 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_tdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + SIZ(quot) = 0; + rl = np[0]; + return rl; + } + + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/tdiv_qr.c b/gmp-6.3.0/mpz/tdiv_qr.c new file mode 100644 index 0000000..ad82945 --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_qr.c @@ -0,0 +1,111 @@ +/* mpz_tdiv_qr(quot,rem,dividend,divisor) -- Set QUOT to DIVIDEND/DIVISOR, + and REM to DIVIDEND mod DIVISOR. + +Copyright 1991, 1993, 1994, 2000, 2001, 2005, 2011, 2012, 2021 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +void +mpz_tdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr num, mpz_srcptr den) +{ + mp_size_t ql, n0; + mp_size_t ns, ds, nl, dl; + mp_ptr np, dp, qp, rp; + TMP_DECL; + + ns = SIZ (num); + ds = SIZ (den); + nl = ABS (ns); + dl = ABS (ds); + ql = nl - dl + 1; + + if (UNLIKELY (dl == 0)) + DIVIDE_BY_ZERO; + + rp = MPZ_REALLOC (rem, dl); + + if (ql <= 0) + { + if (num != rem) + { + np = PTR (num); + MPN_COPY (rp, np, nl); + SIZ (rem) = SIZ (num); + } + /* This needs to follow the assignment to rem, in case the + numerator and quotient are the same. */ + SIZ (quot) = 0; + return; + } + + qp = MPZ_REALLOC (quot, ql); + + TMP_MARK; + np = PTR (num); + dp = PTR (den); + + /* FIXME: We should think about how to handle the temporary allocation. + Perhaps mpn_tdiv_qr should handle it, since it anyway often needs to + allocate temp space. */ + + /* Copy denominator to temporary space if it overlaps with the quotient + or remainder. */ + if (dp == rp || dp == qp) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (dl); + MPN_COPY (tp, dp, dl); + dp = tp; + } + /* Copy numerator to temporary space if it overlaps with the quotient or + remainder. */ + if (np == rp || np == qp) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (nl); + MPN_COPY (tp, np, nl); + np = tp; + } + + for (n0 = 0; *dp == 0; ++dp) + { + rp [n0++] = *np++; + --nl; + } + mpn_tdiv_qr (qp, rp + n0, 0L, np, nl, dp, dl - n0); + + ql -= qp[ql - 1] == 0; + MPN_NORMALIZE (rp, dl); + + SIZ (quot) = (ns ^ ds) >= 0 ? ql : -ql; + SIZ (rem) = ns >= 0 ? dl : -dl; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/tdiv_qr_ui.c b/gmp-6.3.0/mpz/tdiv_qr_ui.c new file mode 100644 index 0000000..4e1c9fa --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_qr_ui.c @@ -0,0 +1,100 @@ +/* mpz_tdiv_qr_ui(quot,rem,dividend,short_divisor) -- + Set QUOT to DIVIDEND / SHORT_DIVISOR + and REM to DIVIDEND mod SHORT_DIVISOR. + +Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2012, 2015 +Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_tdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn, qn; + mp_ptr np, qp; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(quot) = 0; + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + qp = MPZ_REALLOC (quot, nn); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp; + mp_size_t rn; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + SIZ(quot) = 0; + rl = np[0]; + SIZ(rem) = ns >= 0 ? 1 : -1; + MPZ_NEWALLOC (rem, 1)[0] = rl; + return rl; + } + + rp = MPZ_REALLOC (rem, 2); + + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + qn = nn - 2 + 1; qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; + rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0); + SIZ(rem) = ns >= 0 ? rn : -rn; + } + else +#endif + { + rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + SIZ(rem) = ns >= 0 ? 1 : -1; + MPZ_NEWALLOC (rem, 1)[0] = rl; + } + qn = nn - (qp[nn - 1] == 0); + } + + SIZ(quot) = ns >= 0 ? qn : -qn; + return rl; +} diff --git a/gmp-6.3.0/mpz/tdiv_r.c b/gmp-6.3.0/mpz/tdiv_r.c new file mode 100644 index 0000000..b0c38d6 --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_r.c @@ -0,0 +1,102 @@ +/* mpz_tdiv_r(rem, dividend, divisor) -- Set REM to DIVIDEND mod DIVISOR. + +Copyright 1991, 1993, 1994, 2000, 2001, 2005, 2012, 2021 Free Software +Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +void +mpz_tdiv_r (mpz_ptr rem, mpz_srcptr num, mpz_srcptr den) +{ + mp_size_t ql, n0; + mp_size_t ns, nl, dl; + mp_ptr np, dp, qp, rp; + TMP_DECL; + + ns = SIZ (num); + nl = ABS (ns); + dl = ABSIZ (den); + ql = nl - dl + 1; + + if (UNLIKELY (dl == 0)) + DIVIDE_BY_ZERO; + + if (ql <= 0) + { + if (num != rem) + { + SIZ (rem) = ns; + rp = MPZ_NEWALLOC (rem, nl); + np = PTR (num); + MPN_COPY (rp, np, nl); + } + return; + } + + rp = MPZ_REALLOC (rem, dl); + + TMP_MARK; + qp = TMP_ALLOC_LIMBS (ql); + np = PTR (num); + dp = PTR (den); + + /* FIXME: We should think about how to handle the temporary allocation. + Perhaps mpn_tdiv_qr should handle it, since it anyway often needs to + allocate temp space. */ + + /* Copy denominator to temporary space if it overlaps with the remainder. */ + if (dp == rp) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (dl); + MPN_COPY (tp, dp, dl); + dp = tp; + } + /* Copy numerator to temporary space if it overlaps with the remainder. */ + if (np == rp) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (nl); + MPN_COPY (tp, np, nl); + np = tp; + } + + for (n0 = 0; *dp == 0; ++dp) + { + rp [n0++] = *np++; + --nl; + } + mpn_tdiv_qr (qp, rp + n0, 0L, np, nl, dp, dl - n0); + + MPN_NORMALIZE (rp, dl); + + SIZ (rem) = ns >= 0 ? dl : -dl; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/tdiv_r_2exp.c b/gmp-6.3.0/mpz/tdiv_r_2exp.c new file mode 100644 index 0000000..96a81f7 --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_r_2exp.c @@ -0,0 +1,76 @@ +/* mpz_tdiv_r_2exp -- Divide an integer by 2**CNT and produce a remainder. + +Copyright 1991, 1993-1995, 2001, 2002, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, mp_bitcnt_t cnt) +{ + mp_size_t in_size = ABSIZ (in); + mp_size_t res_size; + mp_size_t limb_cnt = cnt / GMP_NUMB_BITS; + mp_srcptr in_ptr = PTR (in); + + if (in_size > limb_cnt) + { + /* The input operand is (probably) greater than 2**CNT. */ + mp_limb_t x; + + x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % GMP_NUMB_BITS) - 1); + if (x != 0) + { + res_size = limb_cnt + 1; + MPZ_REALLOC (res, res_size); + + PTR (res)[limb_cnt] = x; + } + else + { + MPN_NORMALIZE (in_ptr, limb_cnt); + + MPZ_REALLOC (res, limb_cnt); + + res_size = limb_cnt; + } + } + else + { + /* The input operand is smaller than 2**CNT. We perform a no-op, + apart from that we might need to copy IN to RES. */ + limb_cnt = in_size; + MPZ_REALLOC (res, limb_cnt); + + res_size = limb_cnt; + } + + if (res != in) + MPN_COPY (PTR (res), PTR (in), limb_cnt); + SIZ (res) = SIZ (in) >= 0 ? res_size : -res_size; +} diff --git a/gmp-6.3.0/mpz/tdiv_r_ui.c b/gmp-6.3.0/mpz/tdiv_r_ui.c new file mode 100644 index 0000000..f3da8ef --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_r_ui.c @@ -0,0 +1,96 @@ +/* mpz_tdiv_r_ui(rem, dividend, divisor_limb) + -- Set REM to DIVDEND mod DIVISOR_LIMB. + +Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2005, 2012, +2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +unsigned long int +mpz_tdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + SIZ(rem) = 0; + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2]; + mp_ptr rp, qp; + mp_size_t rn; + TMP_DECL; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + SIZ(rem) = ns >= 0 ? 1 : -1; + MPZ_NEWALLOC (rem, 1)[0] = rl; + return rl; + } + + rp = MPZ_NEWALLOC (rem, 2); + + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0); + SIZ(rem) = ns >= 0 ? rn : -rn; + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + if (rl == 0) + SIZ(rem) = 0; + else + { + SIZ(rem) = ns >= 0 ? 1 : -1; + MPZ_NEWALLOC (rem, 1)[0] = rl; + } + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/tdiv_ui.c b/gmp-6.3.0/mpz/tdiv_ui.c new file mode 100644 index 0000000..4618599 --- /dev/null +++ b/gmp-6.3.0/mpz/tdiv_ui.c @@ -0,0 +1,84 @@ +/* mpz_tdiv_ui(dividend, divisor_limb) -- Return DIVDEND mod DIVISOR_LIMB. + +Copyright 1991, 1993, 1994, 1996-1998, 2001, 2002, 2004, 2005, 2012 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + +unsigned long int +mpz_tdiv_ui (mpz_srcptr dividend, unsigned long int divisor) +{ + mp_size_t ns, nn; + mp_ptr np; + mp_limb_t rl; + + if (UNLIKELY (divisor == 0)) + DIVIDE_BY_ZERO; + + ns = SIZ(dividend); + if (ns == 0) + { + return 0; + } + + nn = ABS(ns); + np = PTR(dividend); + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (divisor > GMP_NUMB_MAX) + { + mp_limb_t dp[2], rp[2]; + mp_ptr qp; + mp_size_t rn; + TMP_DECL; + + if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ + { + rl = np[0]; + return rl; + } + + TMP_MARK; + dp[0] = divisor & GMP_NUMB_MASK; + dp[1] = divisor >> GMP_NUMB_BITS; + qp = TMP_ALLOC_LIMBS (nn - 2 + 1); + mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); + TMP_FREE; + rl = rp[0] + (rp[1] << GMP_NUMB_BITS); + rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0); + } + else +#endif + { + rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); + } + + return rl; +} diff --git a/gmp-6.3.0/mpz/tstbit.c b/gmp-6.3.0/mpz/tstbit.c new file mode 100644 index 0000000..48725d4 --- /dev/null +++ b/gmp-6.3.0/mpz/tstbit.c @@ -0,0 +1,80 @@ +/* mpz_tstbit -- test a specified bit. + +Copyright 2000, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +/* For negatives the effective twos complement is achieved by negating the + limb tested, either with a ones or twos complement. Twos complement + ("-") is used if there's only zero limbs below the one being tested. + Ones complement ("~") is used if there's a non-zero below. Note that "-" + is correct even if the limb examined is 0 (and the true beginning of twos + complement is further up). + + Testing the limbs below p is unavoidable on negatives, but will usually + need to examine only *(p-1). The search is done from *(p-1) down to + *u_ptr, since that might give better cache locality, and because a + non-zero limb is perhaps a touch more likely in the middle of a number + than at the low end. + + Bits past the end of available data simply follow sign of u. Notice that + the limb_index >= abs_size test covers u=0 too. */ + +int +mpz_tstbit (mpz_srcptr u, mp_bitcnt_t bit_index) __GMP_NOTHROW +{ + mp_srcptr u_ptr = PTR(u); + mp_size_t size = SIZ(u); + unsigned abs_size = ABS(size); + mp_size_t limb_index = bit_index / GMP_NUMB_BITS; + mp_srcptr p = u_ptr + limb_index; + mp_limb_t limb; + + if (limb_index >= abs_size) + return (size < 0); + + limb = *p; + if (size < 0) + { + limb = -limb; /* twos complement */ + + while (p != u_ptr) + { + p--; + if (*p != 0) + { + limb--; /* make it a ones complement instead */ + break; + } + } + } + + return (limb >> (bit_index % GMP_NUMB_BITS)) & 1; +} diff --git a/gmp-6.3.0/mpz/ui_pow_ui.c b/gmp-6.3.0/mpz/ui_pow_ui.c new file mode 100644 index 0000000..87f2d3a --- /dev/null +++ b/gmp-6.3.0/mpz/ui_pow_ui.c @@ -0,0 +1,58 @@ +/* mpz_ui_pow_ui -- ulong raised to ulong. + +Copyright 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +void +mpz_ui_pow_ui (mpz_ptr r, unsigned long b, unsigned long e) +{ +#if GMP_NAIL_BITS != 0 + if (b > GMP_NUMB_MAX) + { + mp_limb_t bb[2]; + bb[0] = b & GMP_NUMB_MASK; + bb[1] = b >> GMP_NUMB_BITS; + mpz_n_pow_ui (r, bb, (mp_size_t) 2, e); + } + else +#endif + { +#ifdef _LONG_LONG_LIMB + /* i386 gcc 2.95.3 doesn't recognise blimb can be eliminated when + mp_limb_t is an unsigned long, so only use a separate blimb when + necessary. */ + mp_limb_t blimb = b; + mpz_n_pow_ui (r, &blimb, (mp_size_t) (b != 0), e); +#else + mpz_n_pow_ui (r, &b, (mp_size_t) (b != 0), e); +#endif + } +} diff --git a/gmp-6.3.0/mpz/ui_sub.c b/gmp-6.3.0/mpz/ui_sub.c new file mode 100644 index 0000000..1d0edb9 --- /dev/null +++ b/gmp-6.3.0/mpz/ui_sub.c @@ -0,0 +1,90 @@ +/* mpz_ui_sub -- Subtract an unsigned one-word integer and an mpz_t. + +Copyright 2002, 2004, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_ui_sub (mpz_ptr w, unsigned long int uval, mpz_srcptr v) +{ + mp_ptr vp, wp; + mp_size_t vn, wn; + mp_limb_t cy; + +#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ + if (uval > GMP_NUMB_MAX) + { + mpz_t u; + mp_limb_t ul[2]; + PTR(u) = ul; + ul[0] = uval & GMP_NUMB_MASK; + ul[1] = uval >> GMP_NUMB_BITS; + SIZ(u) = 2; + mpz_sub (w, u, v); + return; + } +#endif + + vn = SIZ(v); + + if (vn > 1) + { + wp = MPZ_REALLOC (w, vn); + vp = PTR(v); + mpn_sub_1 (wp, vp, vn, (mp_limb_t) uval); + wn = -(vn - (wp[vn - 1] == 0)); + } + else if (vn >= 0) + { + mp_limb_t vp0; + vp0 = PTR (v)[0] & - (mp_limb_t) vn; + wp = MPZ_NEWALLOC (w, 1); + if (uval >= vp0) + { + wp[0] = uval - vp0; + wn = wp[0] != 0; + } + else + { + wp[0] = vp0 - uval; + wn = -1; + } + } + else /* (vn < 0) */ + { + vn = -vn; + wp = MPZ_REALLOC (w, vn + 1); + vp = PTR(v); + cy = mpn_add_1 (wp, vp, vn, (mp_limb_t) uval); + wp[vn] = cy; + wn = vn + (cy != 0); + } + + SIZ(w) = wn; +} diff --git a/gmp-6.3.0/mpz/urandomb.c b/gmp-6.3.0/mpz/urandomb.c new file mode 100644 index 0000000..5c6ad77 --- /dev/null +++ b/gmp-6.3.0/mpz/urandomb.c @@ -0,0 +1,47 @@ +/* mpz_urandomb (rop, state, n) -- Generate a uniform pseudorandom + integer in the range 0 to 2^N - 1, inclusive, using STATE as the + random state previously initialized by a call to gmp_randinit(). + +Copyright 1999, 2000, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_urandomb (mpz_ptr rop, gmp_randstate_ptr rstate, mp_bitcnt_t nbits) +{ + mp_ptr rp; + mp_size_t size; + + size = BITS_TO_LIMBS (nbits); + rp = MPZ_NEWALLOC (rop, size); + + _gmp_rand (rp, rstate, nbits); + MPN_NORMALIZE (rp, size); + SIZ (rop) = size; +} diff --git a/gmp-6.3.0/mpz/urandomm.c b/gmp-6.3.0/mpz/urandomm.c new file mode 100644 index 0000000..4e6b0ba --- /dev/null +++ b/gmp-6.3.0/mpz/urandomm.c @@ -0,0 +1,98 @@ +/* mpz_urandomm (rop, state, n) -- Generate a uniform pseudorandom + integer in the range 0 to N-1, using STATE as the random state + previously initialized by a call to gmp_randinit(). + +Copyright 2000, 2002, 2012, 2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" /* for count_leading_zeros */ + + +#define MAX_URANDOMM_ITER 80 + +void +mpz_urandomm (mpz_ptr rop, gmp_randstate_ptr rstate, mpz_srcptr n) +{ + mp_ptr rp, np; + mp_size_t nbits, size; + mp_limb_t nh; + int count; + int pow2; + int cmp; + TMP_DECL; + + size = ABSIZ (n); + if (UNLIKELY (size == 0)) + DIVIDE_BY_ZERO; + + np = PTR (n); + nh = np[size - 1]; + + /* Detect whether n is a power of 2. */ + pow2 = POW2_P (nh) && (size == 1 || mpn_zero_p (np, size - 1)); + + count_leading_zeros (count, nh); + nbits = size * GMP_NUMB_BITS - (count - GMP_NAIL_BITS) - pow2; + if (nbits == 0) /* nbits == 0 means that n was == 1. */ + { + SIZ (rop) = 0; + return; + } + + TMP_MARK; + if (rop == n) + { + mp_ptr tp; + tp = TMP_ALLOC_LIMBS (size); + MPN_COPY (tp, np, size); + np = tp; + } + + /* Here the allocated size can be one too much if n is a power of + (2^GMP_NUMB_BITS) but it's convenient for using mpn_cmp below. */ + rp = MPZ_NEWALLOC (rop, size); + /* Clear last limb to prevent the case in which size is one too much. */ + rp[size - 1] = 0; + + count = MAX_URANDOMM_ITER; /* Set iteration count limit. */ + do + { + _gmp_rand (rp, rstate, nbits); + MPN_CMP (cmp, rp, np, size); + } + while (cmp >= 0 && --count != 0); + + if (count == 0) + /* Too many iterations; return result mod n == result - n */ + mpn_sub_n (rp, rp, np, size); + + MPN_NORMALIZE (rp, size); + SIZ (rop) = size; + TMP_FREE; +} diff --git a/gmp-6.3.0/mpz/xor.c b/gmp-6.3.0/mpz/xor.c new file mode 100644 index 0000000..5ec657a --- /dev/null +++ b/gmp-6.3.0/mpz/xor.c @@ -0,0 +1,146 @@ +/* mpz_xor -- Logical xor. + +Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012, +2015-2018 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + +void +mpz_xor (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) +{ + mp_srcptr op1_ptr, op2_ptr; + mp_size_t op1_size, op2_size; + mp_ptr res_ptr; + mp_size_t res_size; + + op1_size = SIZ(op1); + op2_size = SIZ(op2); + + if (op1_size < op2_size) + { + MPZ_SRCPTR_SWAP (op1, op2); + MP_SIZE_T_SWAP (op1_size, op2_size); + } + + op1_ptr = PTR(op1); + res_ptr = PTR(res); + + if (op2_size >= 0) + { + if (res_ptr != op1_ptr) + { + res_ptr = MPZ_REALLOC (res, op1_size); + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, + op1_size - op2_size); + } + if (LIKELY (op2_size != 0)) + mpn_xor_n (res_ptr, op1_ptr, PTR(op2), op2_size); + res_size = op1_size; + + MPN_NORMALIZE (res_ptr, res_size); + SIZ(res) = res_size; + } + else + { + mp_ptr opx; + TMP_DECL; + + op2_size = -op2_size; + TMP_MARK; + if (op1_size < 0) + { + mp_ptr opy; + + /* Both operands are negative, the result will be positive. + (-OP1) ^ (-OP2) = + = ~(OP1 - 1) ^ ~(OP2 - 1) = + = (OP1 - 1) ^ (OP2 - 1) */ + + op1_size = -op1_size; + + /* Possible optimization: Decrease mpn_sub precision, + as we won't use the entire res of both. */ + TMP_ALLOC_LIMBS_2 (opx, op1_size, opy, op2_size); + mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1); + op1_ptr = opx; + + mpn_sub_1 (opy, PTR(op2), op2_size, (mp_limb_t) 1); + op2_ptr = opy; + + res_ptr = MPZ_NEWALLOC (res, op2_size); + /* Don't re-read OP1_PTR and OP2_PTR. They point to temporary + space--never to the space PTR(res) used to point to before + reallocation. */ + + MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, + op2_size - op1_size); + mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size); + TMP_FREE; + res_size = op2_size; + + MPN_NORMALIZE (res_ptr, res_size); + SIZ(res) = res_size; + } + else + { + /* Operand 2 negative, so will be the result. + -(OP1 ^ (-OP2)) = -(OP1 ^ ~(OP2 - 1)) = + = ~(OP1 ^ ~(OP2 - 1)) + 1 = + = (OP1 ^ (OP2 - 1)) + 1 */ + + res_size = MAX (op1_size, op2_size); + res_ptr = MPZ_REALLOC (res, res_size + 1); + op1_ptr = PTR(op1); + + opx = TMP_ALLOC_LIMBS (op2_size); + mpn_sub_1 (opx, PTR(op2), op2_size, (mp_limb_t) 1); + op2_ptr = opx; + + if (res_size == op1_size) + { + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size); + mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op2_size); + } + else + { + MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); + if (LIKELY (op1_size != 0)) + mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size); + } + TMP_FREE; + + res_ptr[res_size] = 0; + MPN_INCR_U (res_ptr, res_size + 1, (mp_limb_t) 1); + res_size += res_ptr[res_size]; + + MPN_NORMALIZE_NOT_ZERO (res_ptr, res_size); + SIZ(res) = -res_size; + } + } +} -- cgit v1.2.3