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; } }
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); }
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; }
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; }
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; }
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; }
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); }
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--; } }
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); }
/* 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); }
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); }
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); }
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); }
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); }
/* 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(); } } }
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); }
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); }
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); }
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); }
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 (); } } }
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 }
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); }
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; }