static void special_overflow (void) { mpfr_t x, y; mpfr_exp_t emin, emax; emin = mpfr_get_emin (); emax = mpfr_get_emax (); set_emin (-125); set_emax (128); mpfr_init2 (x, 24); mpfr_init2 (y, 48); mpfr_set_str_binary (x, "0.101100100000000000110100E0"); mpfr_asin (y, x, MPFR_RNDN); if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0", 2, MPFR_RNDN)) { printf("Special Overflow error.\n"); mpfr_dump (y); exit (1); } mpfr_clear (y); mpfr_clear (x); set_emin (emin); set_emax (emax); }
decimal r_asin(const decimal& a,bool round) { #ifdef USE_CGAL CGAL::Gmpfr m; CGAL::Gmpfr n=to_gmpfr(a); mpfr_asin(m.fr(),n.fr(),MPFR_RNDN); return r_round_preference(decimal(m),round); #else return r_round_preference(asin(a),round); #endif }
/* bug reported by Kevin Rauch on 15 December 2007 */ static void test20071215 (void) { mpfr_t x, y; mpfr_init (x); mpfr_init (y); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); mpfr_set_ui (y, 1, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_NEG(y)); mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_set_si (y, -1, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_POS(y)); mpfr_clear (x); mpfr_clear (y); }
static void reduced_expo_range (void) { mpfr_exp_t emin, emax; mpfr_t x, y, ex_y; int inex, ex_inex; unsigned int flags, ex_flags; emin = mpfr_get_emin (); emax = mpfr_get_emax (); mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0); mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN); mpfr_set_emin (1); mpfr_set_emax (1); mpfr_clear_flags (); inex = mpfr_asin (y, x, MPFR_RNDA); flags = __gmpfr_flags; mpfr_set_emin (emin); mpfr_set_emax (emax); mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN); ex_inex = -1; ex_flags = MPFR_FLAGS_INEXACT; if (SIGN (inex) != ex_inex || flags != ex_flags || ! mpfr_equal_p (y, ex_y)) { printf ("Error in reduced_expo_range\non x = "); mpfr_dump (x); printf ("Expected y = "); mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN); printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); printf ("Got y = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); exit (1); } mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); }
REAL _asin(REAL a, REAL, QByteArray &) { mpfr_t tmp1; mpfr_init2(tmp1, NUMBITS); mpfr_t result; mpfr_init2(result, NUMBITS); try { // mpfr_init_set_f(tmp1, a.get_mpf_t(), MPFR_RNDN); mpfr_set_str(tmp1, getString(a).data(), 10, MPFR_RNDN); mpfr_asin(result, tmp1, MPFR_RNDN); mpfr_get_f(a.get_mpf_t(), result, MPFR_RNDN); } catch(...) { mpfr_clear(tmp1); mpfr_clear(result); return ZERO; } mpfr_clear(tmp1); mpfr_clear(result); return a; }
static PyObject * _GMPy_MPFR_Asin(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!mpfr_nan_p(MPFR(x)) && (mpfr_cmp_si(MPFR(x), 1) > 0 || mpfr_cmp_si(MPFR(x), -1) < 0) && context->ctx.allow_complex ) { return GMPy_Complex_Asin(x, context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_asin(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; }
//------------------------------------------------------------------------------ // Name: //------------------------------------------------------------------------------ knumber_base *knumber_float::asin() { if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) { delete this; return new knumber_error(knumber_error::ERROR_UNDEFINED); } #ifdef KNUMBER_USE_MPFR mpfr_t mpfr; mpfr_init_set_f(mpfr, mpf_, rounding_mode); mpfr_asin(mpfr, mpfr, rounding_mode); mpfr_get_f(mpf_, mpfr, rounding_mode); mpfr_clear(mpfr); return this; #else const double x = mpf_get_d(mpf_); if(isinf(x)) { delete this; return new knumber_error(knumber_error::ERROR_POS_INFINITY); } else { return execute_libc_func< ::asin>(x); } #endif }
/// @brief asin keyword implementation /// void program::rpn_asin(void) { MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_asin(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } else if (_stack->get_type(0) == cmd_complex) { number* num; complex* i; // asin(z)=-iln(iz+sqrt(1-z*z)) stack::copy_and_push_back(*_stack, _stack->size() - 1, _calc_stack); i = (complex*)_calc_stack.get_obj(0); CHECK_MPFR(mpfr_set_d(i->re()->mpfr, 0.0, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_set_d(i->im()->mpfr, 1.0, floating_t::s_mpfr_rnd)); rpn_dup(); rpn_square(); num = (number*)_stack->allocate_back(number::calc_size(), cmd_number); CHECK_MPFR(mpfr_set_d(num->_value.mpfr, 1.0, floating_t::s_mpfr_rnd)); rpn_minus(); rpn_neg(); rpn_squareroot(); rpn_swap(); stack::copy_and_push_back(_calc_stack, 0, *_stack); rpn_mul(); rpn_plus(); rpn_ln(); stack::copy_and_push_back(_calc_stack, 0, *_stack); rpn_mul(); rpn_neg(); _calc_stack.pop_back(); } else ERR_CONTEXT(ret_bad_operand_type); }
int mpc_asin (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { mpfr_prec_t p, p_re, p_im, incr_p = 0; mpfr_rnd_t rnd_re, rnd_im; mpc_t z1; int inex; /* special values */ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op))) { if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op))) { mpfr_set_nan (mpc_realref (rop)); mpfr_set_inf (mpc_imagref (rop), mpfr_signbit (mpc_imagref (op)) ? -1 : +1); } else if (mpfr_zero_p (mpc_realref (op))) { mpfr_set (mpc_realref (rop), mpc_realref (op), GMP_RNDN); mpfr_set_nan (mpc_imagref (rop)); } else { mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); } return 0; } if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op))) { int inex_re; if (mpfr_inf_p (mpc_realref (op))) { int inf_im = mpfr_inf_p (mpc_imagref (op)); inex_re = set_pi_over_2 (mpc_realref (rop), (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd)); mpfr_set_inf (mpc_imagref (rop), (mpfr_signbit (mpc_imagref (op)) ? -1 : 1)); if (inf_im) mpfr_div_2ui (mpc_realref (rop), mpc_realref (rop), 1, GMP_RNDN); } else { mpfr_set_zero (mpc_realref (rop), (mpfr_signbit (mpc_realref (op)) ? -1 : 1)); inex_re = 0; mpfr_set_inf (mpc_imagref (rop), (mpfr_signbit (mpc_imagref (op)) ? -1 : 1)); } return MPC_INEX (inex_re, 0); } /* pure real argument */ if (mpfr_zero_p (mpc_imagref (op))) { int inex_re; int inex_im; int s_im; s_im = mpfr_signbit (mpc_imagref (op)); if (mpfr_cmp_ui (mpc_realref (op), 1) > 0) { if (s_im) inex_im = -mpfr_acosh (mpc_imagref (rop), mpc_realref (op), INV_RND (MPC_RND_IM (rnd))); else inex_im = mpfr_acosh (mpc_imagref (rop), mpc_realref (op), MPC_RND_IM (rnd)); inex_re = set_pi_over_2 (mpc_realref (rop), (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd)); if (s_im) mpc_conj (rop, rop, MPC_RNDNN); } else if (mpfr_cmp_si (mpc_realref (op), -1) < 0) { mpfr_t minus_op_re; minus_op_re[0] = mpc_realref (op)[0]; MPFR_CHANGE_SIGN (minus_op_re); if (s_im) inex_im = -mpfr_acosh (mpc_imagref (rop), minus_op_re, INV_RND (MPC_RND_IM (rnd))); else inex_im = mpfr_acosh (mpc_imagref (rop), minus_op_re, MPC_RND_IM (rnd)); inex_re = set_pi_over_2 (mpc_realref (rop), (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd)); if (s_im) mpc_conj (rop, rop, MPC_RNDNN); } else { inex_im = mpfr_set_ui (mpc_imagref (rop), 0, MPC_RND_IM (rnd)); if (s_im) mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), GMP_RNDN); inex_re = mpfr_asin (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd)); } return MPC_INEX (inex_re, inex_im); } /* pure imaginary argument */ if (mpfr_zero_p (mpc_realref (op))) { int inex_im; int s; s = mpfr_signbit (mpc_realref (op)); mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN); if (s) mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN); inex_im = mpfr_asinh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd)); return MPC_INEX (0, inex_im); } /* regular complex: asin(z) = -i*log(i*z+sqrt(1-z^2)) */ p_re = mpfr_get_prec (mpc_realref(rop)); p_im = mpfr_get_prec (mpc_imagref(rop)); rnd_re = MPC_RND_RE(rnd); rnd_im = MPC_RND_IM(rnd); p = p_re >= p_im ? p_re : p_im; mpc_init2 (z1, p); while (1) { mpfr_exp_t ex, ey, err; p += mpc_ceil_log2 (p) + 3 + incr_p; /* incr_p is zero initially */ incr_p = p / 2; mpfr_set_prec (mpc_realref(z1), p); mpfr_set_prec (mpc_imagref(z1), p); /* z1 <- z^2 */ mpc_sqr (z1, op, MPC_RNDNN); /* err(x) <= 1/2 ulp(x), err(y) <= 1/2 ulp(y) */ /* z1 <- 1-z1 */ ex = mpfr_get_exp (mpc_realref(z1)); mpfr_ui_sub (mpc_realref(z1), 1, mpc_realref(z1), GMP_RNDN); mpfr_neg (mpc_imagref(z1), mpc_imagref(z1), GMP_RNDN); ex = ex - mpfr_get_exp (mpc_realref(z1)); ex = (ex <= 0) ? 0 : ex; /* err(x) <= 2^ex * ulp(x) */ ex = ex + mpfr_get_exp (mpc_realref(z1)) - p; /* err(x) <= 2^ex */ ey = mpfr_get_exp (mpc_imagref(z1)) - p - 1; /* err(y) <= 2^ey */ ex = (ex >= ey) ? ex : ey; /* err(x), err(y) <= 2^ex, i.e., the norm of the error is bounded by |h|<=2^(ex+1/2) */ /* z1 <- sqrt(z1): if z1 = z + h, then sqrt(z1) = sqrt(z) + h/2/sqrt(t) */ ey = mpfr_get_exp (mpc_realref(z1)) >= mpfr_get_exp (mpc_imagref(z1)) ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1)); /* we have |z1| >= 2^(ey-1) thus 1/|z1| <= 2^(1-ey) */ mpc_sqrt (z1, z1, MPC_RNDNN); ex = (2 * ex + 1) - 2 - (ey - 1); /* |h^2/4/|t| <= 2^ex */ ex = (ex + 1) / 2; /* ceil(ex/2) */ /* express ex in terms of ulp(z1) */ ey = mpfr_get_exp (mpc_realref(z1)) <= mpfr_get_exp (mpc_imagref(z1)) ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1)); ex = ex - ey + p; /* take into account the rounding error in the mpc_sqrt call */ err = (ex <= 0) ? 1 : ex + 1; /* err(x) <= 2^err * ulp(x), err(y) <= 2^err * ulp(y) */ /* z1 <- i*z + z1 */ ex = mpfr_get_exp (mpc_realref(z1)); ey = mpfr_get_exp (mpc_imagref(z1)); mpfr_sub (mpc_realref(z1), mpc_realref(z1), mpc_imagref(op), GMP_RNDN); mpfr_add (mpc_imagref(z1), mpc_imagref(z1), mpc_realref(op), GMP_RNDN); if (mpfr_cmp_ui (mpc_realref(z1), 0) == 0 || mpfr_cmp_ui (mpc_imagref(z1), 0) == 0) continue; ex -= mpfr_get_exp (mpc_realref(z1)); /* cancellation in x */ ey -= mpfr_get_exp (mpc_imagref(z1)); /* cancellation in y */ ex = (ex >= ey) ? ex : ey; /* maximum cancellation */ err += ex; err = (err <= 0) ? 1 : err + 1; /* rounding error in sub/add */ /* z1 <- log(z1): if z1 = z + h, then log(z1) = log(z) + h/t with |t| >= min(|z1|,|z|) */ ex = mpfr_get_exp (mpc_realref(z1)); ey = mpfr_get_exp (mpc_imagref(z1)); ex = (ex >= ey) ? ex : ey; err += ex - p; /* revert to absolute error <= 2^err */ mpc_log (z1, z1, GMP_RNDN); err -= ex - 1; /* 1/|t| <= 1/|z| <= 2^(1-ex) */ /* express err in terms of ulp(z1) */ ey = mpfr_get_exp (mpc_realref(z1)) <= mpfr_get_exp (mpc_imagref(z1)) ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1)); err = err - ey + p; /* take into account the rounding error in the mpc_log call */ err = (err <= 0) ? 1 : err + 1; /* z1 <- -i*z1 */ mpfr_swap (mpc_realref(z1), mpc_imagref(z1)); mpfr_neg (mpc_imagref(z1), mpc_imagref(z1), GMP_RNDN); if (mpfr_can_round (mpc_realref(z1), p - err, GMP_RNDN, GMP_RNDZ, p_re + (rnd_re == GMP_RNDN)) && mpfr_can_round (mpc_imagref(z1), p - err, GMP_RNDN, GMP_RNDZ, p_im + (rnd_im == GMP_RNDN))) break; } inex = mpc_set (rop, z1, rnd); mpc_clear (z1); return inex; }
int main() { long iter; flint_rand_t state; printf("asin...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { arb_t a, b; fmpq_t q; mpfr_t t; long prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_asin(t, t, MPFR_RNDN); arb_asin(b, a, prec); if (!arb_contains_mpfr(b, t)) { printf("FAIL: containment\n\n"); printf("a = "); arb_print(a); printf("\n\n"); printf("b = "); arb_print(b); printf("\n\n"); abort(); } arb_asin(a, a, prec); if (!arb_equal(a, b)) { printf("FAIL: aliasing\n\n"); abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; long prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100); arb_asin(b, a, prec1); arb_asin(c, a, prec2); if (!arb_overlaps(b, c)) { printf("FAIL: overlap\n\n"); printf("a = "); arb_print(a); printf("\n\n"); printf("b = "); arb_print(b); printf("\n\n"); printf("c = "); arb_print(c); printf("\n\n"); abort(); } /* check sin(asin(x)) = x */ arb_sin(c, b, prec1); if (!arb_contains(c, a)) { printf("FAIL: functional equation\n\n"); printf("a = "); arb_print(a); printf("\n\n"); printf("b = "); arb_print(b); printf("\n\n"); printf("c = "); arb_print(c); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
MpfrFloat MpfrFloat::asin(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_asin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; }
static void special (void) { mpfr_t x, y; int r; mpfr_init (x); mpfr_init (y); /* asin(NaN) = NaN */ mpfr_set_nan (x); mpfr_asin (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_asin (NaN) <> NaN\n"); exit (1); } /* asin(+/-Inf) = NaN */ mpfr_set_inf (x, 1); mpfr_asin (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_asin (+Inf) <> NaN\n"); exit (1); } mpfr_set_inf (x, -1); mpfr_asin (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_asin (-Inf) <> NaN\n"); exit (1); } /* asin(+/-2) = NaN */ mpfr_set_ui (x, 2, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_asin (+2) <> NaN\n"); exit (1); } mpfr_set_si (x, -2, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); if (!mpfr_nan_p (y)) { printf ("Error: mpfr_asin (-2) <> NaN\n"); exit (1); } /* asin(+/-0) = +/-0 */ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("Error: mpfr_asin (+0) <> +0\n"); exit (1); } mpfr_neg (x, x, MPFR_RNDN); mpfr_asin (y, x, MPFR_RNDN); if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) { printf ("Error: mpfr_asin (-0) <> -0\n"); exit (1); } /* asin(1) = Pi/2 */ for (r = 0; r < MPFR_RND_MAX; r++) { mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */ mpfr_asin (y, x, (mpfr_rnd_t) r); mpfr_const_pi (x, (mpfr_rnd_t) r); mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */ if (mpfr_cmp (x, y)) { printf ("Error: asin(1) != Pi/2 for rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); exit (1); } } /* asin(-1) = -Pi/2 */ for (r = 0; r < MPFR_RND_MAX; r++) { mpfr_set_si (x, -1, MPFR_RNDN); /* exact */ mpfr_asin (y, x, (mpfr_rnd_t) r); mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r)); mpfr_neg (x, x, MPFR_RNDN); /* exact */ mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */ if (mpfr_cmp (x, y)) { printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); exit (1); } } mpfr_set_prec (x, 32); mpfr_set_prec (y, 32); mpfr_set_str_binary (x, "0.1101110111111111001011101000101"); mpfr_asin (x, x, MPFR_RNDN); mpfr_set_str_binary (y, "1.00001100101011000001111100111"); if (mpfr_cmp (x, y)) { printf ("Error: mpfr_asin (1)\n"); exit (1); } mpfr_set_str_binary (x, "-0.01110111000011101010111100000101"); mpfr_asin (x, x, MPFR_RNDN); mpfr_set_str_binary (y, "-0.0111101111010100011111110101"); if (mpfr_cmp (x, y)) { printf ("Error: mpfr_asin (2)\n"); mpfr_print_binary (x); printf ("\n"); mpfr_print_binary (y); printf ("\n"); exit (1); } mpfr_set_prec (x, 9); mpfr_set_prec (y, 19); mpfr_set_str_binary (x, "0.110000000E-6"); mpfr_asin (y, x, MPFR_RNDD); mpfr_set_prec (x, 19); mpfr_set_str_binary (x, "0.1100000000000001001E-6"); if (mpfr_cmp (x, y)) { printf ("Error: mpfr_asin (3)\n"); mpfr_dump (x); mpfr_dump (y); exit (1); } mpfr_clear (x); mpfr_clear (y); }
void bvisit(const ASec &x) { apply(result_, *(x.get_arg())); mpfr_ui_div(result_, 1, result_, rnd_); mpfr_asin(result_, result_, rnd_); }
void bvisit(const ASin &x) { apply(result_, *(x.get_arg())); mpfr_asin(result_, result_, rnd_); }