/ src / gmpy2_mpz.c
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