Beispiel #1
0
void
mpf_set_prec (mpf_ptr x, mp_bitcnt_t new_prec_in_bits)
{
  mp_size_t  old_prec, new_prec, new_prec_plus1;
  mp_size_t  size, sign;
  mp_ptr     xp;

  new_prec = __GMPF_BITS_TO_PREC (new_prec_in_bits);
  old_prec = PREC(x);

  /* do nothing if already the right precision */
  if (new_prec == old_prec)
    return;

  PREC(x) = new_prec;
  new_prec_plus1 = new_prec + 1;

  /* retain most significant limbs */
  sign = SIZ(x);
  size = ABS (sign);
  xp = PTR(x);
  if (size > new_prec_plus1)
    {
      SIZ(x) = (sign >= 0 ? new_prec_plus1 : -new_prec_plus1);
      MPN_COPY_INCR (xp, xp + size - new_prec_plus1, new_prec_plus1);
    }

  PTR(x) = __GMP_REALLOCATE_FUNC_LIMBS (xp, old_prec+1, new_prec_plus1);
}
Beispiel #2
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);
}
Beispiel #3
0
void
mpf_init2 (mpf_ptr r, mp_bitcnt_t prec_in_bits)
{
  mp_size_t prec;

  prec = __GMPF_BITS_TO_PREC (prec_in_bits);
  r->_mp_size = 0;
  r->_mp_exp = 0;
  r->_mp_prec = prec;
  r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
}
Beispiel #4
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_t  rands;
  unsigned long  prec;
  mpf_t  got;
  mpq_t  q;
  int    i;

  mpf_init (got);
  mpq_init (q);
  gmp_randinit_default(rands);

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

      /* num */
      prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
      mpz_rrandomb (mpq_numref(q), rands, prec);

      /* possibly negative num */
      if (gmp_urandomb_ui (rands, 1L))
        mpz_neg (mpq_numref(q), mpq_numref(q));

      /* den, non-zero */
      do {
        prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
        mpz_rrandomb (mpq_denref(q), rands, prec);
      } while (mpz_sgn (mpq_denref(q)) <= 0);

      check_one (got, q);
    }

  mpf_clear (got);
  mpq_clear (q);
  gmp_randclear(rands);
}
Beispiel #5
0
/* Exercise calls mpf(x,x,x) */
void
check_reuse_three (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long  result_prec, input_prec, set_prec;
  mpf_t  got;
  int    i;

  mpf_init (got);

  for (i = 0; i < 8; i++)
    {
      result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
      input_prec = min_prec + gmp_urandomm_ui (rands, 15L);

      set_prec = MAX (result_prec, input_prec);
      refmpf_set_prec_limbs (got, set_prec);

      /* input, non-zero, possibly negative */
      PREC(got) = input_prec;
      do {
        mpf_random2 (got, input_prec, (mp_exp_t) 20);
      } while (SIZ(got) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (got, got);

      PREC(got) = result_prec;

      mpf_div (got, got, got);

      /* expect exactly 1.0 always */
      ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);

      PREC(got) = set_prec;
    }

  mpf_clear (got);
}
Beispiel #6
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);
}
Beispiel #7
0
void
check_rand (void)
{
  unsigned long      max_prec = 15;
  unsigned long      min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long      x, prec;
  mpf_t              r, s;
  int                i;

  mpf_init (r);
  mpf_init (s);
  refmpf_set_prec_limbs (s, 2*max_prec+10);

  for (i = 0; i < 50; i++)
    {
      /* input, a random non-zero ulong, exponentially distributed */
      do {
        x = gmp_urandomb_ui (rands,
                             gmp_urandomm_ui (rands, BITS_PER_ULONG) + 1);
      } while (x == 0);

      /* result precision */
      prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (r, prec);

      mpf_sqrt_ui (r, x);
      MPF_CHECK_FORMAT (r);

      /* Expect to prec limbs of result.
         In the current implementation there's no stripping of low zero
         limbs in mpf_sqrt_ui, not even on perfect squares, so size should
         be exactly prec.  */
      if (SIZ(r) != prec)
        {
          printf ("mpf_sqrt_ui result not enough result limbs\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r", r);
          printf    ("  r size %ld\n", (long) SIZ(r));
          printf    ("  r prec %ld\n", (long) PREC(r));
          abort ();
        }

      /* Must have r^2 <= x, since r has been truncated. */
      mpf_mul (s, r, r);
      if (! (mpf_cmp_ui (s, x) <= 0))
        {
          printf    ("mpf_sqrt_ui result too big\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r", r);
          mpf_trace ("  s", s);
          abort ();
        }

      /* Must have (r+ulp)^2 > x.
         No overflow from refmpf_add_ulp since r is only prec limbs. */
      refmpf_add_ulp (r);
      mpf_mul (s, r, r);
      if (! (mpf_cmp_ui (s, x) > 0))
        {
          printf    ("mpf_sqrt_ui result too small\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r+ulp", r);
          mpf_trace ("  s", s);
          abort ();
        }
    }

  mpf_clear (r);
  mpf_clear (s);
}
Beispiel #8
0
void
mpf_set_prec_raw (mpf_ptr x, mp_bitcnt_t prec_in_bits)
{
  x->_mp_prec = __GMPF_BITS_TO_PREC (prec_in_bits);
}
Beispiel #9
0
void
check_rand2 (void)
{
  unsigned long      max_prec = 20;
  unsigned long      min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long      x_prec, r_prec;
  mpf_t              x, r, s;
  int                i;

  mpf_init (x);
  mpf_init (r);
  mpf_init (s);
  refmpf_set_prec_limbs (s, 2*max_prec+10);

  for (i = 0; i < 500; i++)
    {
      /* input precision */
      x_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (x, x_prec);

      /* result precision */
      r_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (r, r_prec);

      mpf_random2 (x, x_prec, 1000);

      mpf_sqrt (r, x);
      MPF_CHECK_FORMAT (r);

      /* Expect to prec limbs of result.
         In the current implementation there's no stripping of low zero
         limbs in mpf_sqrt, so size should be exactly prec.  */
      if (SIZ(r) != r_prec)
        {
          printf ("mpf_sqrt wrong number of result limbs\n");
          mpf_trace ("  x", x);
          mpf_trace ("  r", r);
          printf    ("  r_prec=%lu\n", r_prec);
          printf    ("  SIZ(r)  %ld\n", (long) SIZ(r));
          printf    ("  PREC(r) %ld\n", (long) PREC(r));
          abort ();
        }

      /* Must have r^2 <= x, since r has been truncated. */
      mpf_mul (s, r, r);
      if (! (mpf_cmp (s, x) <= 0))
        {
          printf    ("mpf_sqrt result too big\n");
          mpf_trace ("  x", x);
          printf    ("  r_prec=%lu\n", r_prec);
          mpf_trace ("  r", r);
          mpf_trace ("  s", s);
          abort ();
        }

      /* Must have (r+ulp)^2 > x, or else r is too small. */
      refmpf_add_ulp (r);
      mpf_mul (s, r, r);
      if (! (mpf_cmp (s, x) > 0))
        {
          printf    ("mpf_sqrt result too small\n");
          mpf_trace ("  x", x);
          printf    ("  r_prec=%lu\n", r_prec);
          mpf_trace ("  r+ulp", r);
          mpf_trace ("  s", s);
          abort ();
        }
    }

  mpf_clear (x);
  mpf_clear (r);
  mpf_clear (s);
}
Beispiel #10
0
void
mpf_set_default_prec (unsigned long int prec_in_bits)
{
  __gmp_default_fp_limb_precision = __GMPF_BITS_TO_PREC (prec_in_bits);
}
Beispiel #11
0
/* mpf_set_default_prec --

Copyright 1993, 1994, 1995, 2001 Free Software Foundation, Inc.

This file is part of the GNU MP Library.

The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */

#include "gmp.h"
#include "gmp-impl.h"

mp_size_t __gmp_default_fp_limb_precision = __GMPF_BITS_TO_PREC (53);

void
mpf_set_default_prec (unsigned long int prec_in_bits)
{
  __gmp_default_fp_limb_precision = __GMPF_BITS_TO_PREC (prec_in_bits);
}
Beispiel #12
0
void
mpf_set_prec_raw (mpf_ptr x, unsigned long int prec_in_bits)
{
  x->_mp_prec = __GMPF_BITS_TO_PREC (prec_in_bits);
}