Exemple #1
0
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;
}
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #7
0
 /// @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;
      }
  }
Exemple #8
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();
}
Exemple #9
0
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;
}