示例#1
0
/* r = sqrt(x) */
void
my_sqrt_ui(mpf_t r, unsigned long x)
{
  unsigned long prec, bits, prec0;

  prec0 = mpf_get_prec(r);

  if (prec0<=DOUBLE_PREC) {
    mpf_set_d(r, sqrt(x));
    return;
  }

  bits = 0;
  for (prec=prec0; prec>DOUBLE_PREC;)
    {
      int bit = prec&1;
      prec = (prec+bit)/2;
      bits = bits*2+bit;
    }

  mpf_set_prec_raw(t1, DOUBLE_PREC);
  mpf_set_d(t1, 1/sqrt(x));

  while (prec<prec0)
    {
      prec *=2;
      if (prec<prec0)
	{
	  /* t1 = t1+t1*(1-x*t1*t1)/2; */
	  mpf_set_prec_raw(t2, prec);
	  mpf_mul(t2, t1, t1);         /* half x half -> full */
	  mpf_mul_ui(t2, t2, x);
	  mpf_ui_sub(t2, 1, t2);
	  mpf_set_prec_raw(t2, prec/2);
	  mpf_div_2exp(t2, t2, 1);
	  mpf_mul(t2, t2, t1);         /* half x half -> half */
	  mpf_set_prec_raw(t1, prec);
	  mpf_add(t1, t1, t2);
	}
      else
	{
	  break;
	}
      prec -= (bits&1);
      bits /=2;
    }
  /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */
  mpf_set_prec_raw(t2, prec0/2);
  mpf_mul_ui(t2, t1, x);
  mpf_mul(r, t2, t2);          /* half x half -> full */
  mpf_ui_sub(r, x, r);
  mpf_mul(t1, t1, r);          /* half x half -> half */
  mpf_div_2exp(t1, t1, 1);
  mpf_add(r, t1, t2);
}
示例#2
0
文件: my.c 项目: macroxue/const-pi
void my_out_str_raw(FILE *fp, unsigned long digits, mpf_t f, unsigned long offset)
{
    unsigned long d;

    if (digits <= LINE_SIZE*NUM_BLOCKS) {
        unsigned long cursor = offset % LINE_SIZE;
        for (d = 0; d < digits; ) {
            mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
            mpf_mul_ui(f, f, UNIT_MOD);
            unsigned long i = mpf_get_ui(f);
            mpf_sub_ui(f, f, i);

            utoa(i, UNIT_SIZE);
            *out_ptr++ = ' ';
            d += UNIT_SIZE;
            cursor += UNIT_SIZE;
            if (cursor == LINE_SIZE) {
                cursor = 0;
                *out_ptr++ = ':';
                *out_ptr++ = ' ';
                utoa(offset + d, 0);
                *out_ptr++ = '\n';
                if ((offset + d) % (LINE_SIZE*10) == 0)
                    flush_out(fp);
            }
        }
    } else {
        mpf_t block, mod;
        unsigned long num_units = (digits + UNIT_SIZE-1)/UNIT_SIZE;
        unsigned long block_size =  (num_units + NUM_BLOCKS-1)/NUM_BLOCKS*UNIT_SIZE;
        mpf_set_default_prec((int)(block_size*BITS_PER_DIGIT+1));
        mpf_init(block);
        mpf_init_set_ui(mod, 10);
        mpf_pow_ui(mod, mod, block_size);

        for (d = 0; d < digits; d += block_size) {
            unsigned long size = block_size < digits - d ? block_size : digits - d;
            mpf_set_prec_raw(block, (int)(size*BITS_PER_DIGIT+1));
            mpf_set(block, f);
            my_out_str_raw(fp, size, block, offset+d);
            if (block_size < digits - d) {
                mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
                mpf_mul(f, f, mod);
                mpf_floor(trunk, f);
                mpf_sub(f, f, trunk);
            }
        }
        mpf_clear(block);
        mpf_clear(mod);
    }
}
// r = y/x   WARNING: r cannot be the same as y.
void
my_div(mpf_t r, mpf_t y, mpf_t x)
{
  unsigned long prec, bits, prec0;

  prec0 = mpf_get_prec(r);

  if (prec0<=DOUBLE_PREC) {
    mpf_set_d(r, mpf_get_d(y)/mpf_get_d(x));
    return;
  }

  bits = 0;
  for (prec=prec0; prec>DOUBLE_PREC;) {
    int bit = prec&1;
    prec = (prec+bit)/2;
    bits = bits*2+bit;
  }

  mpf_set_prec_raw(t1, DOUBLE_PREC);
  mpf_ui_div(t1, 1, x);

  while (prec<prec0) {
    prec *=2;
    if (prec<prec0) {
      /* t1 = t1+t1*(1-x*t1); */
      mpf_set_prec_raw(t2, prec);
      mpf_mul(t2, x, t1);          // full x half -> full
      mpf_ui_sub(t2, 1, t2);
      mpf_set_prec_raw(t2, prec/2);
      mpf_mul(t2, t2, t1);         // half x half -> half
      mpf_set_prec_raw(t1, prec);
      mpf_add(t1, t1, t2);
    } else {
      prec = prec0;
      /* t2=y*t1, t1 = t2+t1*(y-x*t2); */
      mpf_set_prec_raw(t2, prec/2);
      mpf_mul(t2, t1, y);          // half x half -> half
      mpf_mul(r, x, t2);           // full x half -> full
      mpf_sub(r, y, r);
      mpf_mul(t1, t1, r);          // half x half -> half
      mpf_add(r, t1, t2);
      break;
    }
    prec -= (bits&1);
    bits /=2;
  }
}
示例#4
0
文件: t-set.c 项目: BrianGladman/mpir
void
check_reuse (void)
{
  /* Try mpf_set(f,f) when f is bigger than prec.  In the past this had
     resulted in an MPN_COPY with invalid operand overlap. */
  mpf_t  f;
  mp_size_t      limbs = 20;
  unsigned long  bits = limbs * GMP_NUMB_BITS;
  mpf_init2 (f, bits);
  refmpf_fill (f, limbs, GMP_NUMB_MAX);
  mpf_set_prec_raw (f, bits / 2);
  mpf_set (f, f);
  MPF_CHECK_FORMAT (f);
  mpf_set_prec_raw (f, bits);
  mpf_clear (f);
}
示例#5
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_t  rands;
  mpf_t              got, u;
  unsigned long      prec, v;
  int                i;

  /* The nails code in mpf_mul_ui currently isn't exact, so suppress these
     tests for now.  */
  if (BITS_PER_UI > GMP_NUMB_BITS)
    return;

  mpf_init (got);
  mpf_init (u);
  gmp_randinit_default(rands);

  for (i = 0; i < 200; i++)
    {
      /* got precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (got, prec);

      /* u precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (u, prec);

      /* u, possibly negative */
      mpf_rrandomb (u, rands, PREC(u), (mp_exp_t) 20);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (u, u);

      /* v, 0 to BITS_PER_ULONG bits (inclusive) */
      prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
      v = gmp_urandomb_ui (rands, prec);

      if ((i % 2) == 0)
        {
          /* separate */
          mpf_mul_ui (got, u, v);
          check_one ("separate", got, u, v);
        }
      else
        {
          /* overlap */
          prec = refmpf_set_overlap (got, u);
          mpf_mul_ui (got, got, v);
          check_one ("overlap src==dst", got, u, v);

          mpf_set_prec_raw (got, prec);
        }
    }

  mpf_clear (got);
  mpf_clear (u);
  gmp_randclear(rands);
}
示例#6
0
文件: my.c 项目: macroxue/const-pi
// r = sqrt(x)
void my_sqrt(mpf_t r, mpf_t x)
{
    unsigned prec, bits, prec0;

    prec0 = mpf_get_prec(r);

    if (prec0 <= DOUBLE_PREC) {
        mpf_set_d(r, sqrt(mpf_get_d(x)));
        return;
    }

    bits = 0;
    for (prec = prec0; prec > DOUBLE_PREC;) {
        int bit = prec & 1;
        prec = (prec + bit) / 2;
        bits = bits * 2 + bit;
    }

    mpf_set_prec_raw(t1, DOUBLE_PREC);
    mpf_set_d(t1, 1 / sqrt(mpf_get_d(x)));

    while (prec < prec0) {
        prec *= 2;
        /*printf("prec=%d, prec0=%d\n", prec, prec0); */
        if (prec < prec0) {
            /* t1 = t1+t1*(1-x*t1*t1)/2; */
            mpf_set_prec_raw(t2, prec);
            mpf_mul(t2, t1, t1);
            mpf_set_prec_raw(x, prec/2);
            mpf_mul(t2, t2, x);
            mpf_ui_sub(t2, 1, t2);
            mpf_set_prec_raw(t2, prec/2);
            mpf_div_2exp(t2, t2, 1);
            mpf_mul(t2, t2, t1);
            mpf_set_prec_raw(t1, prec);
            mpf_add(t1, t1, t2);
        } else {
            prec = prec0;
            /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */
            mpf_set_prec_raw(t2, prec/2);
            mpf_set_prec_raw(x, prec/2);
            mpf_mul(t2, t1, x);
            mpf_mul(r, t2, t2);
            mpf_set_prec_raw(x, prec);
            mpf_sub(r, x, r);
            mpf_mul(t1, t1, r);
            mpf_div_2exp(t1, t1, 1);
            mpf_add(r, t1, t2);
            break;
        }
        prec -= (bits & 1);
        bits /= 2;
    }
}
示例#7
0
文件: my.c 项目: macroxue/const-pi
void my_divexact(mpz_t r, mpz_t y, mpz_t x)
{
    unsigned long prec = mpz_sizeinbase(y, 2);
    unsigned long prec2 = mpz_sizeinbase(x, 2);
    if (prec >= div_threshold) {
        mpf_set_prec_raw(d1, prec);
        mpf_set_prec_raw(d2, prec);
        mpf_set_z(d1, y);
        mpf_set_z(d2, x);
        mpf_div_2exp(d1, d1, prec);
        mpf_div_2exp(d2, d2, prec2);
        my_div(d2, d1, d2);
        mpf_mul_2exp(d2, d2, prec-prec2);
        mpf_set_d(d1, 0.5);
        mpf_add(d2, d2, d1);
        mpz_set_f(y, d2);
    } else {
        mpz_divexact(y, y, x);
        //mpz_tdiv_q(y, y, x);
    }
}
示例#8
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long  prec;
  mpf_t  got, u, v;
  int    i;

  mpf_init (got);
  mpf_init (u);
  mpf_init (v);

  /* separate */
  for (i = 0; i < 100; i++)
    {
      /* got precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (got, prec);

      /* u */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (u, prec);
      do {
        mpf_random2 (u, PREC(u), (mp_exp_t) 20);
      } while (SIZ(u) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (u, u);

      /* v */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (v, prec);
      do {
        mpf_random2 (v, PREC(v), (mp_exp_t) 20);
      } while (SIZ(v) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (v, v);

      switch (i % 3) {
      case 0:
        mpf_div (got, u, v);
        check_one ("separate", got, u, v);
        break;
      case 1:
        prec = refmpf_set_overlap (got, u);
        mpf_div (got, got, v);
        check_one ("dst == u", got, u, v);
        mpf_set_prec_raw (got, prec);
        break;
      case 2:
        prec = refmpf_set_overlap (got, v);
        mpf_div (got, u, got);
        check_one ("dst == v", got, u, v);
        mpf_set_prec_raw (got, prec);
        break;
      }
    }

  mpf_clear (got);
  mpf_clear (u);
  mpf_clear (v);
}