static PyObject * GMPy_Integer_Abs(PyObject *x, CTXT_Object *context) { MPZ_Object *result = NULL; if (MPZ_Check(x)) { if (mpz_sgn(MPZ(x)) >= 0) { Py_INCREF(x); return x; } else { if ((result = GMPy_MPZ_New(context))) mpz_abs(result->z, MPZ(x)); return (PyObject*)result; } } /* This is safe because result is not an incremented reference to an * existing value. Why? * 1) No values are interned like Python's integers. * 2) MPZ is already handled so GMPy_MPZ_From_Integer() can't return * an incremented reference to an existing value (which it would do * if passed an MPZ). */ if ((result = GMPy_MPZ_From_Integer(x, context))) { mpz_abs(result->z, result->z); } return (PyObject*)result; }
static PyObject * GMPy_MPZ_Function_Isqrt(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) < 0) { VALUE_ERROR("isqrt() of negative number"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_sqrt(result->z, MPZ(other)); } } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("isqrt() requires 'mpz' argument"); return NULL; } if (mpz_sgn(result->z) < 0) { VALUE_ERROR("isqrt() of negative number"); Py_DECREF((PyObject*)result); return NULL; } mpz_sqrt(result->z, result->z); } return (PyObject*)result; }
static PyObject * GMPy_MPZ_Add_Slot(PyObject *x, PyObject *y) { if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { MPZ_Object *result; if ((result = GMPy_MPZ_New(NULL))) { mpz_add(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Add(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Add(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Add(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Xor_Slot(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(self)) { if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_New(NULL))) return NULL; mpz_xor(result->z, MPZ(self), MPZ(other)); } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) return NULL; mpz_xor(result->z, MPZ(self), result->z); } } else if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_From_Integer(self, NULL))) return NULL; mpz_xor(result->z, result->z, MPZ(other)); } else { Py_RETURN_NOTIMPLEMENTED; } return (PyObject*)result; }
static PyObject * GMPy_MPZ_FloorDiv_Slot(PyObject *x, PyObject *y) { if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { MPZ_Object *result; if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_fdiv_q(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_FloorDiv(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_FloorDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_FloorDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_FloorDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Mul_Slot(PyObject *x, PyObject *y) { if (MPZ_Check(x) && MPZ_Check(y)) { MPZ_Object *result = NULL; if ((result = GMPy_MPZ_New(NULL))) { mpz_mul(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Mul(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mul(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mul(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Method_IsDivisible(PyObject *self, PyObject *other) { unsigned long temp; int error, res; MPZ_Object *tempd; temp = GMPy_Integer_AsUnsignedLongAndError(other, &error); if (!error) { res = mpz_divisible_ui_p(MPZ(self), temp); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } if (!(tempd = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_divisible() requires integer argument"); return NULL; } res = mpz_divisible_p(MPZ(self), tempd->z); Py_DECREF((PyObject*)tempd); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static PyObject * GMPy_MPZ_IMul_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(other)) { mpz_mul(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { mpz_mul_si(rz->z, MPZ(self), temp); } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_mul(rz->z, MPZ(self), tempz); mpz_cloc(tempz); } return (PyObject*)rz; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_bit_length_method(PyObject *self, PyObject *other) { mp_bitcnt_t n = 0; if (mpz_size(MPZ(self))) n = mpz_sizeinbase(MPZ(self), 2); return PyIntOrLong_FromMpBitCnt(n); }
static PyObject * GMPy_XMPZ_ISub_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp >= 0) { mpz_sub_ui(MPZ(self), MPZ(self), temp); } else { mpz_add_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_sub(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_sub(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_XMPZ_IAdd_Slot(PyObject *self, PyObject *other) { /* Try to make mpz + small_int faster */ if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { if (temp >= 0) { mpz_add_ui(MPZ(self), MPZ(self), temp); } else { mpz_sub_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_add(MPZ(self), MPZ(self), tempz); mpz_cloc(tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_add(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Function_Remove(PyObject *self, PyObject *args) { MPZ_Object *result = NULL, *tempx = NULL, *tempf = NULL; PyObject *x, *f; size_t multiplicity; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); f = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(f)) { if (mpz_cmp_si(MPZ(f), 2) < 0) { VALUE_ERROR("factor must be > 1"); Py_DECREF((PyObject*)result); return NULL; } multiplicity = mpz_remove(result->z, MPZ(x), MPZ(f)); return Py_BuildValue("(Nk)", result, multiplicity); } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempf = GMPy_MPZ_From_Integer(f, NULL))) { TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempf); Py_DECREF((PyObject*)result); return NULL; } if (mpz_cmp_si(MPZ(tempf), 2) < 0) { VALUE_ERROR("factor must be > 1"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempf); Py_DECREF((PyObject*)result); return NULL; } multiplicity = mpz_remove(result->z, tempx->z, tempf->z); return Py_BuildValue("(Nk)", result, multiplicity); } }
static PyObject * GMPy_MPZ_Function_GCDext(PyObject *self, PyObject *args) { PyObject *arg0, *arg1, *result = NULL; MPZ_Object *g = NULL, *s = NULL, *t = NULL, *tempa = NULL, *tempb = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = PyTuple_New(3)) || !(g = GMPy_MPZ_New(NULL)) || !(s = GMPy_MPZ_New(NULL)) || !(t = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)g); Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)t); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(arg0) && MPZ_Check(arg1)) { mpz_gcdext(g->z, s->z, t->z, MPZ(arg0), MPZ(arg1)); } else { if(!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempa); Py_XDECREF((PyObject*)tempb); Py_DECREF((PyObject*)g); Py_DECREF((PyObject*)s); Py_DECREF((PyObject*)t); Py_DECREF(result); return NULL; } mpz_gcdext(g->z, s->z, t->z, tempa->z, tempb->z); Py_DECREF((PyObject*)tempa); Py_DECREF((PyObject*)tempb); } PyTuple_SET_ITEM(result, 0, (PyObject*)g); PyTuple_SET_ITEM(result, 1, (PyObject*)s); PyTuple_SET_ITEM(result, 2, (PyObject*)t); return result; }
static PyObject * GMPy_MPZ_Method_Round(PyObject *self, PyObject *args) { Py_ssize_t round_digits; MPZ_Object *result; mpz_t temp, rem; if (PyTuple_GET_SIZE(args) == 0) { Py_INCREF(self); return self; } round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } if (round_digits >= 0) { Py_INCREF(self); return self; } round_digits = -round_digits; if ((result = GMPy_MPZ_New(NULL))) { if (round_digits >= mpz_sizeinbase(MPZ(self), 10)) { mpz_set_ui(result->z, 0); } else { mpz_inoc(temp); mpz_inoc(rem); mpz_ui_pow_ui(temp, 10, round_digits); mpz_fdiv_qr(result->z, rem, MPZ(self), temp); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, temp) > 0) { mpz_add_ui(result->z, result->z, 1); } else if (mpz_cmp(rem, temp) == 0) { if (mpz_odd_p(result->z)) { mpz_add_ui(result->z, result->z, 1); } } mpz_mul(result->z, result->z, temp); mpz_cloc(rem); mpz_cloc(temp); } } return (PyObject*)result; }
static PyObject * GMPy_MPZ_Function_Divexact(PyObject *self, PyObject *args) { PyObject *x, *y; MPZ_Object *result, *tempx= NULL, *tempy = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, MPZ(x), MPZ(y)); } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(MPZ(tempy)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)result; }
static PyObject * GMPy_XMPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod) { mp_bitcnt_t exp; exp = mp_bitcnt_t_From_Integer(other); if (exp == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } mpz_pow_ui(MPZ(self), MPZ(self), exp); Py_INCREF((PyObject*)self); return (PyObject*)self; }
static PyObject * GMPy_XMPZ_Method_MakeMPZ(PyObject *self, PyObject *other) { MPZ_Object* result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_swap(result->z, MPZ(self)); mpz_set_ui(MPZ(self), 0); return (PyObject*)result; }
static PyObject * GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args) { int res; MPZ_Object *tempy = NULL, *tempm = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("is_congruent() requires 2 integer arguments"); return NULL; } if (!(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)tempm); TYPE_ERROR("is_congruent() requires 2 integer arguments"); return NULL; } res = mpz_congruent_p(MPZ(self), tempy->z, tempm->z); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempm); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static PyObject * GMPy_MPZ_Lshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t count; MPZ_Object *result, *tempx; count = mp_bitcnt_t_From_Integer(other); if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred()) return NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(self)) { mpz_mul_2exp(result->z, MPZ(self), count); return (PyObject*)result; } else { if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_mul_2exp(result->z, tempx->z, count); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } }
static PyObject * GMPy_MPZ_Method_IsPrime(PyObject *self, PyObject *args) { int i; unsigned long reps = 25; Py_ssize_t argc; argc = PyTuple_GET_SIZE(args); if (argc > 1) { TYPE_ERROR("is_prime() takes at most 1 argument"); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { reps = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); if (reps == -1 && PyErr_Occurred()) { return NULL; } /* Silently limit n to a reasonable value. */ if (reps > 1000) { reps = 1000; } } i = mpz_probab_prime_p(MPZ(self), (int)reps); if (i) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static PyObject * GMPy_MPZ_Function_IsOdd(PyObject *self, PyObject *other) { int res; MPZ_Object *tempx; if (CHECK_MPZANY(other)) { res = mpz_odd_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_odd() requires 'mpz' argument"); return NULL; } else { res = mpz_odd_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static PyObject * GMPy_XMPZ_ILshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t shift; if (IS_INTEGER(other)) { shift = mp_bitcnt_t_From_Integer(other); if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; mpz_mul_2exp(MPZ(self), MPZ(self), shift); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_XMPZ_IMul_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { mpz_mul_si(MPZ(self), MPZ(self), temp); } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_mul(MPZ(self), MPZ(self), tempz); mpz_cloc(tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_mul(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_XMPZ_IIor_Slot(PyObject *self, PyObject *other) { if(CHECK_MPZANY(other)) { mpz_ior(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } if(PyIntOrLong_Check(other)) { mpz_set_PyIntOrLong(global.tempz, other); mpz_ior(MPZ(self), MPZ(self), global.tempz); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Invert_Slot(MPZ_Object *self) { MPZ_Object *result; if ((result = GMPy_MPZ_New(NULL))) mpz_com(result->z, MPZ(self)); return (PyObject*)result; }
static PyObject * GMPy_XMPZ_IRem_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(MPZ(self), MPZ(self), temp); } else if (temp == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } else { mpz_cdiv_r_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_fdiv_r(MPZ(self), MPZ(self), tempz); mpz_cloc(tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { if(mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } mpz_fdiv_r(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_IAdd_Slot(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; if (CHECK_MPZANY(other)) { if ((result = GMPy_MPZ_New(NULL))) { mpz_add(result->z, MPZ(self), MPZ(other)); } return (PyObject*)result; } if (PyLong_CheckExact(other)) { if ((result = GMPy_MPZ_New(NULL))) { switch (Py_SIZE((PyLongObject*)other)) { case -1: mpz_sub_ui(result->z, MPZ(self), ((PyLongObject*)other)->ob_digit[0]); return (PyObject*)result; case 0: case 1: mpz_add_ui(result->z, MPZ(self), ((PyLongObject*)other)->ob_digit[0]); return (PyObject*)result; default: break; } } else { return NULL; } } if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if ((result = GMPy_MPZ_New(NULL))) { if (!error) { if (temp >= 0) { mpz_add_ui(result->z, MPZ(self), temp); } else { mpz_sub_ui(result->z, MPZ(self), -temp); } } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_add(result->z, MPZ(self), tempz); mpz_cloc(tempz); } } return (PyObject*)result; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_MPZ_Method_IsPower(PyObject *self, PyObject *other) { int res; res = mpz_perfect_power_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static PyObject * _GMPy_MPZ_Minus(PyObject *x, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_neg(result->z, MPZ(x)); return (PyObject*)result; }
static PyObject * GMPy_MPZ_Method_IsOdd(PyObject *self, PyObject *other) { int res; res = mpz_odd_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }