Ejemplo n.º 1
0
void
mpf_reldiff (mpf_t rdiff, mpf_srcptr x, mpf_srcptr y)
{
  if (UNLIKELY (SIZ(x) == 0))
    {
      mpf_set_ui (rdiff, (unsigned long int) (mpf_sgn (y) != 0));
    }
  else
    {
      mp_size_t dprec;
      mpf_t d;
      TMP_DECL;

      TMP_MARK;
      dprec = PREC(rdiff) + ABSIZ(x);
      ASSERT (PREC(rdiff)+1 == dprec - ABSIZ(x) + 1);

      PREC(d) = dprec;
      PTR(d) = TMP_ALLOC_LIMBS (dprec + 1);

      mpf_sub (d, x, y);
      SIZ(d) = ABSIZ(d);
      mpf_div (rdiff, d, x);

      TMP_FREE;
    }
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
void
mpf_mul_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
{
  mp_srcptr up;
  mp_size_t usize;
  mp_size_t size;
  mp_size_t prec, excess;
  mp_limb_t cy_limb, vl, cbit, cin;
  mp_ptr rp;

  usize = u->_mp_size;
  if (UNLIKELY (v == 0) || UNLIKELY (usize == 0))
    {
      r->_mp_size = 0;
      r->_mp_exp = 0;
      return;
    }

#if BITS_PER_ULONG > GMP_NUMB_BITS  /* avoid warnings about shift amount */
  if (v > GMP_NUMB_MAX)
    {
      mpf_t     vf;
      mp_limb_t vp[2];
      vp[0] = v & GMP_NUMB_MASK;
      vp[1] = v >> GMP_NUMB_BITS;
      PTR(vf) = vp;
      SIZ(vf) = 2;
      ASSERT_CODE (PREC(vf) = 2);
      EXP(vf) = 2;
      mpf_mul (r, u, vf);
      return;
    }
Ejemplo n.º 4
0
void
mpf_random2 (mpf_ptr x, mp_size_t xs, mp_exp_t exp)
{
    mp_size_t xn;
    mp_size_t prec;
    mp_limb_t elimb;

    xn = ABS (xs);
    prec = PREC(x);

    if (xn == 0)
    {
        EXP(x) = 0;
        SIZ(x) = 0;
        return;
    }

    if (xn > prec + 1)
        xn = prec + 1;

    /* General random mantissa.  */
    mpn_random2 (PTR(x), xn);

    /* Generate random exponent.  */
    _gmp_rand (&elimb, RANDS, GMP_NUMB_BITS);
    exp = ABS (exp);
    exp = elimb % (2 * exp + 1) - exp;

    EXP(x) = exp;
    SIZ(x) = xs < 0 ? -xn : xn;
}
Ejemplo n.º 5
0
 std::string& Verifier::remove_signature(std::string& message) const
 {
   number_size_t sig_len = signature_length();
   number_size_t length = message.length();
   PREC(SignatureLength, length >= sig_len);
   message.erase(length - sig_len, sig_len);
   return message;
 }
Ejemplo n.º 6
0
    string Decrypter::decrypt(const string& cipher) const
    {
      PREC(CipherBlockLength, cipher.length() == m_cipher_length);

      // Convert to numbers
      number_t cipher_number = m_converter.binread(cipher.substr(0, m_cipher_part_length));
      number_t cipher_power = m_converter.binread(cipher.substr(m_cipher_part_length, m_key_part_length));

      // Decrypt
      number_t plain_number = decrypt(cipher_number, cipher_power);

      // Convert back
      PREC(DecryptedPlainBlockLength, m_converter.byte_size(plain_number) <= m_plain_length);
      string plain = m_converter.binwrite(plain_number, m_plain_length);
      assert(plain.length() == m_plain_length);
      return plain;
    }
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
Archivo: fmt.c Proyecto: j4cbo/minilib
static void _fmts(struct fmtctx *ctx, char c, va_list *va) {
	const char *s = va_arg(*va, const char *);
	unsigned int n = PREC(ctx);
	(void)c;
	while ((!(ctx->state & ST_PREC) || n) && *s) {
		ctx->out(ctx->priv, *s++);
		n--;
	}
}
Ejemplo n.º 9
0
void
insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
{
  mp_size_t max = PREC(x) - SIZ(x);
  mp_size_t s;
  mpz_t ds; mpz_init (ds);
  mpz_urandomb (ds, rands, 32);
  s = mpz_get_ui (ds) % (max + 1);
  MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
  MPN_ZERO (PTR(x), s);
  SIZ(x) += s;
  mpz_clear (ds);
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
void
check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor)
{
  mpf_t  got;

  mpf_init2 (got, mpf_get_prec (trunc));
  ASSERT_ALWAYS (PREC(got) == PREC(trunc));
  ASSERT_ALWAYS (PREC(got) == PREC(ceil));
  ASSERT_ALWAYS (PREC(got) == PREC(floor));

#define CHECK_SEP(name, fun, want)              \
  mpf_set_ui (got, 54321L); /* initial junk */  \
  fun (got, src);                               \
  MPF_CHECK_FORMAT (got);                       \
  if (mpf_cmp (got, want) != 0)                 \
    {                                           \
	printf ("%s wrong\n", name);            \
	check_print (src, got, want);           \
	abort ();                               \
    }

  CHECK_SEP ("mpf_trunc", mpf_trunc, trunc);
  CHECK_SEP ("mpf_ceil",  mpf_ceil,  ceil);
  CHECK_SEP ("mpf_floor", mpf_floor, floor);

#define CHECK_INPLACE(name, fun, want)  \
  mpf_set (got, src);                   \
  fun (got, got);                       \
  MPF_CHECK_FORMAT (got);               \
  if (mpf_cmp (got, want) != 0)         \
    {                                   \
	printf ("%s wrong\n", name);    \
	check_print (src, got, want);   \
	abort ();                       \
    }

  CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc);

  /* Can't do these unconditionally in case truncation by mpf_set strips
     some low non-zero limbs which would have rounded the result.  */
  if (ABSIZ(src) <= PREC(trunc)+1)
    {
      CHECK_INPLACE ("mpf_ceil",  mpf_ceil,  ceil);
      CHECK_INPLACE ("mpf_floor", mpf_floor, floor);
    }

  mpf_clear (got);
}
Ejemplo n.º 12
0
void
mpf_trunc (mpf_ptr r, mpf_srcptr u)
{
  mp_ptr     rp;
  mp_srcptr  up;
  mp_size_t  size, asize, prec;
  mp_exp_t   exp;

  exp = EXP(u);
  size = SIZ(u);
  if (size == 0 || exp <= 0)
    {
      /* u is only a fraction */
      SIZ(r) = 0;
      EXP(r) = 0;
      return;
    }

  up = PTR(u);
  EXP(r) = exp;
  asize = ABS (size);
  up += asize;

  /* skip fraction part of u */
  asize = MIN (asize, exp);

  /* don't lose precision in the copy */
  prec = PREC(r) + 1;

  /* skip excess over target precision */
  asize = MIN (asize, prec);

  up -= asize;
  rp = PTR(r);
  SIZ(r) = (size >= 0 ? asize : -asize);
  if (rp != up)
    MPN_COPY_INCR (rp, up, asize);
}
Ejemplo n.º 13
0
static void
mpf_ceil_or_floor (mpf_ptr r, mpf_srcptr u, int dir)
{
  mp_ptr     rp, up, p;
  mp_size_t  size, asize, prec;
  mp_exp_t   exp;

  size = SIZ(u);
  if (size == 0)
    {
    zero:
      SIZ(r) = 0;
      EXP(r) = 0;
      return;
    }

  rp = PTR(r);
  exp = EXP(u);
  if (exp <= 0)
    {
      /* u is only a fraction */
      if ((size ^ dir) < 0)
        goto zero;
      rp[0] = 1;
      EXP(r) = 1;
      SIZ(r) = dir;
      return;
    }
  EXP(r) = exp;

  up = PTR(u);
  asize = ABS (size);
  up += asize;

  /* skip fraction part of u */
  asize = MIN (asize, exp);

  /* don't lose precision in the copy */
  prec = PREC (r) + 1;

  /* skip excess over target precision */
  asize = MIN (asize, prec);

  up -= asize;

  if ((size ^ dir) >= 0)
    {
      /* rounding direction matches sign, must increment if ignored part is
         non-zero */
      for (p = PTR(u); p != up; p++)
        {
          if (*p != 0)
            {
              if (mpn_add_1 (rp, up, asize, CNST_LIMB(1)))
                {
                  /* was all 0xFF..FFs, which have become zeros, giving just
                     a carry */
                  rp[0] = 1;
                  asize = 1;
                  EXP(r)++;
                }
              SIZ(r) = (size >= 0 ? asize : -asize);
              return;
            }
        }
    }

  SIZ(r) = (size >= 0 ? asize : -asize);
  if (rp != up)
    MPN_COPY_INCR (rp, up, asize);
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
/* Since MPFR-3.0, return the usual inexact value.
   The erange flag is set if an error occurred in the conversion
   (y is NaN, +Inf, or -Inf that have no equivalent in mpf)
*/
int
mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
{
  int inex;
  mp_size_t sx, sy;
  mpfr_prec_t precx, precy;
  mp_limb_t *xp;
  int sh;

  if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
    {
      if (MPFR_IS_ZERO(y))
        {
          mpf_set_ui (x, 0);
          return 0;
        }
      else if (MPFR_IS_NAN (y))
        {
          MPFR_SET_ERANGEFLAG ();
          return 0;
        }
      else /* y is plus infinity (resp. minus infinity), set x to the maximum
              value (resp. the minimum value) in precision PREC(x) */
        {
          int i;
          mp_limb_t *xp;

          MPFR_SET_ERANGEFLAG ();

          /* To this day, [mp_exp_t] and mp_size_t are #defined as the same
             type */
          EXP (x) = MP_SIZE_T_MAX;

          sx = PREC (x);
          SIZ (x) = sx;
          xp = PTR (x);
          for (i = 0; i < sx; i++)
            xp[i] = MPFR_LIMB_MAX;

          if (MPFR_IS_POS (y))
            return -1;
          else
            {
              mpf_neg (x, x);
              return +1;
            }
        }
    }

  sx = PREC(x); /* number of limbs of the mantissa of x */

  precy = MPFR_PREC(y);
  precx = (mpfr_prec_t) sx * GMP_NUMB_BITS;
  sy = MPFR_LIMB_SIZE (y);

  xp = PTR (x);

  /* since mpf numbers are represented in base 2^GMP_NUMB_BITS,
     we loose -EXP(y) % GMP_NUMB_BITS bits in the most significant limb */
  sh = MPFR_GET_EXP(y) % GMP_NUMB_BITS;
  sh = sh <= 0 ? - sh : GMP_NUMB_BITS - sh;
  MPFR_ASSERTD (sh >= 0);
  if (precy + sh <= precx) /* we can copy directly */
    {
      mp_size_t ds;

      MPFR_ASSERTN (sx >= sy);
      ds = sx - sy;

      if (sh != 0)
        {
          mp_limb_t out;
          out = mpn_rshift (xp + ds, MPFR_MANT(y), sy, sh);
          MPFR_ASSERTN (ds > 0 || out == 0);
          if (ds > 0)
            xp[--ds] = out;
        }
      else
        MPN_COPY (xp + ds, MPFR_MANT (y), sy);
      if (ds > 0)
        MPN_ZERO (xp, ds);
      EXP(x) = (MPFR_GET_EXP(y) + sh) / GMP_NUMB_BITS;
      inex = 0;
    }
  else /* we have to round to precx - sh bits */
    {
      mpfr_t z;
      mp_size_t sz;

      /* Recall that precx = (mpfr_prec_t) sx * GMP_NUMB_BITS, thus removing
         sh bits (sh < GMP_NUMB_BITSS) won't reduce the number of limbs. */
      mpfr_init2 (z, precx - sh);
      sz = MPFR_LIMB_SIZE (z);
      MPFR_ASSERTN (sx == sz);

      inex = mpfr_set (z, y, rnd_mode);
      /* warning, sh may change due to rounding, but then z is a power of two,
         thus we can safely ignore its last bit which is 0 */
      sh = MPFR_GET_EXP(z) % GMP_NUMB_BITS;
      sh = sh <= 0 ? - sh : GMP_NUMB_BITS - sh;
      MPFR_ASSERTD (sh >= 0);
      if (sh != 0)
        {
          mp_limb_t out;
          out = mpn_rshift (xp, MPFR_MANT(z), sz, sh);
          /* If sh hasn't changed, it is the number of the non-significant
             bits in the lowest limb of z. Therefore out == 0. */
          MPFR_ASSERTD (out == 0);  (void) out; /* avoid a warning */
        }
      else
        MPN_COPY (xp, MPFR_MANT(z), sz);
      EXP(x) = (MPFR_GET_EXP(z) + sh) / GMP_NUMB_BITS;
      mpfr_clear (z);
    }

  /* set size and sign */
  SIZ(x) = (MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0) ? -sx : sx;

  return inex;
}
void
check_limbdata (void)
{
#define M  GMP_NUMB_MAX
  
  static const struct {
    mp_exp_t       exp;
    mp_size_t      size;
    mp_limb_t      d[10];
    unsigned long  want;

  } data[] = {

    /* in the comments here, a "_" indicates a digit (ie. limb) position not
       included in the d data, and therefore zero */

    { 0, 0, { 0 }, 0L },    /* 0 */

    { 1,  1, { 1 }, 1L },   /* 1 */
    { 1, -1, { 1 }, -1L },  /* -1 */

    { 0,  1, { 1 }, 0L },   /* .1 */
    { 0, -1, { 1 }, 0L },   /* -.1 */

    { -1,  1, { 1 }, 0L },  /* ._1 */
    { -1, -1, { 1 }, 0L },  /* -._1 */

    { -999,          1, { 1 }, 0L },   /* .___1 small */
    { MP_EXP_T_MIN,  1, { 1 }, 0L },   /* .____1 very small */

    { 999,          1, { 1 }, 0L },    /* 1____. big */
    { MP_EXP_T_MAX, 1, { 1 }, 0L },    /* 1_____. very big */

    { 1, 2, { 999, 2 }, 2L },                  /* 2.9 */
    { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L },  /* 10003.987 */

    { 2, 2, { M, M },    LONG_MAX }, /* FF. */
    { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */
    { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */

#if GMP_NUMB_BITS >= BITS_PER_ULONG
    /* normal case, numb bigger than long */
    { 2,  1, { 1 },    0L },      /* 1_. */
    { 2,  2, { 0, 1 }, 0L },      /* 10. */
    { 2,  2, { 999, 1 }, 999L },  /* 19. */
    { 3,  2, { 999, 1 }, 0L },    /* 19_. */

#else
    /* nails case, numb smaller than long */
    { 2,  1, { 1 }, 1L << GMP_NUMB_BITS },  /* 1_. */
    { 3,  1, { 1 }, 0L },                   /* 1__. */

    { 2,  2, { 99, 1 },    99L + (1L << GMP_NUMB_BITS) },  /* 19. */
    { 3,  2, { 1, 99 },    1L << GMP_NUMB_BITS },          /* 91_. */
    { 3,  3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS },          /* 910. */

#endif
  };

  mpf_t          f;
  unsigned long  got;
  int            i;
  mp_limb_t      buf[20 + numberof(data[i].d)];

  for (i = 0; i < numberof (data); i++)
    {
      refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
      refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
      refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));

      PTR(f) = buf+10;
      EXP(f) = data[i].exp;
      SIZ(f) = data[i].size;
      PREC(f) = numberof (data[i].d);
      MPF_CHECK_FORMAT (f);

      got = mpf_get_si (f);
      if (got != data[i].want)
        {
          printf    ("mpf_get_si wrong at limb data[%d]\n", i);
          mpf_trace ("  f", f);
          mpn_trace ("  d", data[i].d, data[i].size);
          printf    ("  size %ld\n", (long) data[i].size);
          printf    ("  exp %ld\n", (long) data[i].exp);
          printf    ("  got   %lu (0x%lX)\n", got, got);
          printf    ("  want  %lu (0x%lX)\n", data[i].want, data[i].want);
          abort();
        }
    }
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
void
check_various (void)
{
  mpf_t  src, trunc, ceil, floor;
  int    n, i;

  mpf_init2 (src, 512L);
  mpf_init2 (trunc, 256L);
  mpf_init2 (ceil,  256L);
  mpf_init2 (floor, 256L);

  /* 0 */
  mpf_set_ui (src, 0L);
  mpf_set_ui (trunc, 0L);
  mpf_set_ui (ceil, 0L);
  mpf_set_ui (floor, 0L);
  check_all (src, trunc, ceil, floor);

  /* 1 */
  mpf_set_ui (src, 1L);
  mpf_set_ui (trunc, 1L);
  mpf_set_ui (ceil, 1L);
  mpf_set_ui (floor, 1L);
  check_all (src, trunc, ceil, floor);

  /* 2^1024 */
  mpf_set_ui (src, 1L);
  mpf_mul_2exp (src,   src,   1024L);
  mpf_set (trunc, src);
  mpf_set (ceil,  src);
  mpf_set (floor, src);
  check_all (src, trunc, ceil, floor);

  /* 1/2^1024, fraction only */
  mpf_set_ui (src, 1L);
  mpf_div_2exp (src,  src, 1024L);
  mpf_set_si (trunc, 0L);
  mpf_set_si (ceil, 1L);
  mpf_set_si (floor, 0L);
  check_all (src, trunc, ceil, floor);

  /* 1/2 */
  mpf_set_ui (src, 1L);
  mpf_div_2exp (src,  src, 1L);
  mpf_set_si (trunc, 0L);
  mpf_set_si (ceil, 1L);
  mpf_set_si (floor, 0L);
  check_all (src, trunc, ceil, floor);

  /* 123+1/2^64 */
  mpf_set_ui (src, 1L);
  mpf_div_2exp (src,  src, 64L);
  mpf_add_ui (src,  src, 123L);
  mpf_set_si (trunc, 123L);
  mpf_set_si (ceil, 124L);
  mpf_set_si (floor, 123L);
  check_all (src, trunc, ceil, floor);

  /* integer of full prec+1 limbs, unchanged */
  n = PREC(trunc)+1;
  ASSERT_ALWAYS (n <= PREC(src)+1);
  EXP(src) = n;
  SIZ(src) = n;
  for (i = 0; i < SIZ(src); i++)
    PTR(src)[i] = i+100;
  mpf_set (trunc, src);
  mpf_set (ceil, src);
  mpf_set (floor, src);
  check_all (src, trunc, ceil, floor);

  /* full prec+1 limbs, 1 trimmed for integer */
  n = PREC(trunc)+1;
  ASSERT_ALWAYS (n <= PREC(src)+1);
  EXP(src) = n-1;
  SIZ(src) = n;
  for (i = 0; i < SIZ(src); i++)
    PTR(src)[i] = i+200;
  EXP(trunc) = n-1;
  SIZ(trunc) = n-1;
  for (i = 0; i < SIZ(trunc); i++)
    PTR(trunc)[i] = i+201;
  mpf_set (floor, trunc);
  mpf_add_ui (ceil, trunc, 1L);
  check_all (src, trunc, ceil, floor);

  /* prec+3 limbs, 2 trimmed for size */
  n = PREC(trunc)+3;
  ASSERT_ALWAYS (n <= PREC(src)+1);
  EXP(src) = n;
  SIZ(src) = n;
  for (i = 0; i < SIZ(src); i++)
    PTR(src)[i] = i+300;
  EXP(trunc) = n;
  SIZ(trunc) = n-2;
  for (i = 0; i < SIZ(trunc); i++)
    PTR(trunc)[i] = i+302;
  mpf_set (floor, trunc);
  mpf_set (ceil, trunc);
  PTR(ceil)[0]++;
  check_all (src, trunc, ceil, floor);

  /* prec+4 limbs, 2 trimmed for size, 1 trimmed for integer */
  n = PREC(trunc)+4;
  ASSERT_ALWAYS (n <= PREC(src)+1);
  EXP(src) = n-1;
  SIZ(src) = n;
  for (i = 0; i < SIZ(src); i++)
    PTR(src)[i] = i+400;
  EXP(trunc) = n-1;
  SIZ(trunc) = n-3;
  for (i = 0; i < SIZ(trunc); i++)
    PTR(trunc)[i] = i+403;
  mpf_set (floor, trunc);
  mpf_set (ceil, trunc);
  PTR(ceil)[0]++;
  check_all (src, trunc, ceil, floor);

  /* F.F, carry out of ceil */
  EXP(src) = 1;
  SIZ(src) = 2;
  PTR(src)[0] = GMP_NUMB_MAX;
  PTR(src)[1] = GMP_NUMB_MAX;
  EXP(trunc) = 1;
  SIZ(trunc) = 1;
  PTR(trunc)[0] = GMP_NUMB_MAX;
  mpf_set (floor, trunc);
  EXP(ceil) = 2;
  SIZ(ceil) = 1;
  PTR(ceil)[0] = 1;
  check_all (src, trunc, ceil, floor);

  /* FF.F, carry out of ceil */
  EXP(src) = 2;
  SIZ(src) = 3;
  PTR(src)[0] = GMP_NUMB_MAX;
  PTR(src)[1] = GMP_NUMB_MAX;
  PTR(src)[2] = GMP_NUMB_MAX;
  EXP(trunc) = 2;
  SIZ(trunc) = 2;
  PTR(trunc)[0] = GMP_NUMB_MAX;
  PTR(trunc)[1] = GMP_NUMB_MAX;
  mpf_set (floor, trunc);
  EXP(ceil) = 3;
  SIZ(ceil) = 1;
  PTR(ceil)[0] = 1;
  check_all (src, trunc, ceil, floor);

  mpf_clear (src);
  mpf_clear (trunc);
  mpf_clear (ceil);
  mpf_clear (floor);
}
Ejemplo n.º 19
0
static void
ternary_test (void)
{
  int prec;
  int rnd;
  int inex, expected_inex;
  mpf_t x;
  mpfr_t y;

  mpf_init2 (x, 256);
  mpfr_init2 (y, 256);

  for (prec = 2; prec <= 256; prec++)
    {

      mpf_set_prec (x, prec);
      mpfr_set_prec (y, PREC (x) * GMP_NUMB_BITS + 1);

      /* y == 1 */
      mpfr_set_ui_2exp (y, 1, prec, MPFR_RNDN);

      RND_LOOP (rnd)
      {
        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (inex != 0 || mpfr_cmp_f (y, x) !=0)
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            if (inex != 0)
              printf ("got ternary value = %+d, expected: 0\n", inex);

            exit (1);
          }
      }

      /* y == 1 + epsilon */
      mpfr_nextbelow (y);

      RND_LOOP (rnd)
      {
        switch (rnd)
          {
          case MPFR_RNDU: case MPFR_RNDA:
          case MPFR_RNDN:
            expected_inex = +1;
            break;
          default :
            expected_inex = -1;
          }

        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (! SAME_SIGN (expected_inex, inex)
            || SAME_SIGN (expected_inex, mpfr_cmp_f (y, x)))
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            if (! SAME_SIGN (expected_inex, inex))
              printf ("got ternary value = %+d, expected: %+d\n",
                      inex, expected_inex);

            exit (1);
          }
      }

      /* y == positive random float */
      mpfr_random2 (y, MPFR_LIMB_SIZE (y), 1024, RANDS);

      RND_LOOP (rnd)
      {
        inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);

        if (! SAME_SIGN (inex, -mpfr_cmp_f (y, x)))
          {
            printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
            mpf_out_str (stdout, 2, 0, x);
            printf ("\ny = ");
            mpfr_dump (y);
            printf ("got ternary value = %+d, expected: %+d\n",
                    inex, -mpfr_cmp_f (y, x));

            exit (1);
          }
      }
    }

  mpf_clear (x);
  mpfr_clear (y);
}
Ejemplo n.º 20
0
void
check_data (void)
{
    static const struct {
        struct {
            int        exp, size;
            mp_limb_t  d[10];
        } x, y, want;

    } data[] = {
        { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },

        /* f - f == 0, various sizes.
           These exercise a past problem (gmp 4.1.3 and earlier) where the
           result exponent was not zeroed on a zero result like this.  */
        { { 0, 0 }, { 0, 0 }, { 0, 0 } },
        { { 99, 1, { 1 } },             { 99, 1, { 1 } },             { 0, 0 } },
        { { 99, 2, { 123, 456 } },      { 99, 2, { 123, 456 } },      { 0, 0 } },
        { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } },

        /* High limbs cancel, leaving just the low limbs of the longer operand.
           This exercises a past problem (gmp 4.1.3 and earlier) where high zero
           limbs on the remainder were not stripped before truncating to the
           destination, causing loss of precision.  */
        { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },
        { { 123, 3, { 8, 0, 9 } },          { 123, 1, { 9 } }, { 121, 1, { 8 } } },
        { { 123, 4, { 8, 0, 0, 9 } },       { 123, 1, { 9 } }, { 120, 1, { 8 } } },
        { { 123, 5, { 8, 0, 0, 0, 9 } },    { 123, 1, { 9 } }, { 119, 1, { 8 } } },
        { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } },

    };

    mpf_t  x, y, got, want;
    int  i, swap;

    mp_trace_base = 16;
    mpf_init (got);

    for (i = 0; i < numberof (data); i++)
    {
        for (swap = 0; swap <= 1; swap++)
        {
            PTR(x) = (mp_ptr) data[i].x.d;
            SIZ(x) = data[i].x.size;
            EXP(x) = data[i].x.exp;
            PREC(x) = numberof (data[i].x.d);
            MPF_CHECK_FORMAT (x);

            PTR(y) = (mp_ptr) data[i].y.d;
            SIZ(y) = data[i].y.size;
            EXP(y) = data[i].y.exp;
            PREC(y) = numberof (data[i].y.d);
            MPF_CHECK_FORMAT (y);

            PTR(want) = (mp_ptr) data[i].want.d;
            SIZ(want) = data[i].want.size;
            EXP(want) = data[i].want.exp;
            PREC(want) = numberof (data[i].want.d);
            MPF_CHECK_FORMAT (want);

            if (swap)
            {
                mpf_swap (x, y);
                SIZ(want) = - SIZ(want);
            }

            mpf_sub (got, x, y);
            /*           MPF_CHECK_FORMAT (got); */

            if (mpf_cmp (got, want) != 0)
            {
                printf ("check_data() wrong reault at data[%d] (operands%s swapped)\n", i, swap ? "" : " not");
                mpf_trace ("x   ", x);
                mpf_trace ("y   ", y);
                mpf_trace ("got ", got);
                mpf_trace ("want", want);
                abort ();
            }
        }
    }

    mpf_clear (got);
}
Ejemplo n.º 21
0
void
check_data (void)
{
  static const struct
  {
    struct {
      int        exp, size;
      mp_limb_t  d[10];
    } x, y;
    mp_bitcnt_t bits;
    int want;

  } data[] = {
    { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },

    { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
    { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
    { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },

    { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },

    { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
  };

  mpf_t  x, y;
  int got, got_swapped;
  int i;
  mp_trace_base = 16;

  for (i = 0; i < numberof (data); i++)
    {
      PTR(x) = (mp_ptr) data[i].x.d;
      SIZ(x) = data[i].x.size;
      EXP(x) = data[i].x.exp;
      PREC(x) = numberof (data[i].x.d);
      MPF_CHECK_FORMAT (x);

      PTR(y) = (mp_ptr) data[i].y.d;
      SIZ(y) = data[i].y.size;
      EXP(y) = data[i].y.exp;
      PREC(y) = numberof (data[i].y.d);
      MPF_CHECK_FORMAT (y);

      got         = mpf_eq (x, y, data[i].bits);
      got_swapped = mpf_eq (y, x, data[i].bits);

      if (got != got_swapped || got != data[i].want)
	{
	  printf ("check_data() wrong result at data[%d]\n", i);
	  mpf_trace ("x   ", x);
	  mpf_trace ("y   ", y);
	  printf ("got         %d\n", got);
	  printf ("got_swapped %d\n", got_swapped);
	  printf ("want        %d\n", data[i].want);
	  abort ();
        }
    }
}
Ejemplo n.º 22
0
uint8_t lcd_outdezNAtt( uint8_t x, uint8_t y, int32_t val, uint8_t mode, int8_t len )
{
  uint8_t fw = FWNUM;
  uint8_t prec = PREC(mode);
	uint8_t negative = 0 ;
  uint8_t xn = 0;
  uint8_t ln = 2;
  char c;
  uint8_t xinc ;
	uint8_t fullwidth = 0 ;

	mode &= ~NO_UNIT ;
	if ( len < 0 )
	{
		fullwidth = 1 ;
		len = -len ;		
	}

  if ( val < 0 )
	{
		val = -val ;
		negative = 1 ;
	}

  if (mode & DBLSIZE)
  {
    fw += FWNUM ;
    xinc = 2*FWNUM;
    lcd_lastPos = 2*FW;
  }
  else
  {
    xinc = FWNUM ;
    lcd_lastPos = FW;
  }

  if (mode & LEFT) {
//    if (val >= 10000)
//      x += fw;
    if(negative)
    {
      x += fw;
    }
    if (val >= 1000)
      x += fw;
    if (val >= 100)
      x += fw;
    if (val >= 10)
      x += fw;
    if ( prec )
    {
      if ( prec == 2 )
      {
        if ( val < 100 )
        {
          x += fw;
        }
      }
      if ( val < 10 )
      {
        x+= fw;
      }
    }
  }
  else
  {
    x -= xinc;
  }
  lcd_lastPos += x ;

  if ( prec == 2 )
  {
    mode -= LEADING0;  // Can't have PREC2 and LEADING0
  }

  for (uint8_t i=1; i<=len; i++)
	{
		div_t qr ;
		qr = div( val, 10 ) ;
    c = (qr.rem) + '0';
    lcd_putcAtt(x, y, c, mode);
    if (prec==i) {
      if (mode & DBLSIZE) {
        xn = x;
        if( c<='3' && c>='1') ln++;
        uint8_t tn = (qr.quot) % 10;
        if(tn==2 || tn==4) {
          if (c=='4') {
            xn++;
          }
          else {
            xn--; ln++;
          }
        }
      }
      else {
        x -= 2;
        if (mode & INVERS)
          lcd_vline(x+1, y, 7);
        else
          lcd_plot(x+1, y+6);
      }
      if (qr.quot)
        prec = 0;
    }
    val = qr.quot ;
    if (!val)
    {
      if (prec)
      {
        if ( prec == 2 )
        {
          if ( i > 1 )
          {
            prec = 0 ;
          }
        }
        else
        {
          prec = 0 ;
        }
      }
      else if (mode & LEADING0)
			{
				if ( fullwidth == 0 )
				{
        	mode -= LEADING0;
				}
			}
      else
        break;
    }
    x-=fw;
  }
  if (xn) {
    lcd_hline(xn, y+2*FH-4, ln);
    lcd_hline(xn, y+2*FH-3, ln);
  }
  if(negative) lcd_putcAtt(x-fw,y,'-',mode);
	asm("") ;
	return 0 ;		// Stops compiler creating two sets of POPS, saves flash
}
Ejemplo n.º 23
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);
}
Ejemplo n.º 24
0
Archivo: set_q.c Proyecto: Cl3Kener/gmp
void
mpf_set_q (mpf_t r, mpq_srcptr q)
{
  mp_srcptr np, dp;
  mp_size_t prec, nsize, dsize, qsize, prospective_qsize, tsize, zeros;
  mp_size_t sign_quotient, high_zero;
  mp_ptr qp, tp;
  mp_exp_t exp;
  TMP_DECL;

  ASSERT (SIZ(&q->_mp_den) > 0);  /* canonical q */

  nsize = SIZ (&q->_mp_num);
  dsize = SIZ (&q->_mp_den);

  if (UNLIKELY (nsize == 0))
    {
      SIZ (r) = 0;
      EXP (r) = 0;
      return;
    }

  TMP_MARK;

  prec = PREC (r);
  qp = PTR (r);

  sign_quotient = nsize;
  nsize = ABS (nsize);
  np = PTR (&q->_mp_num);
  dp = PTR (&q->_mp_den);

  prospective_qsize = nsize - dsize + 1;  /* q from using given n,d sizes */
  exp = prospective_qsize;                /* ie. number of integer limbs */
  qsize = prec + 1;                       /* desired q */

  zeros = qsize - prospective_qsize;      /* n zeros to get desired qsize */
  tsize = nsize + zeros;                  /* size of intermediate numerator */
  tp = TMP_ALLOC_LIMBS (tsize + 1);       /* +1 for mpn_div_q's scratch */

  if (zeros > 0)
    {
      /* pad n with zeros into temporary space */
      MPN_ZERO (tp, zeros);
      MPN_COPY (tp+zeros, np, nsize);
      np = tp;                            /* mpn_div_q allows this overlap */
    }
  else
    {
      /* shorten n to get desired qsize */
      np -= zeros;
    }

  ASSERT (tsize-dsize+1 == qsize);
  mpn_div_q (qp, np, tsize, dp, dsize, tp);

  /* strip possible zero high limb */
  high_zero = (qp[qsize-1] == 0);
  qsize -= high_zero;
  exp -= high_zero;

  EXP (r) = exp;
  SIZ (r) = sign_quotient >= 0 ? qsize : -qsize;

  TMP_FREE;
}