/* compute remainder as in definition: r = x - n * y, where n = trunc(x/y). warning: may change flags. */ static int slow_fmod (mpfr_ptr r, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd) { mpfr_t q; int inexact; 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)) { MPFR_SET_NAN (r); 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. */ return mpfr_set (r, x, rnd); } /* regular cases */ /* if 2^(ex-1) <= |x| < 2^ex, and 2^(ey-1) <= |y| < 2^ey, then |x/y| < 2^(ex-ey+1) */ mpfr_init2 (q, MAX (MPFR_PREC_MIN, mpfr_get_exp (x) - mpfr_get_exp (y) + 1)); mpfr_div (q, x, y, MPFR_RNDZ); mpfr_trunc (q, q); /* may change inexact flag */ mpfr_prec_round (q, mpfr_get_prec (q) + mpfr_get_prec (y), MPFR_RNDZ); inexact = mpfr_mul (q, q, y, MPFR_RNDZ); /* exact */ inexact = mpfr_sub (r, x, q, rnd); mpfr_clear (q); return inexact; }
SeedValue seed_mpfr_trunc (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue args[], SeedException * exception) { mpfr_ptr rop, op; gint ret; CHECK_ARG_COUNT("mpfr.trunc", 1); rop = seed_object_get_private(this_object); if ( seed_value_is_object_of_class(ctx, args[0], mpfr_class) ) { op = seed_object_get_private(args[0]); } else { TYPE_EXCEPTION("mpfr.trunc", "mpfr_t"); } ret = mpfr_trunc(rop, op); return seed_value_from_int(ctx, ret, exception); }
int mpfr_rint_trunc (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) { if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u)) return mpfr_set (r, u, rnd_mode); else { mpfr_t tmp; int inex; unsigned int saved_flags = __gmpfr_flags; mpfr_init2 (tmp, MPFR_PREC (u)); /* trunc(u) is always representable in tmp */ mpfr_trunc (tmp, u); __gmpfr_flags = saved_flags; inex = mpfr_set (r, tmp, rnd_mode); mpfr_clear (tmp); return inex; } }
int mpfr_rint_trunc (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) { if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u)) return mpfr_set (r, u, rnd_mode); else { mpfr_t tmp; int inex; MPFR_SAVE_EXPO_DECL (expo); MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (tmp, MPFR_PREC (u)); /* trunc(u) is always representable in tmp */ mpfr_trunc (tmp, u); inex = mpfr_set (r, tmp, rnd_mode); mpfr_clear (tmp); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (r, inex, rnd_mode); } }
int main (void) { mpfr_prec_t prec; mpfr_t x, y; intmax_t s; uintmax_t u; tests_start_mpfr (); for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++) { } mpfr_init2 (x, prec + 4); mpfr_init2 (y, prec + 4); mpfr_set_ui (x, 0, MPFR_RNDN); check_sj (0, x); check_uj (0, x); mpfr_set_ui (x, 1, MPFR_RNDN); check_sj (1, x); check_uj (1, x); mpfr_neg (x, x, MPFR_RNDN); check_sj (-1, x); mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN); mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */ mpfr_div_ui (y, x, 2, MPFR_RNDZ); mpfr_trunc (y, y); /* INTMAX_MAX */ for (s = MPFR_INTMAX_MAX; s != 0; s /= 17) { check_sj (s, y); mpfr_div_ui (y, y, 17, MPFR_RNDZ); mpfr_trunc (y, y); } mpfr_div_ui (y, x, 2, MPFR_RNDZ); mpfr_trunc (y, y); /* INTMAX_MAX */ mpfr_neg (y, y, MPFR_RNDN); if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0) mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */ for (s = MPFR_INTMAX_MIN; s != 0; s /= 17) { check_sj (s, y); mpfr_div_ui (y, y, 17, MPFR_RNDZ); mpfr_trunc (y, y); } for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17) { check_uj (u, x); mpfr_div_ui (x, x, 17, MPFR_RNDZ); mpfr_trunc (x, x); } mpfr_clear (x); mpfr_clear (y); check_erange (); tests_end_mpfr (); return 0; }
int main (void) { int j, k; mpfr_t x, y, z, t, y2, z2, t2; tests_start_mpfr (); mpfr_inits2 (SIZEX, x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); mpfr_set_str1 (x, "0.5"); mpfr_ceil(y, x); if (mpfr_cmp_ui (y, 1)) { printf ("Error in mpfr_ceil for x=0.5: expected 1.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_ceil(y, x); if (mpfr_cmp_ui(y,0)) { printf ("Error in mpfr_ceil for x=0.0: expected 0.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_ceil(y, x); if (mpfr_cmp_ui(y,1)) { printf ("Error in mpfr_ceil for x=1.0: expected 1.0, got "); mpfr_print_binary(y); putchar('\n'); exit (1); } for (j=0;j<1000;j++) { mpfr_urandomb (x, RANDS); MPFR_EXP (x) = 2; for (k = 2; k <= SIZEX; k++) { mpfr_set_prec(y, k); mpfr_set_prec(y2, k); mpfr_set_prec(z, k); mpfr_set_prec(z2, k); mpfr_set_prec(t, k); mpfr_set_prec(t2, k); mpfr_floor(y, x); mpfr_set(y2, x, MPFR_RNDD); mpfr_trunc(z, x); mpfr_set(z2, x, MPFR_RNDZ); mpfr_ceil(t, x); mpfr_set(t2, x, MPFR_RNDU); if (!mpfr_eq(y, y2, k)) { printf("Error in floor, x = "); mpfr_print_binary(x); printf("\n"); printf("floor(x) = "); mpfr_print_binary(y); printf("\n"); printf("round(x, RNDD) = "); mpfr_print_binary(y2); printf("\n"); exit(1); } if (!mpfr_eq(z, z2, k)) { printf("Error in trunc, x = "); mpfr_print_binary(x); printf("\n"); printf("trunc(x) = "); mpfr_print_binary(z); printf("\n"); printf("round(x, RNDZ) = "); mpfr_print_binary(z2); printf("\n"); exit(1); } if (!mpfr_eq(y, y2, k)) { printf("Error in ceil, x = "); mpfr_print_binary(x); printf("\n"); printf("ceil(x) = "); mpfr_print_binary(t); printf("\n"); printf("round(x, RNDU) = "); mpfr_print_binary(t2); printf("\n"); exit(1); } MPFR_EXP(x)++; } } mpfr_clears (x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); tests_end_mpfr (); return 0; }
MpfrFloat MpfrFloat::trunc(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_trunc(retval.mData->mFloat, value.mData->mFloat); return retval; }
int main (int argc, char *argv[]) { mp_size_t s; mpz_t z; mpfr_prec_t p; mpfr_t x, y, t, u, v; int r; int inexact, sign_t; tests_start_mpfr (); mpfr_init (x); mpfr_init (y); mpz_init (z); mpfr_init (t); mpfr_init (u); mpfr_init (v); mpz_set_ui (z, 1); for (s = 2; s < 100; s++) { /* z has exactly s bits */ mpz_mul_2exp (z, z, 1); if (randlimb () % 2) mpz_add_ui (z, z, 1); mpfr_set_prec (x, s); mpfr_set_prec (t, s); mpfr_set_prec (u, s); if (mpfr_set_z (x, z, MPFR_RNDN)) { printf ("Error: mpfr_set_z should be exact (s = %u)\n", (unsigned int) s); exit (1); } if (randlimb () % 2) mpfr_neg (x, x, MPFR_RNDN); if (randlimb () % 2) mpfr_div_2ui (x, x, randlimb () % s, MPFR_RNDN); for (p = 2; p < 100; p++) { int trint; mpfr_set_prec (y, p); mpfr_set_prec (v, p); for (r = 0; r < MPFR_RND_MAX ; r++) for (trint = 0; trint < 3; trint++) { if (trint == 2) inexact = mpfr_rint (y, x, (mpfr_rnd_t) r); else if (r == MPFR_RNDN) inexact = mpfr_round (y, x); else if (r == MPFR_RNDZ) inexact = (trint ? mpfr_trunc (y, x) : mpfr_rint_trunc (y, x, MPFR_RNDZ)); else if (r == MPFR_RNDU) inexact = (trint ? mpfr_ceil (y, x) : mpfr_rint_ceil (y, x, MPFR_RNDU)); else /* r = MPFR_RNDD */ inexact = (trint ? mpfr_floor (y, x) : mpfr_rint_floor (y, x, MPFR_RNDD)); if (mpfr_sub (t, y, x, MPFR_RNDN)) err ("subtraction 1 should be exact", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); sign_t = mpfr_cmp_ui (t, 0); if (trint != 0 && (((inexact == 0) && (sign_t != 0)) || ((inexact < 0) && (sign_t >= 0)) || ((inexact > 0) && (sign_t <= 0)))) err ("wrong inexact flag", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); if (inexact == 0) continue; /* end of the test for exact results */ if (((r == MPFR_RNDD || (r == MPFR_RNDZ && MPFR_SIGN (x) > 0)) && inexact > 0) || ((r == MPFR_RNDU || (r == MPFR_RNDZ && MPFR_SIGN (x) < 0)) && inexact < 0)) err ("wrong rounding direction", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); if (inexact < 0) { mpfr_add_ui (v, y, 1, MPFR_RNDU); if (mpfr_cmp (v, x) <= 0) err ("representable integer between x and its " "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); } else { mpfr_sub_ui (v, y, 1, MPFR_RNDD); if (mpfr_cmp (v, x) >= 0) err ("representable integer between x and its " "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); } if (r == MPFR_RNDN) { int cmp; if (mpfr_sub (u, v, x, MPFR_RNDN)) err ("subtraction 2 should be exact", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); cmp = mpfr_cmp_abs (t, u); if (cmp > 0) err ("faithful rounding, but not the nearest integer", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); if (cmp < 0) continue; /* |t| = |u|: x is the middle of two consecutive representable integers. */ if (trint == 2) { /* halfway case for mpfr_rint in MPFR_RNDN rounding mode: round to an even integer or significand. */ mpfr_div_2ui (y, y, 1, MPFR_RNDZ); if (!mpfr_integer_p (y)) err ("halfway case for mpfr_rint, result isn't an" " even integer", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); /* If floor(x) and ceil(x) aren't both representable integers, the significand must be even. */ mpfr_sub (v, v, y, MPFR_RNDN); mpfr_abs (v, v, MPFR_RNDN); if (mpfr_cmp_ui (v, 1) != 0) { mpfr_div_2si (y, y, MPFR_EXP (y) - MPFR_PREC (y) + 1, MPFR_RNDN); if (!mpfr_integer_p (y)) err ("halfway case for mpfr_rint, significand isn't" " even", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); } } else { /* halfway case for mpfr_round: x must have been rounded away from zero. */ if ((MPFR_SIGN (x) > 0 && inexact < 0) || (MPFR_SIGN (x) < 0 && inexact > 0)) err ("halfway case for mpfr_round, bad rounding" " direction", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); } } } } } mpfr_clear (x); mpfr_clear (y); mpz_clear (z); mpfr_clear (t); mpfr_clear (u); mpfr_clear (v); special (); coverage_03032011 (); #if __MPFR_STDC (199901L) if (argc > 1 && strcmp (argv[1], "-s") == 0) test_against_libc (); #endif tests_end_mpfr (); return 0; }
int main (void) { mp_size_t s; mpz_t z; mp_prec_t p; mpfr_t x, y, t; mp_rnd_t r; int inexact, sign_t; mpfr_init (x); mpfr_init (y); mpz_init (z); mpfr_init (t); mpz_set_ui (z, 1); for (s = 2; s < 100; s++) { /* z has exactly s bits */ mpz_mul_2exp (z, z, 1); if (LONG_RAND () % 2) mpz_add_ui (z, z, 1); mpfr_set_prec (x, s); mpfr_set_prec (t, s); if (mpfr_set_z (x, z, GMP_RNDN)) { fprintf (stderr, "Error: mpfr_set_z should be exact (s = %u)\n", (unsigned int) s); exit (1); } for (p=2; p<100; p++) { mpfr_set_prec (y, p); for (r=0; r<4; r++) { if (r == GMP_RNDN) inexact = mpfr_round (y, x); else if (r == GMP_RNDZ) inexact = mpfr_trunc (y, x); else if (r == GMP_RNDU) inexact = mpfr_ceil (y, x); else /* r = GMP_RNDD */ inexact = mpfr_floor (y, x); if (mpfr_sub (t, y, x, GMP_RNDN)) { fprintf (stderr, "Error: subtraction should be exact\n"); exit (1); } sign_t = mpfr_cmp_ui (t, 0); if (((inexact == 0) && (sign_t != 0)) || ((inexact < 0) && (sign_t >= 0)) || ((inexact > 0) && (sign_t <= 0))) { fprintf (stderr, "Wrong inexact flag\n"); exit (1); } } } } mpfr_clear (x); mpfr_clear (y); mpz_clear (z); mpfr_clear (t); return 0; }