void exp_modulo(mpz_t rop, const mpz_t base, const mpz_t exponent, const mpz_t modulus) { /* fast exp-modulo */ mpz_t c; mpz_init_set_ui(c, 1); mpz_t ex; mpz_init_set(ex, exponent); mpz_t b; mpz_init_set(b, base); mpz_t temp; mpz_init(temp); while (mpz_cmp_ui(ex, 0) > 0) { /* ex mod 2 == 1 */ mpz_fdiv_r_ui(temp, ex, 2); if (mpz_cmp_ui(temp, 1) == 0) { mpz_mul(temp, c, b); mpz_fdiv_r(c, temp, modulus); } /* right shift by 1 */ mpz_fdiv_q_2exp(ex, ex, 1); /* b^2 mod modulus */ mpz_mul(b, b, b); mpz_fdiv_r(b, b, modulus); } mpz_set(rop, c); mpz_clear(c); mpz_clear(ex); mpz_clear(temp); mpz_clear(b); }
std::pair<BigInt,uint16_t> BigInt::DivRem(uint16_t d) const { std::pair<BigInt,uint16_t> ret; mpz_div_ui(ret.first.mImpl,mImpl,d); ret.second = mpz_fdiv_r_ui(0,mImpl,d); return ret; }
static void fp_set_mpz(element_ptr e, mpz_ptr z) { mpz_t r; mpz_init(r); pbc_mpui *p = e->field->data; pbc_mpui *l = e->data; mpz_fdiv_r_ui(r, z, *p); *l = mpz_get_ui(r); mpz_clear(r); }
static PyObject * GMPy_MPZ_IRem_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("mpz modulo by zero"); return NULL; } mpz_fdiv_r(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(rz->z, MPZ(self), temp); } else if (temp == 0) { ZERO_ERROR("mpz modulo by zero"); return NULL; } else { mpz_cdiv_r_ui(rz->z, MPZ(self), -temp); } } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_fdiv_r(rz->z, MPZ(self), tempz); mpz_cloc(tempz); } return (PyObject*)rz; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * Pyxmpz_inplace_rem(PyObject *a, PyObject *b) { mpz_t tempz; mpir_si temp_si; int overflow; if (PyIntOrLong_Check(b)) { temp_si = PyLong_AsSIAndOverflow(b, &overflow); if (overflow) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, b); mpz_fdiv_r(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz); mpz_cloc(tempz); } else if(temp_si > 0) { mpz_fdiv_r_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si); } else if(temp_si == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } else { mpz_cdiv_r_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), -temp_si); } Py_INCREF(a); return a; } if (CHECK_MPZANY(b)) { if(mpz_sgn(Pyxmpz_AS_MPZ(b)) == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } mpz_fdiv_r(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(b)); Py_INCREF(a); return a; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_XMPZ_IRem_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_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_set_PyIntOrLong(global.tempz, other); mpz_fdiv_r(MPZ(self), MPZ(self), global.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; }
/// @jakob: overflow can be occured due to multiplication. use exact mpz for multiply and modulo operation instead! void ARingGF::power(ElementType &result, const ElementType a, const STT n) const { if (givaroField.isnzero(a)) { mpz_t mpz_a; mpz_t mpz_n; mpz_t mpz_tmp; mpz_init( mpz_a); mpz_init( mpz_n); mpz_init( mpz_tmp); mpz_set_si (mpz_n,n); mpz_set_ui (mpz_a,a); //std::cerr << "a = " << a << std::endl; //std::cerr << "mpz_a = " << mpz_a << std::endl; //std::cerr << "n = " << n << std::endl; //std::cerr << "mpz_n = " << mpz_n << std::endl; mpz_fdiv_r_ui(mpz_tmp, mpz_n, givaroField.cardinality() -1) ; mpz_mul(mpz_n, mpz_a, mpz_tmp); STT tmp = static_cast< STT>(mpz_fdiv_ui( mpz_n, givaroField.cardinality() -1)) ; if ( tmp==0 ) { tmp+=givaroField.cardinality()-1; // result=givaroField.one; } //std::cerr << "tmp = " << tmp << std::endl; assert(tmp>=0); // tmp<0 should never occur if (tmp < 0) tmp += givaroField.cardinality()-1 ; result = tmp; } else { if (n<0) ERROR(" division by zero"); result = 0; } }
/* p-adic logarithm */ void padiclog(mpz_t ans, const mpz_t a, unsigned long p, unsigned long prec, const mpz_t modulo) { /* Compute the p-adic logarithm of a, which is supposed to be congruent to 1 mod p Algorithm: 1. we raise a at the power p^(v-1) (for a suitable v) in order to make it closer to 1 2. we write the new a as a product 1/a = (1 - a_0*p^v) (1 - a_1*p^(2*v) (1 - a_2*p^(4*v) ... with 0 <= a_i < p^(v*2^i). 3. we compute each log(1 - a_i*p^(v*2^i)) using Taylor expansion and a binary spliting strategy. */ unsigned long i, v, e, N, saveN, Np, tmp, trunc, step; double den = log(p); mpz_t f, arg, trunc_mod, h, hpow, mpz_tmp, mpz_tmp2, d, inv, mod2; mpz_t *num, *denom; mpz_init(mpz_tmp); mpz_init(mpz_tmp2); mpz_init(arg); mpz_set_ui(ans, 0); mpz_fdiv_r_ui(mpz_tmp, a, p); mpz_set(arg, a); /* First we make the argument closer to 1 by raising it to the p^(v-1) */ if (prec < p) { v = 0; e = 1; } else { v = (unsigned long)(log(prec)/den); // v here is v-1 e = pow(p,v); mpz_mul_ui(mpz_tmp, modulo, e); mpz_powm_ui(arg, arg, e, mpz_tmp); prec += v; } /* Where do we need to truncate the Taylor expansion */ N = prec+v; N /= ++v; // note the ++v Np = N; den *= v; while(1) { tmp = Np + (unsigned long)(log(N)/den); if (tmp == N) break; N = tmp; } /* We allocate memory and initialize variables */ mpz_init(f); mpz_init(mod2); mpz_init(h); mpz_init(hpow); mpz_init(d); mpz_init(inv); sig_block(); num = (mpz_t*)malloc(N*sizeof(mpz_t)); denom = (mpz_t*)malloc(N*sizeof(mpz_t)); sig_unblock(); for (i = 0; i < N; i++) { mpz_init(num[i]); mpz_init(denom[i]); } trunc = v << 1; mpz_init(trunc_mod); mpz_ui_pow_ui(trunc_mod, p, trunc); while(1) { /* We compute f = 1 - a_i*p^((v+1)*2^i) trunc_mod is p^((v+1)*2^(i+1)) */ mpz_fdiv_r(f, arg, trunc_mod); if (mpz_cmp_ui(f, 1) != 0) { mpz_ui_sub(f, 2, f); mpz_mul(arg, arg, f); /* We compute the Taylor expansion of log(f) For now, computations are carried out over the rationals */ for (i = 0; i < N; i++) { mpz_set_ui(num[i], 1); mpz_set_ui(denom[i], i+1); } step = 1; mpz_ui_sub(h, 1, f); // we write f = 1 - h, i.e. h = a_i*p^(2^i) mpz_set(hpow, h); while(step < N) { for (i = 0; i < N - step; i += step << 1) { mpz_mul(mpz_tmp2, hpow, num[i+step]); mpz_mul(mpz_tmp, mpz_tmp2, denom[i]); mpz_mul(num[i], num[i], denom[i+step]); mpz_add(num[i], num[i], mpz_tmp); mpz_mul(denom[i], denom[i], denom[i+step]); } step <<= 1; mpz_mul(hpow, hpow, hpow); } /* We simplify the fraction */ Np = N; tmp = 0; while(Np > 0) { Np /= p; tmp += Np; } mpz_ui_pow_ui(d, p, tmp); mpz_divexact(mpz_tmp, num[0], d); mpz_divexact(denom[0], denom[0], d); mpz_divexact_ui(h, h, e); mpz_mul(mpz_tmp, h, mpz_tmp); /* We coerce the result from Q to Zp */ mpz_gcdext(d, inv, NULL, denom[0], modulo); mpz_mul(mpz_tmp, mpz_tmp, inv); /* We add this contribution to log(f) */ mpz_add(ans, ans, mpz_tmp); } if (trunc > prec) break; /* We update the variables for the next step */ mpz_mul(trunc_mod, trunc_mod, trunc_mod); trunc <<= 1; for (i = N >> 1; i < N; i++) { mpz_clear(num[i]); mpz_clear(denom[i]); } N >>= 1; } mpz_fdiv_r(ans, ans, modulo); /* We clear memory */ mpz_clear(arg); mpz_clear(f); mpz_clear(trunc_mod); mpz_clear(h); mpz_clear(hpow); mpz_clear(mpz_tmp); mpz_clear(d); mpz_clear(inv); mpz_clear(mod2); for (i = 0; i < N; i++) { mpz_clear(num[i]); mpz_clear(denom[i]); } sig_block(); free(num); free(denom); sig_unblock(); }
static PyObject * GMPy_Integer_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPZ_New(context))) return NULL; if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(result->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } else { mpz_cdiv_r_ui(result->z, MPZ(x), -temp); } } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpz_fdiv_r(result->z, MPZ(x), tempz); mpz_cloc(tempz); } return (PyObject*)result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_r(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } if (PyIntOrLong_Check(x)) { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpz_fdiv_r(result->z, tempz, MPZ(y)); mpz_cloc(tempz); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx, *tempy; 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*)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*)result); return NULL; } mpz_fdiv_r(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; }