gmpy2_mpz.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_mpz.c * 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 4 * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * 5 * libraries. * 6 * * 7 * Copyright 2000 - 2009 Alex Martelli * 8 * * 9 * Copyright 2008 - 2021 Case Van Horsen * 10 * * 11 * This file is part of GMPY2. * 12 * * 13 * GMPY2 is free software: you can redistribute it and/or modify it under * 14 * the terms of the GNU Lesser General Public License as published by the * 15 * Free Software Foundation, either version 3 of the License, or (at your * 16 * option) any later version. * 17 * * 18 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * 19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * 20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * 21 * License for more details. * 22 * * 23 * You should have received a copy of the GNU Lesser General Public * 24 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> * 25 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 26 27 PyDoc_STRVAR(GMPy_doc_mpz, 28 "mpz() -> mpz(0)\n\n" 29 " If no argument is given, return mpz(0).\n\n" 30 "mpz(n) -> mpz\n\n" 31 " Return an 'mpz' object with a numeric value 'n' (truncating n\n" 32 " to its integer part if it's a Fraction, 'mpq', float or 'mpfr').\n\n" 33 "mpz(s[, base=0]):\n\n" 34 " Return an 'mpz' object from a string 's' made of digits in the\n" 35 " given base. If base=0, binary, octal, or hex Python strings\n" 36 " are recognized by leading 0b, 0o, or 0x characters, otherwise\n" 37 " the string is assumed to be decimal. Values for base can range\n" 38 " between 2 and 62."); 39 40 /* Since `gmpy2.mpz` is now a type and no longer a factory function, see 41 * gmpy2_cache.c/GMPy_MPZ_NewInit for details on creation. 42 */ 43 44 #ifdef PY3 45 static PyNumberMethods GMPy_MPZ_number_methods = 46 { 47 (binaryfunc) GMPy_Number_Add_Slot, /* nb_add */ 48 (binaryfunc) GMPy_Number_Sub_Slot, /* nb_subtract */ 49 (binaryfunc) GMPy_Number_Mul_Slot, /* nb_multiply */ 50 (binaryfunc) GMPy_Number_Mod_Slot, /* nb_remainder */ 51 (binaryfunc) GMPy_Number_DivMod_Slot, /* nb_divmod */ 52 (ternaryfunc) GMPy_Number_Pow_Slot, /* nb_power */ 53 (unaryfunc) GMPy_MPZ_Minus_Slot, /* nb_negative */ 54 (unaryfunc) GMPy_MPZ_Plus_Slot, /* nb_positive */ 55 (unaryfunc) GMPy_MPZ_Abs_Slot, /* nb_absolute */ 56 (inquiry) GMPy_MPZ_NonZero_Slot, /* nb_bool */ 57 (unaryfunc) GMPy_MPZ_Invert_Slot, /* nb_invert */ 58 (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ 59 (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ 60 (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ 61 (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ 62 (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ 63 (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ 64 0, /* nb_reserved */ 65 (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ 66 (binaryfunc) GMPy_MPZ_IAdd_Slot, /* nb_inplace_add */ 67 (binaryfunc) GMPy_MPZ_ISub_Slot, /* nb_inplace_subtract */ 68 (binaryfunc) GMPy_MPZ_IMul_Slot, /* nb_inplace_multiply */ 69 (binaryfunc) GMPy_MPZ_IRem_Slot, /* nb_inplace_remainder */ 70 (ternaryfunc) GMPy_MPZ_IPow_Slot, /* nb_inplace_power */ 71 (binaryfunc) GMPy_MPZ_ILshift_Slot, /* nb_inplace_lshift */ 72 (binaryfunc) GMPy_MPZ_IRshift_Slot, /* nb_inplace_rshift */ 73 0, /* nb_inplace_and */ 74 0, /* nb_inplace_xor */ 75 0, /* nb_inplace_or */ 76 (binaryfunc) GMPy_Number_FloorDiv_Slot, /* nb_floor_divide */ 77 (binaryfunc) GMPy_Number_TrueDiv_Slot, /* nb_true_divide */ 78 (binaryfunc) GMPy_MPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 79 0, /* nb_inplace_true_divide */ 80 (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ 81 }; 82 83 #else 84 static PyNumberMethods GMPy_MPZ_number_methods = 85 { 86 (binaryfunc) GMPy_Number_Add_Slot, /* nb_add */ 87 (binaryfunc) GMPy_Number_Sub_Slot, /* nb_subtract */ 88 (binaryfunc) GMPy_Number_Mul_Slot, /* nb_multiply */ 89 (binaryfunc) GMPy_Number_Div2_Slot, /* nb_divide */ 90 (binaryfunc) GMPy_Number_Mod_Slot, /* nb_remainder */ 91 (binaryfunc) GMPy_Number_DivMod_Slot, /* nb_divmod */ 92 (ternaryfunc) GMPy_Number_Pow_Slot, /* nb_power */ 93 (unaryfunc) GMPy_MPZ_Minus_Slot, /* nb_negative */ 94 (unaryfunc) GMPy_MPZ_Plus_Slot, /* nb_positive */ 95 (unaryfunc) GMPy_MPZ_Abs_Slot, /* nb_absolute */ 96 (inquiry) GMPy_MPZ_NonZero_Slot, /* nb_bool */ 97 (unaryfunc) GMPy_MPZ_Invert_Slot, /* nb_invert */ 98 (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ 99 (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ 100 (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ 101 (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ 102 (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ 103 0, /* nb_coerce */ 104 (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ 105 (unaryfunc) GMPy_MPZ_Long_Slot, /* nb_long */ 106 (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ 107 (unaryfunc) GMPy_MPZ_Oct_Slot, /* nb_oct */ 108 (unaryfunc) GMPy_MPZ_Hex_Slot, /* nb_hex */ 109 (binaryfunc) GMPy_MPZ_IAdd_Slot, /* nb_inplace_add */ 110 (binaryfunc) GMPy_MPZ_ISub_Slot, /* nb_inplace_subtract */ 111 (binaryfunc) GMPy_MPZ_IMul_Slot, /* nb_inplace_multiply */ 112 0, /* nb_inplace_divide */ 113 (binaryfunc) GMPy_MPZ_IRem_Slot, /* nb_inplace_remainder */ 114 (ternaryfunc) GMPy_MPZ_IPow_Slot, /* nb_inplace_power */ 115 (binaryfunc) GMPy_MPZ_ILshift_Slot, /* nb_inplace_lshift */ 116 (binaryfunc) GMPy_MPZ_IRshift_Slot, /* nb_inplace_rshift */ 117 0, /* nb_inplace_and */ 118 0, /* nb_inplace_xor */ 119 0, /* nb_inplace_or */ 120 (binaryfunc) GMPy_Number_FloorDiv_Slot, /* nb_floor_divide */ 121 (binaryfunc) GMPy_Number_TrueDiv_Slot, /* nb_true_divide */ 122 (binaryfunc) GMPy_MPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 123 0, /* nb_inplace_true_divide */ 124 (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ 125 }; 126 #endif 127 128 static PyMappingMethods GMPy_MPZ_mapping_methods = { 129 (lenfunc)GMPy_MPZ_Method_Length, 130 (binaryfunc)GMPy_MPZ_Method_SubScript, 131 NULL 132 }; 133 134 static PyGetSetDef GMPy_MPZ_getseters[] = 135 { 136 { "numerator", (getter)GMPy_MPZ_Attrib_GetNumer, NULL, 137 "the numerator of a rational number in lowest terms", NULL }, 138 { "denominator", (getter)GMPy_MPZ_Attrib_GetDenom, NULL, 139 "the denominator of a rational number in lowest terms", NULL }, 140 { "real", (getter)GMPy_MPZ_Attrib_GetReal, NULL, 141 "the real part of a complex number", NULL }, 142 { "imag", (getter)GMPy_MPZ_Attrib_GetImag, NULL, 143 "the imaginary part of a complex number", NULL }, 144 {NULL} 145 }; 146 147 static PyMethodDef GMPy_MPZ_methods [] = 148 { 149 { "__format__", GMPy_MPZ_Format, METH_VARARGS, GMPy_doc_mpz_format }, 150 { "__ceil__", GMPy_MPZ_Method_Ceil, METH_NOARGS, GMPy_doc_mpz_method_ceil }, 151 { "__floor__", GMPy_MPZ_Method_Floor, METH_NOARGS, GMPy_doc_mpz_method_floor }, 152 { "__round__", GMPy_MPZ_Method_Round, METH_VARARGS, GMPy_doc_mpz_method_round }, 153 { "__sizeof__", GMPy_MPZ_Method_SizeOf, METH_NOARGS, GMPy_doc_mpz_method_sizeof }, 154 { "__trunc__", GMPy_MPZ_Method_Trunc, METH_NOARGS, GMPy_doc_mpz_method_trunc }, 155 { "bit_clear", GMPy_MPZ_bit_clear_method, METH_O, doc_bit_clear_method }, 156 { "bit_flip", GMPy_MPZ_bit_flip_method, METH_O, doc_bit_flip_method }, 157 { "bit_length", GMPy_MPZ_bit_length_method, METH_NOARGS, doc_bit_length_method }, 158 { "bit_scan0", GMPy_MPZ_bit_scan0_method, METH_VARARGS, doc_bit_scan0_method }, 159 { "bit_scan1", GMPy_MPZ_bit_scan1_method, METH_VARARGS, doc_bit_scan1_method }, 160 { "bit_set", GMPy_MPZ_bit_set_method, METH_O, doc_bit_set_method }, 161 { "bit_test", GMPy_MPZ_bit_test_method, METH_O, doc_bit_test_method }, 162 { "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate }, 163 { "digits", GMPy_MPZ_Digits_Method, METH_VARARGS, GMPy_doc_mpz_digits_method }, 164 { "is_congruent", GMPy_MPZ_Method_IsCongruent, METH_VARARGS, GMPy_doc_mpz_method_is_congruent }, 165 { "is_divisible", GMPy_MPZ_Method_IsDivisible, METH_O, GMPy_doc_mpz_method_is_divisible }, 166 { "is_even", GMPy_MPZ_Method_IsEven, METH_NOARGS, GMPy_doc_mpz_method_is_even }, 167 { "is_odd", GMPy_MPZ_Method_IsOdd, METH_NOARGS, GMPy_doc_mpz_method_is_odd }, 168 { "is_power", GMPy_MPZ_Method_IsPower, METH_NOARGS, GMPy_doc_mpz_method_is_power }, 169 { "is_prime", GMPy_MPZ_Method_IsPrime, METH_VARARGS, GMPy_doc_mpz_method_is_prime }, 170 { "is_square", GMPy_MPZ_Method_IsSquare, METH_NOARGS, GMPy_doc_mpz_method_is_square }, 171 { "num_digits", GMPy_MPZ_Method_NumDigits, METH_VARARGS, GMPy_doc_mpz_method_num_digits }, 172 { NULL, NULL, 1 } 173 }; 174 175 static PyTypeObject MPZ_Type = 176 { 177 /* PyObject_HEAD_INIT(&PyType_Type) */ 178 #ifdef PY3 179 PyVarObject_HEAD_INIT(NULL, 0) 180 #else 181 PyObject_HEAD_INIT(0) 182 0, /* ob_size */ 183 #endif 184 "mpz", /* tp_name */ 185 sizeof(MPZ_Object), /* tp_basicsize */ 186 0, /* tp_itemsize */ 187 /* methods */ 188 (destructor) GMPy_MPZ_Dealloc, /* tp_dealloc */ 189 0, /* tp_print */ 190 0, /* tp_getattr */ 191 0, /* tp_setattr */ 192 0, /* tp_reserved */ 193 (reprfunc) GMPy_MPZ_Repr_Slot, /* tp_repr */ 194 &GMPy_MPZ_number_methods, /* tp_as_number */ 195 0, /* tp_as_sequence */ 196 &GMPy_MPZ_mapping_methods, /* tp_as_mapping */ 197 (hashfunc) GMPy_MPZ_Hash_Slot, /* tp_hash */ 198 0, /* tp_call */ 199 (reprfunc) GMPy_MPZ_Str_Slot, /* tp_str */ 200 0, /* tp_getattro */ 201 0, /* tp_setattro */ 202 0, /* tp_as_buffer */ 203 #ifdef PY3 204 Py_TPFLAGS_DEFAULT, /* tp_flags */ 205 #else 206 Py_TPFLAGS_HAVE_INDEX|Py_TPFLAGS_HAVE_RICHCOMPARE| \ 207 Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_CLASS| \ 208 Py_TPFLAGS_HAVE_INPLACEOPS, 209 #endif 210 GMPy_doc_mpz, /* tp_doc */ 211 0, /* tp_traverse */ 212 0, /* tp_clear */ 213 (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 214 0, /* tp_weaklistoffset*/ 215 0, /* tp_iter */ 216 0, /* tp_iternext */ 217 GMPy_MPZ_methods, /* tp_methods */ 218 0, /* tp_members */ 219 GMPy_MPZ_getseters, /* tp_getset */ 220 0, /* tp_base */ 221 0, /* tp_dict */ 222 0, /* tp_descr_get */ 223 0, /* tp_descr_set */ 224 0, /* tp_dictoffset */ 225 0, /* tp_init */ 226 0, /* tp_alloc */ 227 GMPy_MPZ_NewInit, /* tp_new */ 228 0, /* tp_free */ 229 }; 230