static void push(mpz_t val, const unsigned int *p, int r) { unsigned long int n; mpz_t dum; p += r<<1; mpz_init(dum); n = mpz_fdiv_qr_ui(val, dum, val, p[0]); mpz_clear(dum); mpz_mul_ui(val, val, 256); mpz_add_ui(val, val, n+p[1]); }
/** * \fn unsigned char* conversion256(unsigned char* conv, mpz_t n, unsigned int blocs) * \brief conversion d'un entier n de base 10 à une numération en base 256 * \param conv numération converti * \param n entier en base 10 * \param taille taille de la numération * */ void conversion256(unsigned char* conv, mpz_t n, unsigned int blocs) // base 10 -> 256 { int i; mpz_t temp,temp2; mpz_init(temp); mpz_init(temp2); mpz_set(temp,n); for (i=blocs-1;i>=0;i--) conv[i] = (unsigned char)mpz_fdiv_qr_ui(temp,temp2,temp,256); mpz_clear(temp); }
static int pop(mpz_t val, const unsigned int *p) { unsigned long int n; int r = 0; mpz_t dum; mpz_init(dum); n = mpz_fdiv_qr_ui(val, dum, val, 256); mpz_clear(dum); while(n<p[1] || n>=p[0]+p[1]) { r++; p += 2; } mpz_mul_ui(val, val, *p++); mpz_add_ui(val, val, n-*p); return r; }
static void gmp_to_sac(Word *sac_int, mpz_ptr gmp_int) { MP_INT n, q, r; Word i = 0; long d; short set_neg_flag = mpz_is_neg(gmp_int); if (abs(gmp_int->_mp_size) == 1) { d = mpz_get_si(gmp_int); if (set_neg_flag && (d > 0)) d = -d; if (abs(d) < BETA) { *sac_int = d; return; } } mpz_init(&n); mpz_set(&n, gmp_int); mpz_init(&q); mpz_init(&r); if (set_neg_flag) n._mp_size = -n._mp_size; *sac_int = NIL; while (1) { d = mpz_fdiv_qr_ui(&q, &r, &n, BETA); if (set_neg_flag && (d > 0)) d = -d; *sac_int = LEINST(*sac_int, i, d); i++; d = mpz_cmp_si(&q, BETA); if (mpz_cmp_si(&q, BETA) < 0) break; mpz_clear(&n); mpz_set(&n, &q); } /* * now get the last value from q */ d = mpz_get_si(&q); if (set_neg_flag && (d > 0)) d = -d; *sac_int = LEINST(*sac_int, i, d); }
static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result = NULL; MPZ_Object *tempx = NULL, *tempy = NULL, *rem = NULL, *quo = NULL; if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPZ_New(context)) || !(quo = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (error) { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz); mpz_cloc(tempz); } else if (temp > 0) { mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp); mpz_neg(quo->z, quo->z); } PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y)); mpz_cloc(tempz); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_DivMod()."); /* LCOV_EXCL_STOP */ error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; }
static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result; MPZ_Object *tempx, *tempy, *rem, *quo; mpz_t tempz; long temp; int error; result = PyTuple_New(2); rem = GMPy_MPZ_New(context); quo = GMPy_MPZ_New(context); if (!result || !rem || !quo) { Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; } if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { temp = GMPy_Integer_AsLongAndError(y, &error); if (error) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz); mpz_cloc(tempz); } else if (temp > 0) { mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } else { mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp); mpz_neg(quo->z, quo->z); } PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y)); mpz_cloc(tempz); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) { tempx = GMPy_MPZ_From_Integer(x, context); tempy = GMPy_MPZ_From_Integer(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Integer to mpz"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; }
void fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(h)) { printf("Exception: division by zero in fmpz_fdiv_q\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* h is also small */ { fmpz q = c1 / c2; /* compute C quotient */ fmpz r = c1 - c2 * q; /* compute remainder */ if ((c2 > 0L && r < 0L) || (c2 < 0L && r > 0L)) { q--; /* q cannot overflow as remainder implies |c2| != 1 */ r += c2; } fmpz_set_si(f, q); fmpz_set_si(s, r); } else /* h is large and g is small */ { if (c1 == 0L) { fmpz_set_ui(f, 0L); /* g is zero */ fmpz_set_si(s, c1); } else if ((c1 < 0L && fmpz_sgn(h) < 0) || (c1 > 0L && fmpz_sgn(h) > 0)) /* signs are the same */ { fmpz_zero(f); /* quotient is positive, round down to zero */ fmpz_set_si(s, c1); } else { fmpz_add(s, g, h); fmpz_set_si(f, -1L); /* quotient is negative, round down to minus one */ } } } else /* g is large */ { __mpz_struct *mpz_ptr, *mpz_ptr2; _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */ mpz_ptr2 = _fmpz_promote(s); mpz_ptr = COEFF_TO_PTR(*f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { mpz_fdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2); } else { mpz_cdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2); mpz_neg(mpz_ptr, mpz_ptr); } } else /* both are large */ { mpz_fdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); } _fmpz_demote_val(f); /* division by h may result in small value */ _fmpz_demote_val(s); /* division by h may result in small value */ } }