static bool do_mpc_arg2 (real_value *result_real, real_value *result_imag, int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t), const real_value *arg0_real, const real_value *arg0_imag, const real_value *arg1_real, const real_value *arg1_imag, const real_format *format) { if (!real_isfinite (arg0_real) || !real_isfinite (arg0_imag) || !real_isfinite (arg1_real) || !real_isfinite (arg1_imag)) return false; int prec = format->p; mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; mpc_t m0, m1; mpc_init2 (m0, prec); mpc_init2 (m1, prec); mpfr_from_real (mpc_realref (m0), arg0_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m0), arg0_imag, GMP_RNDN); mpfr_from_real (mpc_realref (m1), arg1_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m1), arg1_imag, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m0, m0, m1, crnd); bool ok = do_mpc_ckconv (result_real, result_imag, m0, inexact, format); mpc_clear (m0); mpc_clear (m1); return ok; }
static bool do_mpc_arg1 (real_value *result_real, real_value *result_imag, int (*func) (mpc_ptr, mpc_srcptr, mpc_rnd_t), const real_value *arg_real, const real_value *arg_imag, const real_format *format) { /* To proceed, MPFR must exactly represent the target floating point format, which only happens when the target base equals two. */ if (format->b != 2 || !real_isfinite (arg_real) || !real_isfinite (arg_imag)) return false; int prec = format->p; mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; mpc_t m; mpc_init2 (m, prec); mpfr_from_real (mpc_realref (m), arg_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m), arg_imag, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m, m, crnd); bool ok = do_mpc_ckconv (result_real, result_imag, m, inexact, format); mpc_clear (m); return ok; }
static bool do_mpfr_arg3 (real_value *result, int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t), const real_value *arg0, const real_value *arg1, const real_value *arg2, const real_format *format) { /* To proceed, MPFR must exactly represent the target floating point format, which only happens when the target base equals two. */ if (format->b != 2 || !real_isfinite (arg0) || !real_isfinite (arg1) || !real_isfinite (arg2)) return false; int prec = format->p; mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN; mpfr_t m0, m1, m2; mpfr_inits2 (prec, m0, m1, m2, NULL); mpfr_from_real (m0, arg0, GMP_RNDN); mpfr_from_real (m1, arg1, GMP_RNDN); mpfr_from_real (m2, arg2, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m0, m0, m1, m2, rnd); bool ok = do_mpfr_ckconv (result, m0, inexact, format); mpfr_clears (m0, m1, m2, NULL); return ok; }
static bool do_mpfr_arg2 (real_value *result, int (*func) (mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), const wide_int_ref &arg0, const real_value *arg1, const real_format *format) { if (format->b != 2 || !real_isfinite (arg1)) return false; int prec = format->p; mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN; mpfr_t m; mpfr_init2 (m, prec); mpfr_from_real (m, arg1, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m, arg0.to_shwi (), m, rnd); bool ok = do_mpfr_ckconv (result, m, inexact, format); mpfr_clear (m); return ok; }
static bool do_mpfr_sincos (real_value *result_sin, real_value *result_cos, const real_value *arg, const real_format *format) { /* To proceed, MPFR must exactly represent the target floating point format, which only happens when the target base equals two. */ if (format->b != 2 || !real_isfinite (arg)) return false; int prec = format->p; mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN; mpfr_t m, ms, mc; mpfr_inits2 (prec, m, ms, mc, NULL); mpfr_from_real (m, arg, GMP_RNDN); mpfr_clear_flags (); bool inexact = mpfr_sin_cos (ms, mc, m, rnd); bool ok = (do_mpfr_ckconv (result_sin, ms, inexact, format) && do_mpfr_ckconv (result_cos, mc, inexact, format)); mpfr_clears (m, ms, mc, NULL); return ok; }
void gfc_conv_tree_to_mpfr (mpfr_ptr f, tree source) { mpfr_from_real (f, TREE_REAL_CST_PTR (source), GFC_RND_MODE); }