Exemplo n.º 1
0
/* Called when g is supposed to be gcd(a,b), and g = s a + t b, for some t.
   Uses temp1, temp2 and temp3. */
static int
gcdext_valid_p (const mpz_t a, const mpz_t b, const mpz_t g, const mpz_t s)
{
  /* It's not clear that gcd(0,0) is well defined, but we allow it and require that
     gcd(0,0) = 0. */
  if (mpz_sgn (g) < 0)
    return 0;

  if (mpz_sgn (a) == 0)
    {
      /* Must have g == abs (b). Any value for s is in some sense "correct",
	 but it makes sense to require that s == 0. */
      return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
    }
  else if (mpz_sgn (b) == 0)
    {
      /* Must have g == abs (a), s == sign (a) */
      return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
    }

  if (mpz_sgn (g) <= 0)
    return 0;

  mpz_tdiv_qr (temp1, temp3, a, g);
  if (mpz_sgn (temp3) != 0)
    return 0;

  mpz_tdiv_qr (temp2, temp3, b, g);
  if (mpz_sgn (temp3) != 0)
    return 0;

  /* Require that 2 |s| < |b/g|, or |s| == 1. */
  if (mpz_cmpabs_ui (s, 1) > 0)
    {
      mpz_mul_2exp (temp3, s, 1);
      if (mpz_cmpabs (temp3, temp2) >= 0)
	return 0;
    }

  /* Compute the other cofactor. */
  mpz_mul(temp2, s, a);
  mpz_sub(temp2, g, temp2);
  mpz_tdiv_qr(temp2, temp3, temp2, b);

  if (mpz_sgn (temp3) != 0)
    return 0;

  /* Require that 2 |t| < |a/g| or |t| == 1*/
  if (mpz_cmpabs_ui (temp2, 1) > 0)
    {
      mpz_mul_2exp (temp2, temp2, 1);
      if (mpz_cmpabs (temp2, temp1) >= 0)
	return 0;
    }
  return 1;
}
Exemplo n.º 2
0
static PyObject *
Pygmpy_t_divmod(PyObject *self, PyObject *args)
{
    PyObject *x, *y, *result;
    PympzObject *q, *r, *tempx, *tempy;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("t_divmod() requires 'mpz','mpz' arguments");
        return NULL;
    }

    x = PyTuple_GET_ITEM(args, 0);
    y = PyTuple_GET_ITEM(args, 1);
    CREATE_TWO_MPZ_TUPLE(q, r, result);

    if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) {
        if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) {
            ZERO_ERROR("t_divmod() division by 0");
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        mpz_tdiv_qr(q->z, r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y));
    }
    else {
        tempx = Pympz_From_Integer(x);
        tempy = Pympz_From_Integer(y);
        if (!tempx || !tempy) {
            TYPE_ERROR("t_divmod() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) {
            ZERO_ERROR("t_divmod() division by 0");
            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)q);
            Py_DECREF((PyObject*)r);
            Py_DECREF(result);
            return NULL;
        }
        mpz_tdiv_qr(q->z, r->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
    }
    PyTuple_SET_ITEM(result, 0, (PyObject*)q);
    PyTuple_SET_ITEM(result, 1, (PyObject*)r);
    return result;
}
Exemplo n.º 3
0
void
mpz_fdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
{
  mp_size_t divisor_size = divisor->_mp_size;
  mp_size_t xsize;
  mpz_t temp_divisor;		/* N.B.: lives until function returns! */
  TMP_DECL (marker);

  TMP_MARK (marker);

  /* We need the original value of the divisor after the quotient and
     remainder have been preliminary calculated.  We have to copy it to
     temporary space if it's the same variable as either QUOT or REM.  */
  if (quot == divisor || rem == divisor)
    {
      MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
      mpz_set (temp_divisor, divisor);
      divisor = temp_divisor;
    }

  xsize = dividend->_mp_size ^ divisor_size;;
  mpz_tdiv_qr (quot, rem, dividend, divisor);

  if (xsize < 0 && rem->_mp_size != 0)
    {
      mpz_sub_ui (quot, quot, 1L);
      mpz_add (rem, rem, divisor);
    }

  TMP_FREE (marker);
}
/* Called when g is supposed to be gcd(a,b), and g = s a + t b, for some t.
   Uses temp1 and temp2 */
static int
gcdext_valid_p (const mpz_t a, const mpz_t b, const mpz_t g, const mpz_t s)
{
  /* It's not clear that gcd(0,0) is well defined, but we allow it and require that
     allow gcd(0,0) = 0. */
  if (mpz_sgn (g) < 0)
    return 0;
  
  if (mpz_sgn (a) == 0)
    {
      /* Must have g == abs (b). Any value for s is in some sense "correct",
	 but it makes sense to require that s == 0. */
      return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
    }
  else if (mpz_sgn (b) == 0)
    {
      /* Must have g == abs (a), s == sign (a) */
      return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
    }

  if (mpz_sgn (g) <= 0)
    return 0;

  if (! (mpz_divisible_p (a, g)
	 && mpz_divisible_p (b, g)
	 && mpz_cmpabs (s, b) <= 0))
    return 0;
      
  mpz_mul(temp1, s, a);
  mpz_sub(temp1, g, temp1);
  mpz_tdiv_qr(temp1, temp2, temp1, b);

  return mpz_sgn (temp2) == 0 && mpz_cmpabs (temp1, a) <= 0;
}
Exemplo n.º 5
0
void C_BigInt::divideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) {
  mpz_t quotient ;
  mpz_init (quotient) ;
  mpz_tdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ;
  mpz_swap (quotient, mGMPint) ;
  mpz_clear (quotient) ;
}
Exemplo n.º 6
0
void euclidianGCD(mpz_t *gcd, mpz_t numA, mpz_t numB) {
 
    mpz_t quotient; mpz_init(quotient);
    mpz_t remainder; mpz_init(remainder);

    // if either number is <= 0, bail
    if (mpz_cmp_ui(numA, 0) <= 0 || mpz_cmp_ui(numB, 0) <= 0) {
        fprintf(stderr, "Cannot calculate GCD of non positive integer. GCD has not been set.\n");       
        return;
    }

    // if A is smaller than B then swap them
    if (mpz_cmp(numA, numB) < 0) {
        mpz_t temp;
        mpz_set(temp, numA);
        mpz_set(numA, numB);
        mpz_set(numB, temp);
    }

    do {
        mpz_tdiv_qr(quotient, remainder, numA, numB);

        if(mpz_cmp_ui(remainder, 0) == 0) {
            mpz_set(*gcd, numB);
            return;            
        }

        else {
            mpz_set(numA, numB);
            mpz_set(numB, remainder);
        }

    } while (mpz_cmp_ui(remainder, 0) > 0); // Should this just be while(true)
}
Exemplo n.º 7
0
void
mpz_cdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
{
  mp_size_t divisor_size = SIZ (divisor);
  mp_size_t xsize;
  mpz_t temp_divisor;		/* N.B.: lives until function returns! */
  TMP_DECL;

  TMP_MARK;

  /* We need the original value of the divisor after the quotient and
     remainder have been preliminary calculated.  We have to copy it to
     temporary space if it's the same variable as either QUOT or REM.  */
  if (quot == divisor || rem == divisor)
    {
      MPZ_TMP_INIT (temp_divisor, (int) ABS (divisor_size)); // (int) added by PM
      mpz_set (temp_divisor, divisor);
      divisor = temp_divisor;
    }

  xsize = SIZ (dividend) ^ divisor_size;;
  mpz_tdiv_qr (quot, rem, dividend, divisor);

  if (xsize >= 0 && SIZ (rem) != 0)
    {
      mpz_add_ui (quot, quot, 1L);
      mpz_sub (rem, rem, divisor);
    }

  TMP_FREE;
}
Exemplo n.º 8
0
static Variant HHVM_FUNCTION(gmp_div_qr,
                             const Variant& dataA,
                             const Variant& dataB,
                             int64_t round = GMP_ROUND_ZERO) {
  mpz_t gmpDataA, gmpDataB, gmpReturnQ, gmpReturnR;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataA, dataA)) {
    return false;
  }
  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataB, dataB)) {
    mpz_clear(gmpDataA);
    return false;
  }

  if (mpz_sgn(gmpDataB) == 0) {
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);

    raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO,
                  cs_GMP_FUNC_NAME_GMP_DIV_QR);
    return false;
  }

  mpz_init(gmpReturnQ);
  mpz_init(gmpReturnR);

  switch (round)
  {
  case GMP_ROUND_ZERO:
    mpz_tdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_PLUSINF:
    mpz_cdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_MINUSINF:
    mpz_fdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB);
    break;

  default:
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);
    mpz_clear(gmpReturnQ);
    mpz_clear(gmpReturnR);
    return null_variant;
  }

  ArrayInit returnArray(2, ArrayInit::Map{});
  returnArray.set(0, NEWOBJ(GMPResource)(gmpReturnQ));
  returnArray.set(1, NEWOBJ(GMPResource)(gmpReturnR));

  mpz_clear(gmpDataA);
  mpz_clear(gmpDataB);
  mpz_clear(gmpReturnQ);
  mpz_clear(gmpReturnR);

  return returnArray.toVariant();
}
Exemplo n.º 9
0
void
fmpz_tdiv_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))
    {
        flint_printf("Exception: division by zero in fmpz_tdiv_qr\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 */

            fmpz_set_si(f, q);
            fmpz_set_si(s, r);
        }
        else                    /* h is large and g is small */
        {
            fmpz_set_ui(f, WORD(0)); /* g is zero */
            fmpz_set_si(s, c1);
        }
    }
    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 */
            {
                flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_tdiv_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 */
    }
}
Exemplo n.º 10
0
void C_BigInt::operator %= (const C_BigInt inDivisor) {
  mpz_t quotient ;
  mpz_init (quotient) ;
  mpz_t remainder ;
  mpz_init (remainder) ;
  mpz_tdiv_qr (quotient, remainder, mGMPint, inDivisor.mGMPint) ;
  mpz_swap (remainder, mGMPint) ;
  mpz_clear (quotient) ;
  mpz_clear (remainder) ;
}
Exemplo n.º 11
0
/*--------------------------------------------------------------------*/
static uint32 postprocess(msieve_obj *obj, mpz_t factor, 
			  mpz_t n, pm1_pp1_t *non_ecm_vals,
			  factor_list_t *factor_list) {

	/* handling for factors found. When complete, n
	   is changed to new input to be factored */

	uint32 i;
	mpz_t q, r;
	mp_t mp_factor;
	uint32 is_prime0, is_prime1;

	/* divide out all instances of factor from n */

	mpz_init(q);
	mpz_init(r);
	while (1) {
		mpz_tdiv_qr(q, r, n, factor);
		if (mpz_cmp_ui(q, (unsigned long)0) == 0 || 
		    mpz_cmp_ui(r, (unsigned long)0) != 0)
			break;

		mpz_set(n, q);
	}
	mpz_clear(q);
	mpz_clear(r);

	if (mpz_cmp_ui(n, (unsigned long)1) == 0) {
		mpz_set(n, factor);
	}
	else {
		/* in the worst case, n and factor are both composite.
     		   We would have to give up factoring one of them and
     		   continue on the other */

		is_prime0 = mpz_probab_prime_p(factor, 1);
		is_prime1 = mpz_probab_prime_p(n, 1);
		if ( (is_prime1 > 0 && is_prime0 == 0) ||
		     (is_prime1 == 0 && is_prime0 == 0 &&
				mpz_cmp(factor, n) > 0) ) {
			mpz_swap(factor, n);
		}

		/* switch the P+-1 stage 1 values to 
		   be modulo the new n */

		for (i = 0; i < NUM_NON_ECM; i++) {
			mpz_mod(non_ecm_vals[i].start_val,
				non_ecm_vals[i].start_val, n);
		}
	}

	gmp2mp(factor, &mp_factor);
	return factor_list_add(obj, factor_list, &mp_factor);
}
Exemplo n.º 12
0
Arquivo: t-tdiv.c Projeto: HRF92/mpir
void special_tests(void)
{
   mpz_t n, d, q, q2, r;
   
   mpz_init(n); mpz_init(d);
   mpz_init(q); mpz_init(q2); mpz_init(r);
   
   gmp_sscanf("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "%Zx", n);
   gmp_sscanf("20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "%Zx", d);

   mpz_tdiv_q(q, n, d);
   mpz_tdiv_qr(q2, r, n, d);
   
   if (mpz_cmp(q, q2) != 0)
   {
      fprintf (stderr, "ERROR\n");
      fprintf (stderr, "dividend = "); debug_mp (n, -16);
      fprintf (stderr, "divisor  = "); debug_mp (d, -16);
      fprintf (stderr, "q1 = "); debug_mp (q, -16);
      fprintf (stderr, "q2  = "); debug_mp (q2, -16);
      abort();
   }
   
   gmp_sscanf("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "%Zx", n);
   gmp_sscanf("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "%Zx", d);
   
   mpz_tdiv_q(q, n, d);
   mpz_tdiv_qr(q2, r, n, d);
   
   if (mpz_cmp(q, q2) != 0)
   {
      fprintf (stderr, "ERROR\n");
      fprintf (stderr, "dividend = "); debug_mp (n, -16);
      fprintf (stderr, "divisor  = "); debug_mp (d, -16);
      fprintf (stderr, "q1 = "); debug_mp (q, -16);
      fprintf (stderr, "q2  = "); debug_mp (q2, -16);
      abort();
   }
   
   mpz_clear(n); mpz_clear(d);
   mpz_clear(q); mpz_clear(q2); mpz_clear(r);
}
Exemplo n.º 13
0
void bn254_fp6_from_oct(Element x, const unsigned char *os, const size_t size)
{
    mpz_t quo, rem;

    if (size < 190) {
        fprintf(stderr, "error: please set up the enought buffer for element\n");
        exit(300);
    }

    mpz_init(quo);
    mpz_init(rem);

    mpz_import(quo, size, 1, sizeof(*os), 1, 0, os);

    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep0(rep0(x))), rem);
    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep0(rep1(x))), rem);
    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep0(rep2(x))), rem);
    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep1(rep0(x))), rem);
    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep1(rep1(x))), rem);
    mpz_tdiv_qr(quo, rem, quo, field(x)->base->base->order);
    mpz_set(rep(rep1(rep2(x))), rem);

    mpz_clear(quo);
    mpz_clear(rem);
}
Exemplo n.º 14
0
void
mpz_fdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
{
  mp_size_t dividend_size = dividend->_mp_size;
  mp_size_t divisor_size = divisor->_mp_size;
  mpz_t rem;
  TMP_DECL;

  TMP_MARK;

  MPZ_TMP_INIT (rem, ABS (divisor_size));

  mpz_tdiv_qr (quot, rem, dividend, divisor);

  if ((divisor_size ^ dividend_size) < 0 && rem->_mp_size != 0)
    mpz_sub_ui (quot, quot, 1L);

  TMP_FREE;
}
Exemplo n.º 15
0
void
mpz_cdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
{
  mp_size_t dividend_size = SIZ (dividend);
  mp_size_t divisor_size = SIZ (divisor);
  mpz_t rem;
  TMP_DECL;

  TMP_MARK;

  MPZ_TMP_INIT (rem, ABS (divisor_size));

  mpz_tdiv_qr (quot, rem, dividend, divisor);

  if ((divisor_size ^ dividend_size) >= 0 && SIZ (rem) != 0)
    mpz_add_ui (quot, quot, 1L);

  TMP_FREE;
}
Exemplo n.º 16
0
static obj bignum_modulo( obj a, obj b )
{
    mpz_t q, r, a1, b1;

    OBJ_TO_MPZ(a1, a);
    OBJ_TO_MPZ(b1, b);

    mpz_init(r);
    mpz_init(q);
    mpz_tdiv_qr(q, r, a1, b1);

    /* if sign of remainder is different from sign of divisor,
       adjust the remainder to fit modulo convention.
       but if remainder is 0, keep it (n.b., mpz_sgn(0) == 0)
    */

    if (mpz_sgn(r) != 0 && (mpz_sgn(b1) != mpz_sgn(r)))
    {
        mpz_set(q, r);
        mpz_add(r, q, b1);
    }
    return mpz_to_bignum(r);
}
Exemplo n.º 17
0
void __rat_approx_step(mpq_t res, mpz_t num, mpz_t den, mpz_t a,
		mpz_t pnm2, mpz_t pnm1, mpz_t qnm2, mpz_t qnm1, mpz_t pn, mpz_t qn)
{
	mpz_tdiv_qr(a,num,num,den);

	/* pn = an pn-1 + pn-2
	 * qn = an qn-1 + qn-2 */
	mpz_mul(pn,a,pnm1);
	mpz_add(pn,pn,pnm2);
	mpz_mul(qn,a,qnm1);
	mpz_add(qn,qn,qnm2);

	mpq_set_num(res,pn);
	mpq_set_den(res,qn);
	mpq_canonicalize(res);

	/* Advance: pn-1 -> pn-2, pn -> pn-1, and for q */
	mpz_set(pnm2,pnm1);
	mpz_set(qnm2,qnm1);
	mpz_set(pnm1,pn);
	mpz_set(qnm1,qn);

	mpz_swap(num,den);
}
Exemplo n.º 18
0
mp_bitcnt_t
mpz_remove (mpz_ptr dest, mpz_srcptr src, mpz_srcptr f)
{
  mpz_t fpow[40];		/* inexhaustible...until year 2020 or so */
  mpz_t x, rem;
  mp_bitcnt_t pwr;
  int p;

  if (mpz_cmp_ui (f, 1) <= 0)
    DIVIDE_BY_ZERO;

  if (SIZ (src) == 0)
    {
      if (src != dest)
        mpz_set (dest, src);
      return 0;
    }

  if (mpz_cmp_ui (f, 2) == 0)
    {
      unsigned long int s0;
      s0 = mpz_scan1 (src, 0);
      mpz_fdiv_q_2exp (dest, src, s0);
      return s0;
    }

  /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0).  It is an
     upper bound of the result we're seeking.  We could also shift down the
     operands so that they become odd, to make intermediate values smaller.  */

  mpz_init (rem);
  mpz_init (x);

  pwr = 0;
  mpz_init (fpow[0]);
  mpz_set (fpow[0], f);
  mpz_set (dest, src);

  /* Divide by f, f^2, ..., f^(2^k) until we get a remainder for f^(2^k).  */
  for (p = 0;; p++)
    {
      mpz_tdiv_qr (x, rem, dest, fpow[p]);
      if (SIZ (rem) != 0)
	break;
      mpz_init (fpow[p + 1]);
      mpz_mul (fpow[p + 1], fpow[p], fpow[p]);
      mpz_set (dest, x);
    }

  pwr = (1 << p) - 1;

  mpz_clear (fpow[p]);

  /* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give a
     zero remainder.  */
  while (--p >= 0)
    {
      mpz_tdiv_qr (x, rem, dest, fpow[p]);
      if (SIZ (rem) == 0)
	{
	  pwr += 1 << p;
	  mpz_set (dest, x);
	}
      mpz_clear (fpow[p]);
    }

  mpz_clear (x);
  mpz_clear (rem);
  return pwr;
}
Exemplo n.º 19
0
int
main (int argc, char **argv)
{
  mpz_t dividend, divisor;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size, divisor_size;
  int i;
  int reps = 1000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  TESTS_REPS (reps, argv, argc);

  rands = RANDS;

  mpz_init (bs);

  mpz_init (dividend);
  mpz_init (divisor);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 18 + 2; /* 0..524288 bit operands */

      do
	{
	  mpz_urandomb (bs, rands, size_range);
	  divisor_size = mpz_get_ui (bs);
	  mpz_rrandomb (divisor, rands, divisor_size);
	}
      while (mpz_sgn (divisor) == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs) + divisor_size;
      mpz_rrandomb (dividend, rands, dividend_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (dividend, dividend);
      if ((bsi & 2) != 0)
	mpz_neg (divisor, divisor);

      /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */

      mpz_tdiv_qr (quotient, remainder, dividend, divisor);
      mpz_tdiv_q (quotient2, dividend, divisor);
      mpz_tdiv_r (remainder2, dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
	dump_abort (dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort (dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
	dump_abort (dividend, divisor);

      /* Check if the remainder has the same sign as the dividend
	 (quotient rounded towards 0).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
	  dump_abort (dividend, divisor);

      mpz_mul (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort (dividend, divisor);

      mpz_abs (temp, divisor);
      mpz_abs (remainder, remainder);
      if (mpz_cmp (remainder, temp) >= 0)
	dump_abort (dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (divisor);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);

  tests_end ();
  exit (0);
}
Exemplo n.º 20
0
/**
 *  Extended Euclid's algorithm
 *  output the combination coefficients
 */
void cpt_ext_gcd(mpz_t res, mpz_t c1, mpz_t c2, mpz_srcptr a, mpz_srcptr b)
{
	mpz_t ax,bx,x,y,q,r,ay,by;
	mpz_init(q);
	mpz_init(r);
	mpz_init_set_si(bx,0);
	mpz_init_set_si(ay,0);
	if(mpz_cmp_si(a,0)>=0)
	{
		mpz_init_set(x,a);
		mpz_init_set_si(ax,1);
	}
	else
	{
		mpz_init(x);
		mpz_neg(x,a);
		mpz_init_set_si(ax,-1);
	}
	if(mpz_cmp_si(b,0)>=0)
	{
		mpz_init_set(y,b);
		mpz_init_set_si(by,1);
	}
	else
	{
		mpz_init(y);
		mpz_neg(y,b);
		mpz_init_set_si(by,-1);
	}
	if(mpz_cmp(x,y) > 0)
	{
		mpz_swap(x,y);
		mpz_swap(ax,ay);
		mpz_swap(bx,by);
	}
	while(mpz_cmp_si(x,0)>0)
	{
		mpz_t tmp1,tmp2;
		mpz_tdiv_qr(q,r,y,x);
		mpz_set(y,x);
		mpz_init_set(tmp1,ay);
		mpz_init_set(tmp2,by);
		mpz_set(ay,ax);
		mpz_set(by,bx);
		mpz_set(x,r);
		mpz_submul(tmp1,q,ax);
		mpz_submul(tmp2,q,bx);
		mpz_set(ax,tmp1);
		mpz_set(bx,tmp2);
		mpz_clear(tmp1);
		mpz_clear(tmp2);
	}
	mpz_set(res,y);
	mpz_set(c1,ay);
	mpz_set(c2,by);
	mpz_clear(ax);
	mpz_clear(bx);
	mpz_clear(ay);
	mpz_clear(by);
	mpz_clear(x);
	mpz_clear(y);
	mpz_clear(q);
	mpz_clear(r);
}
Exemplo n.º 21
0
void
hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
		char **ap, char **bp, char **cp, char **dp)
{
  mpz_t a, b, c, d;
  unsigned long abits, bbits;
  unsigned signs;

  mpz_init (a);
  mpz_init (b);
  mpz_init (c);
  mpz_init (d);

  if (op == OP_POWM)
    {
      unsigned long cbits;
      abits = gmp_urandomb_ui (state, 32) % maxbits;
      bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
      cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits;

      mpz_rrandomb (a, state, abits);
      mpz_rrandomb (b, state, bbits);
      mpz_rrandomb (c, state, cbits);

      signs = gmp_urandomb_ui (state, 3);
      if (signs & 1)
	mpz_neg (a, a);
      if (signs & 2)
	{
	  mpz_t g;

	  /* If we negate the exponent, must make sure that gcd(a, c) = 1 */
	  if (mpz_sgn (a) == 0)
	    mpz_set_ui (a, 1);
	  else
	    {
	      mpz_init (g);

	      for (;;)
		{
		  mpz_gcd (g, a, c);
		  if (mpz_cmp_ui (g, 1) == 0)
		    break;
		  mpz_divexact (a, a, g);
		}
	      mpz_clear (g);
	    }
	  mpz_neg (b, b);
	}
      if (signs & 4)
	mpz_neg (c, c);

      mpz_powm (d, a, b, c);
    }
  else
    {
      unsigned long qbits;
      bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
      qbits = gmp_urandomb_ui (state, 32) % maxbits;
      abits = bbits + qbits;
      if (abits > 30)
	abits -= 30;
      else
	abits = 0;

      mpz_rrandomb (a, state, abits);
      mpz_rrandomb (b, state, bbits);

      signs = gmp_urandomb_ui (state, 2);
      if (signs & 1)
	mpz_neg (a, a);
      if (signs & 2)
	mpz_neg (b, b);

      switch (op)
	{
	default:
	  abort ();
	case OP_CDIV:
	  mpz_cdiv_qr (c, d, a, b);
	  break;
	case OP_FDIV:
	  mpz_fdiv_qr (c, d, a, b);
	  break;
	case OP_TDIV:
	  mpz_tdiv_qr (c, d, a, b);
	  break;
	}
    }
  gmp_asprintf (ap, "%Zx", a);
  gmp_asprintf (bp, "%Zx", b);
  gmp_asprintf (cp, "%Zx", c);
  gmp_asprintf (dp, "%Zx", d);

  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (c);
  mpz_clear (d);
}
Exemplo n.º 22
0
value largeint_tdivmod(value quotdest, value remdest, value li1, value li2)
{ 
  mpz_tdiv_qr(Large_val(quotdest), Large_val(remdest), 
	      Large_val(li1), Large_val(li2)); 
  return Val_unit;
}
Exemplo n.º 23
0
static int pass2(cn_t cn, const char *str){
  mpz_t comp;
  int ret = CN_OK;

  str = strchr(str+5, '(');
  str++;

  mpz_init(comp);
  cn_eval(comp, cn->n, cn->x);

  if(str[0] == '1' && str[1] == ')'){
    memcpy(cn->factor[0], comp, sizeof(mpz_t));
    cn->nfactors = 1;
  }else{
    int fix = 0;
    mpz_t tmpq, tmpr;
    mpz_init(tmpq);
    mpz_init(tmpr);
    do{
      mpz_t factor;
      int i = 0;
      while(*str >= '0' && *str <= '9'){
        buf[i++] = *str++;
      }
      buf[i] = '\0';
      mpz_init_set_str(factor, buf, 10);
      mpz_tdiv_qr(tmpq, tmpr, comp, factor);
      if(mpz_sgn(tmpr)){
        if(ret == CN_OK){
          ret = CN_DIV_ERROR(fix);
        }
      }else{
        mpz_set(comp, tmpq);
        if(!ISPRIME(factor)){
          if(ret == CN_OK){
            ret = CN_PRIMARITY_ERROR(fix);
          }
        }
        if(fix > 0 && mpz_cmp(cn->factor[fix-1], factor) > 0){
          if(ret == CN_OK){
            ret = CN_ORDER_ERROR(fix);
          }
        }
        memcpy(cn->factor[fix++], factor, sizeof(mpz_t));
      }
    }while(*str++ == ' ');
    mpz_clear(tmpq);
    mpz_clear(tmpr);
    memcpy(cn->factor[fix++], comp, sizeof(mpz_t));
    cn->nfactors = fix;
  }
  {
    char realflag;
    int realdigit;
    realflag = ISPRIME(comp) ? 'P' : 'C';
    if(cn->flag != realflag){
      ret |= CN_LF_PRIMARITY_ERROR;
    }
    if(cn->nfactors > 1 && realflag == 'P'
    && mpz_cmp(cn->factor[cn->nfactors-2], comp) > 0){
      ret |= CN_LF_ORDER_ERROR;
    }
    realdigit = strlen(mpz_get_str(buf, 10, comp));
    if(cn->lf_digit != realdigit){
      ret |= CN_LF_DIGIT_ERROR(realdigit);
    }
  }
  return ret;
}
Exemplo n.º 24
0
static int
mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q,
           mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
{
  mpfr_exp_t ex, ey;
  int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
  mpz_t mx, my, r;
  int tiny = 0;

  MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
          || MPFR_IS_ZERO (y))
        {
          /* for remquo, quo is undefined */
          MPFR_SET_NAN (rem);
          MPFR_RET_NAN;
        }
      else                      /* either y is Inf and x is 0 or non-special,
                                   or x is 0 and y is non-special,
                                   in both cases the quotient is zero. */
        {
          if (quo)
            *quo = 0;
          return mpfr_set (rem, x, rnd);
        }
    }

  /* now neither x nor y is NaN, Inf or zero */

  mpz_init (mx);
  mpz_init (my);
  mpz_init (r);

  ex = mpfr_get_z_2exp (mx, x);  /* x = mx*2^ex */
  ey = mpfr_get_z_2exp (my, y);  /* y = my*2^ey */

  /* to get rid of sign problems, we compute it separately:
     quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
     quo(-x,y) = -quo(x,y), rem(-x,y)  = -rem(x,y)
     thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
  sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
  mpz_abs (mx, mx);
  mpz_abs (my, my);
  q_is_odd = 0;

  /* divide my by 2^k if possible to make operations mod my easier */
  {
    unsigned long k = mpz_scan1 (my, 0);
    ey += k;
    mpz_fdiv_q_2exp (my, my, k);
  }

  if (ex <= ey)
    {
      /* q = x/y = mx/(my*2^(ey-ex)) */

      /* First detect cases where q=0, to avoid creating a huge number
         my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy =
         mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and
         y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1
         the quotient is 0 */
      if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) <
          ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
        {
          tiny = 1;
          mpz_set (r, mx);
          mpz_set_ui (mx, 0);
        }
      else
        {
          mpz_mul_2exp (my, my, ey - ex);   /* divide mx by my*2^(ey-ex) */

          /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */
          mpz_tdiv_qr (mx, r, mx, my);
          /* 0 <= |r| <= |my|, r has the same sign as mx */
        }

      if (rnd_q == MPFR_RNDN)
        q_is_odd = mpz_tstbit (mx, 0);
      if (quo)                  /* mx is the quotient */
        {
          mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
          *quo = mpz_get_si (mx);
        }
    }
  else                          /* ex > ey */
    {
      if (quo) /* remquo case */
        /* for remquo, to get the low WANTED_BITS more bits of the quotient,
           we first compute R =  X mod Y*2^WANTED_BITS, where X and Y are
           defined below. Then the low WANTED_BITS of the quotient are
           floor(R/Y). */
        mpz_mul_2exp (my, my, WANTED_BITS);     /* 2^WANTED_BITS*Y */

      else if (rnd_q == MPFR_RNDN) /* remainder case */
        /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
           Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
           To be able to perform the rounding, we need the least significant
           bit of the quotient, i.e., one more bit in the remainder,
           which is obtained by dividing by 2Y. */
        mpz_mul_2exp (my, my, 1);       /* 2Y */

      mpz_set_ui (r, 2);
      mpz_powm_ui (r, r, ex - ey, my);  /* 2^(ex-ey) mod my */
      mpz_mul (r, r, mx);
      mpz_mod (r, r, my);

      if (quo)                  /* now 0 <= r < 2^WANTED_BITS*Y */
        {
          mpz_fdiv_q_2exp (my, my, WANTED_BITS);   /* back to Y */
          mpz_tdiv_qr (mx, r, r, my);
          /* oldr = mx*my + newr */
          *quo = mpz_get_si (mx);
          q_is_odd = *quo & 1;
        }
      else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */
        {
          mpz_fdiv_q_2exp (my, my, 1);     /* back to Y */
          /* least significant bit of q */
          q_is_odd = mpz_cmpabs (r, my) >= 0;
          if (q_is_odd)
            mpz_sub (r, r, my);
        }
      /* now 0 <= |r| < |my|, and if needed,
         q_is_odd is the least significant bit of q */
    }

  if (mpz_cmp_ui (r, 0) == 0)
    {
      inex = mpfr_set_ui (rem, 0, MPFR_RNDN);
      /* take into account sign of x */
      if (signx < 0)
        mpfr_neg (rem, rem, MPFR_RNDN);
    }
  else
    {
      if (rnd_q == MPFR_RNDN)
        {
          /* FIXME: the comparison 2*r < my could be done more efficiently
             at the mpn level */
          mpz_mul_2exp (r, r, 1);
          /* if tiny=1, we should compare r with my*2^(ey-ex) */
          if (tiny)
            {
              if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) <
                  ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
                compare = 0; /* r*2^ex < my*2^ey */
              else
                {
                  mpz_mul_2exp (my, my, ey - ex);
                  compare = mpz_cmpabs (r, my);
                }
            }
          else
            compare = mpz_cmpabs (r, my);
          mpz_fdiv_q_2exp (r, r, 1);
          compare = ((compare > 0) ||
                     ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
          /* if compare != 0, we need to subtract my to r, and add 1 to quo */
          if (compare)
            {
              mpz_sub (r, r, my);
              if (quo && (rnd_q == MPFR_RNDN))
                *quo += 1;
            }
        }
      /* take into account sign of x */
      if (signx < 0)
        mpz_neg (r, r);
      inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd);
    }

  if (quo)
    *quo *= sign;

  mpz_clear (mx);
  mpz_clear (my);
  mpz_clear (r);

  return inex;
}
Exemplo n.º 25
0
/* can't be bothered doing the english version ...
 * we often just use the american version anyway. */
static size_t words_conv(Vstr_base *s1, size_t pos, const mpz_t num,
                         int cap, int del)
{
  size_t orig_pos = pos;
  struct Words_conv
  {
   const char *num;
   const char *str;
   const size_t len;
   mpz_t bignum;
  };
  static struct Words_conv conv_m[] =
    {
#if 0
     WORDS_MAKE("1" VAL0_300() VAL0_3(),           "centillion"),
     WORDS_MAKE("1" VAL0_60() VAL0_3(),            "vigintillion"),
     WORDS_MAKE("1" VAL0_60(),                     "novemdecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_12(), "octodecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_9(),  "septendecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_6(),  "sexdecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_3(),  "quindecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15(),           "quattuordecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_12(),           "tredecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_9(),            "duodecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_6(),            "undecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_3(),            "decillion"),
     WORDS_MAKE("1" VAL0_30(),                     "nonillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_12(),           "octillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_9(),            "septillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_6(),            "sextillion"),
#endif
     WORDS_MAKE("1" VAL0_15() VAL0_3(),            "quintillion"),
     WORDS_MAKE("1" VAL0_15(),                     "quadrillion"),
     WORDS_MAKE("1" VAL0_12(),                     "trillion"),
     WORDS_MAKE("1" VAL0_9(),                      "billion"),
     WORDS_MAKE("1" VAL0_6(),                      "million"),
     WORDS_MAKE("1" VAL0_3(),                      "thousand"),
     WORDS_MAKE("100",                             "hundred"),
    };
  static struct Words_conv conv_and =
     WORDS_MAKE("&",                               "and");
  static struct Words_conv conv_a[] =
    {
     WORDS_MAKE("90",                              "ninety"),
     WORDS_MAKE("80",                              "eighty"),
     WORDS_MAKE("70",                              "seventy"),
     WORDS_MAKE("60",                              "sixty"),
     WORDS_MAKE("50",                              "fifty"),
     WORDS_MAKE("40",                              "forty"),
     WORDS_MAKE("30",                              "thirty"),
     WORDS_MAKE("20",                              "twenty"),
     WORDS_MAKE("19",                              "nineteen"),
     WORDS_MAKE("18",                              "eighteen"),
     WORDS_MAKE("17",                              "seventeen"),
     WORDS_MAKE("16",                              "sixteen"),
     WORDS_MAKE("15",                              "fifteen"),
     WORDS_MAKE("14",                              "fourteen"),
     WORDS_MAKE("13",                              "thirteen"),
     WORDS_MAKE("12",                              "twelve"),
     WORDS_MAKE("11",                              "eleven"),
     WORDS_MAKE("10",                              "ten"),
     WORDS_MAKE("9",                               "nine"),
     WORDS_MAKE("8",                               "eight"),
     WORDS_MAKE("7",                               "seven"),
     WORDS_MAKE("6",                               "six"),
     WORDS_MAKE("5",                               "five"),
     WORDS_MAKE("4",                               "four"),
     WORDS_MAKE("3",                               "three"),
     WORDS_MAKE("2",                               "two"),
     WORDS_MAKE("1",                               "one"),
    };
  static struct Words_conv conv_zero =
     WORDS_MAKE("0",                               "zero");
  static struct Words_conv conv_minus =
     WORDS_MAKE("-",                               "minus");  
  static int done = FALSE;
  struct Words_conv *scan = conv_m;
  unsigned int alen = sizeof(conv_m) / sizeof(conv_m[0]);
  size_t ret = 0;
  mpz_t tmp;

  if (!done)
  {
    while (alen)
    {
      mpz_init_set_str(scan->bignum, scan->num, 10);
      
      --alen;
      ++scan;
    }
    scan = conv_a;
    alen = sizeof(conv_a) / sizeof(conv_a[0]);
    while (alen)
    {
      mpz_init_set_str(scan->bignum, scan->num, 10);
      
      --alen;
      ++scan;
    }
    
    scan = conv_m;
    alen = sizeof(conv_m) / sizeof(conv_m[0]);
    
    done = TRUE;
  }
  
  mpz_init_set(tmp, num);
  mpz_abs(tmp, tmp);

  if (mpz_cmp_ui(num, 0) == 0)
  {
    scan = &conv_zero;
    WORDS_ADD_WORD();
  }
  else
  {
    while (alen)
    {
      mpz_t quo;

      mpz_init(quo);
      
      while (mpz_cmp(tmp, scan->bignum) >= 0)
      {
        size_t front = 0;
        
        mpz_tdiv_qr(quo, tmp, tmp, scan->bignum);

        if (!(front = words_conv(s1, pos, quo, FALSE, FALSE)))
          return (0);
        ret += front;
        pos += front;

        WORDS_ADD_WORD();
      }
      
      --alen;
      ++scan;
    }

    if (ret && (mpz_cmp_ui(tmp, 0) != 0))
    {
      scan = &conv_and;
      WORDS_ADD_WORD();
    }

    scan = conv_a;
    alen = sizeof(conv_a) / sizeof(conv_a[0]);
    while (alen)
    {
      while (mpz_cmp(tmp, scan->bignum) >= 0)
      {
        mpz_mod(tmp, tmp, scan->bignum);
        WORDS_ADD_WORD();
      }
      
      --alen;
      ++scan;
    }
  }
  
  ASSERT(ret >= 2);
  
  if (mpz_sgn(num) == -1)
  {
    scan = &conv_minus;
    pos  = orig_pos;
    WORDS_ADD_WORD();
  }
  
  ASSERT(ret >= 2);

  ++orig_pos;
  if (del)
  { /* get rid of space */
    if (s1) vstr_del(s1, orig_pos, 1);
    --ret;
  }
  
  if (cap && s1 && !vstr_conv_uppercase(s1, orig_pos, 1)) /* capitalize */
    return (0);
  
  return (ret);
}
Exemplo n.º 26
0
int applyExtendedEuclid(mpz_t e, mpz_t phi, mpz_t d)
{
	
	mpz_t x, y, z, a, b, c,  div, temp, mul, tx, ty, tz;
	
	if(mpz_even_p(e))	
		return 0;
	
	mpz_init(x);
	mpz_init(y);
	mpz_init(z);
	mpz_init(a);
	mpz_init(b);
	mpz_init(c);
	mpz_init(mul);
	mpz_init(tx);
	mpz_init(ty);
	mpz_init(tz);
	
	mpz_init(div);
	mpz_init(temp);
	
	mpz_init_set_si(a, 1);
	mpz_init_set_si(b, 0);
	mpz_init_set(c, phi);
	mpz_init_set_si(x, 0);
	mpz_init_set_si(y, 1);
	mpz_init_set(z, e);

	do
	{
		mpz_init_set(tx, x);
		mpz_init_set(ty, y);
		mpz_init_set(tz, z);
		#if DEBUG
			printf("\n\n");
			mpz_out_str(NULL, 10, a);
			printf("\n");
			mpz_out_str(NULL, 10, b);
			printf("\n");
			mpz_out_str(NULL, 10, c);
			printf("\n\n");
			mpz_out_str(NULL, 10, x);
			printf("\n");	
			mpz_out_str(NULL, 10, y);
			printf("\n");
			mpz_out_str(NULL, 10, z);
			printf("\n\n");
		#endif
		mpz_tdiv_qr(div, z, c, z);
		mpz_mul(mul, x, div);
		mpz_sub(x, a, mul);
		mpz_mul(mul, y, div);
		mpz_sub(y, b, mul);
		mpz_init_set(a, tx);
		mpz_init_set(b, ty);
		mpz_init_set(c, tz);
		
		
		#if DEBUG
			mpz_out_str(NULL, 10, div);
			printf("\n");
			
			mpz_out_str(NULL, 10, mul);
			printf("\n Sub:");
			
			mpz_out_str(NULL, 10, x);
			printf("\n");
			
			mpz_out_str(NULL, 10, mul);
			printf("\n");
			
			mpz_out_str(NULL, 10, y);
			printf("\n");
			
			mpz_out_str(NULL, 10, a);
			printf("\n");
			mpz_out_str(NULL, 10, b);
			printf("\n");
			mpz_out_str(NULL, 10, c);
			printf("\n\n");
		#endif
	}while(mpz_cmp_si(z, 0L)!=0);	
	
	//LCM not 1
	if(mpz_cmp_si(tz, 1L)!=0)
	{
		return 0;
	}
	else
	{
		mpz_init_set(d, ty);
		return 1;
	}
}