Ejemplo n.º 1
0
real atan(const real & a)
{
	real x;
	
	mpfr_atan(x.r, a.r, MPFR_RNDN);
	return x;
}
Ejemplo n.º 2
0
mpcomplex mpcomplex::PI(const mp_prec_t &p, const mp_rnd_t &r) {
    mpfr_t pi;
    mpfr_t one;
    mpfr_init2(one, p);
    mpfr_set_ui(one , 1, r);
    
    mpfr_init2(pi, p);
    mpfr_atan(pi, one , r );
    mpfr_mul_ui( pi , pi , 4 , r);
    return mpcomplex( pi );
}
Ejemplo n.º 3
0
decimal r_atan(const decimal& a,bool round)
{
#ifdef USE_CGAL
	CGAL::Gmpfr m;
	CGAL::Gmpfr n=to_gmpfr(a);
	mpfr_atan(m.fr(),n.fr(),MPFR_RNDN);
	return r_round_preference(decimal(m),round);
#else
	return r_round_preference(atan(a),round);
#endif
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
knumber_base *knumber_float::atan() {

#ifdef KNUMBER_USE_MPFR
	mpfr_t mpfr;
	mpfr_init_set_f(mpfr, mpf_, rounding_mode);
	mpfr_atan(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< ::atan>(x);
	}
#endif
}
Ejemplo n.º 5
0
Archivo: tatan.c Proyecto: Canar/mpfr
/* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html
 * Incorrect flags (in debug mode on a 32-bit machine, assertion failure).
 */
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 (12, x, y, ex_y, (mpfr_ptr) 0);
    mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN);

    set_emin (-5);
    set_emax (-5);
    mpfr_clear_flags ();
    inex = mpfr_atan (y, x, MPFR_RNDN);
    flags = __gmpfr_flags;
    set_emin (emin);
    set_emax (emax);

    mpfr_set_str (ex_y, "0.1e-5", 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);
}
Ejemplo n.º 6
0
REAL _atan(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_atan(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;
}
Ejemplo n.º 7
0
void
arb_atan_arf_via_mpfr(arb_t z, const arf_t x, slong prec)
{
    mpfr_t t, u;
    int exact;

    mpfr_init2(t, 2 + arf_bits(x));
    mpfr_init2(u, prec);

    mpfr_set_emin(MPFR_EMIN_MIN);
    mpfr_set_emax(MPFR_EMAX_MAX);

    arf_get_mpfr(t, x, MPFR_RNDD);
    exact = (mpfr_atan(u, t, MPFR_RNDD) == 0);

    arf_set_mpfr(arb_midref(z), u);
    if (!exact)
        arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);

    mpfr_clear(t);
    mpfr_clear(u);
}
Ejemplo n.º 8
0
/// @brief atan keyword implementation
///
void program::rpn_atan(void) {
    MIN_ARGUMENTS(1);

    if (_stack->get_type(0) == cmd_number) {
        floating_t* left = &((number*)_stack->get_obj(0))->_value;
        CHECK_MPFR(mpfr_atan(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
    } else if (_stack->get_type(0) == cmd_complex) {
        number* num;
        complex* i;

        // atan(z)=0.5i(ln((1-iz)/(1+iz))
        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));

        stack::copy_and_push_back(_calc_stack, 0, *_stack);
        rpn_mul();
        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();  // iz-1
        rpn_neg();    // 1-iz
        rpn_dup();
        rpn_neg();  // iz-1
        num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
        CHECK_MPFR(mpfr_set_d(num->_value.mpfr, 2.0, floating_t::s_mpfr_rnd));
        rpn_plus();  // iz+1
        rpn_div();

        rpn_ln();
        CHECK_MPFR(mpfr_set_d(i->im()->mpfr, 0.5, floating_t::s_mpfr_rnd));
        stack::copy_and_push_back(_calc_stack, 0, *_stack);
        rpn_mul();

        _calc_stack.pop_back();
    } else
        ERR_CONTEXT(ret_bad_operand_type);
}
Ejemplo n.º 9
0
MpfrFloat MpfrFloat::atan(const MpfrFloat& value)
{
    MpfrFloat retval(MpfrFloat::kNoInitialization);
    mpfr_atan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
    return retval;
}
Ejemplo n.º 10
0
Archivo: tatan.c Proyecto: Canar/mpfr
static void
special (void)
{
    mpfr_t x, y, z;
    int r;
    int i;

    mpfr_init2 (x, 53);
    mpfr_init2 (y, 53);
    mpfr_init2 (z, 53);

    mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101");
    mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1");
    mpfr_atan (z, x, MPFR_RNDN);
    if (mpfr_cmp (y, z))
    {
        printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n");
        printf ("x=");
        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
        printf ("\nexpected ");
        mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
        printf ("\ngot      ");
        mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
        printf ("\n");
        exit (1);
    }

    /* atan(+Inf) = Pi/2 */
    for (r = 0; r < MPFR_RND_MAX ; r++)
    {
        mpfr_set_inf (x, 1);
        mpfr_atan (y, x, (mpfr_rnd_t) r);
        mpfr_const_pi (x, (mpfr_rnd_t) r);
        mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
        if (mpfr_cmp (x, y))
        {
            printf ("Error: mpfr_atan(+Inf), rnd=%s\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
            exit (1);
        }
    }

    /* atan(-Inf) = - Pi/2 */
    for (r = 0; r < MPFR_RND_MAX ; r++)
    {
        mpfr_set_inf (x, -1);
        mpfr_atan (y, x, (mpfr_rnd_t) r);
        mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
        mpfr_neg (x, x, (mpfr_rnd_t) r);
        mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
        if (mpfr_cmp (x, y))
        {
            printf ("Error: mpfr_atan(-Inf), rnd=%s\n",
                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
            exit (1);
        }
    }

    /* atan(NaN) = NaN */
    mpfr_set_nan (x);
    mpfr_atan (y, x, MPFR_RNDN);
    if (!mpfr_nan_p (y))
    {
        printf ("Error: mpfr_atan(NaN) <> NaN\n");
        exit (1);
    }

    /* atan(+/-0) = +/-0 */
    mpfr_set_ui (x, 0, MPFR_RNDN);
    MPFR_SET_NEG (y);
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
    {
        printf ("Error: mpfr_atan (+0) <> +0\n");
        exit (1);
    }
    mpfr_atan (x, x, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x))
    {
        printf ("Error: mpfr_atan (+0) <> +0 (in place)\n");
        exit (1);
    }
    mpfr_neg (x, x, MPFR_RNDN);
    MPFR_SET_POS (y);
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y))
    {
        printf ("Error: mpfr_atan (-0) <> -0\n");
        exit (1);
    }
    mpfr_atan (x, x, MPFR_RNDN);
    if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x))
    {
        printf ("Error: mpfr_atan (-0) <> -0 (in place)\n");
        exit (1);
    }

    mpfr_set_prec (x, 32);
    mpfr_set_prec (y, 32);

    /* test one random positive argument */
    mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
    mpfr_atan (x, x, MPFR_RNDN);
    mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1");
    if (mpfr_cmp (x, y))
    {
        printf ("Error in mpfr_atan (1)\n");
        exit (1);
    }

    /* test one random negative argument */
    mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
    mpfr_atan (x, x, MPFR_RNDN);
    mpfr_set_str_binary (y, "-0.101001110001010010110001110001");
    if (mpfr_cmp (x, y))
    {
        printf ("Error in mpfr_atan (2)\n");
        mpfr_print_binary (x);
        printf ("\n");
        mpfr_print_binary (y);
        printf ("\n");
        exit (1);
    }

    mpfr_set_prec (x, 3);
    mpfr_set_prec (y, 192);
    mpfr_set_prec (z, 192);
    mpfr_set_str_binary (x, "-0.100e1");
    mpfr_atan (z, x, MPFR_RNDD);
    mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101");
    if (mpfr_cmp (z, y))
    {
        printf ("Error in mpfr_atan (3)\n");
        printf ("Expected ");
        mpfr_print_binary (y);
        printf ("\n");
        printf ("Got      ");
        mpfr_print_binary (z);
        printf ("\n");
        exit (1);
    }

    /* Test regression */
    mpfr_set_prec (x, 51);
    mpfr_set_prec (y, 51);
    mpfr_set_str_binary (x,
                         "0.101100100000101111111010001111111000001000000000000E-11");
    i = mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y,
                      "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN)
            || i >= 0)
    {
        printf ("Wrong Regression test (%d)\n", i);
        mpfr_dump (y);
        exit (1);
    }

    mpfr_set_si (x, -1, MPFR_RNDN);
    mpfr_atan (x, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_NEG (x));

    /* Test regression */
    mpfr_set_prec (x, 48);
    mpfr_set_prec (y, 48);
    mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19");
    mpfr_atan (y, x, MPFR_RNDD);
    if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN))
    {
        printf ("Error in mpfr_atan (4)\n");
        printf ("Input    1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n");
        printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n");
        printf ("Got      ");
        mpfr_dump (y);
        exit (1);
    }

    mpfr_clear (x);
    mpfr_clear (y);
    mpfr_clear (z);
}
Ejemplo n.º 11
0
Archivo: tatan.c Proyecto: Canar/mpfr
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.101101010001001101111010E0");
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0",
                      2, MPFR_RNDN))
    {
        printf("Special Overflow error.\n");
        mpfr_dump (y);
        exit (1);
    }

    /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */
    set_emax (1);
    mpfr_set_inf (x, +1);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN)
            || mpfr_overflow_p ())
    {
        printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n",
               (long int) mpfr_get_emax ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+Inf) = Pi/2 underflows */
    set_emax (128);
    set_emin (3);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
    {
        printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */
    set_emax (1);
    set_emin (-128);
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN)
            || mpfr_overflow_p ())
    {
        printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n",
               (long int) mpfr_get_emax ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+1) = Pi/4 underflows and is rounded up to 1 */
    set_emax (128);
    set_emin (1);
    mpfr_set_prec (y, 2);
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDN);
    if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ())
    {
        printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    /* atan(+1) = Pi/4 underflows and is rounded down to 0 */
    mpfr_clear_flags ();
    mpfr_atan (y, x, MPFR_RNDD);
    if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
    {
        printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
               (long int) mpfr_get_emin ());
        mpfr_dump (y);
        exit (1);
    }

    mpfr_clear (y);
    mpfr_clear (x);
    set_emin (emin);
    set_emax (emax);
}
Ejemplo n.º 12
0
int
main (int argc, char *argv[])
{
  int n, prec, st, st2, N, i;
  mpfr_t x, y, z;
  
  if (argc != 2 && argc != 3)
    {
      fprintf(stderr, "Usage: timing digits \n");
      exit(1);
    }

  printf ("Using MPFR-%s with GMP-%s\n", mpfr_version, gmp_version);
  n = atoi(argv[1]);
  prec = (int) ( n * log(10.0) / log(2.0) + 1.0 );
  printf("[precision is %u bits]\n", prec);
 
  mpfr_init2(x, prec); mpfr_init2(y, prec); mpfr_init2(z, prec); 

  mpfr_set_d(x, 3.0, GMP_RNDN); mpfr_sqrt(x, x, GMP_RNDN); mpfr_sub_ui (x, x, 1, GMP_RNDN);
  mpfr_set_d(y, 5.0, GMP_RNDN); mpfr_sqrt(y, y, GMP_RNDN);

  mpfr_log (z, x, GMP_RNDN);

  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_mul(z, x, y, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("x*y        took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);

  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_mul(z, x, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("x*x        took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);

  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_div(z, x, y, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("x/y        took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_sqrt(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("sqrt(x)    took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_exp(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("exp(x)     took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_log(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("log(x)     took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_sin(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000); 	  
  printf("sin(x)     took %f ms (%d eval in %d ms)\n", 
	 (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_cos(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000);
  printf("cos(x)     took %f ms (%d eval in %d ms)\n",
         (double)(st2-st)/(N-1),N-1,st2-st);

  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_acos(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000);
  printf("arccos(x)  took %f ms (%d eval in %d ms)\n",
         (double)(st2-st)/(N-1),N-1,st2-st);
  
  N=1;  st = cputime();
  do {
    for (i=0;i<N;i++) mpfr_atan(z, x, GMP_RNDN);
    N=2*N;
    st2=cputime();
  } while (st2-st<1000);
  printf("arctan(x)  took %f ms (%d eval in %d ms)\n",
         (double)(st2-st)/(N-1),N-1,st2-st);

  mpfr_clear(x); mpfr_clear(y); mpfr_clear(z);
  return 0;
}
Ejemplo n.º 13
0
int
mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_t xp;
  int compared, inexact;
  mpfr_prec_t prec;
  mpfr_exp_t xp_exp;
  MPFR_SAVE_EXPO_DECL (expo);
  MPFR_ZIV_DECL (loop);

  MPFR_LOG_FUNC (
    ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
    ("asin[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (asin), mpfr_log_prec, asin,
     inexact));

  /* Special cases */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
        {
          MPFR_SET_NAN (asin);
          MPFR_RET_NAN;
        }
      else /* x = 0 */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (x));
          MPFR_SET_ZERO (asin);
          MPFR_SET_SAME_SIGN (asin, x);
          MPFR_RET (0); /* exact result */
        }
    }

  /* asin(x) = x + x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
  MPFR_FAST_COMPUTE_IF_SMALL_INPUT (asin, x, -2 * MPFR_GET_EXP (x), 2, 1,
                                    rnd_mode, {});

  /* Set x_p=|x| (x is a normal number) */
  mpfr_init2 (xp, MPFR_PREC (x));
  inexact = mpfr_abs (xp, x, MPFR_RNDN);
  MPFR_ASSERTD (inexact == 0);

  compared = mpfr_cmp_ui (xp, 1);

  MPFR_SAVE_EXPO_MARK (expo);

  if (MPFR_UNLIKELY (compared >= 0))
    {
      mpfr_clear (xp);
      if (compared > 0)                  /* asin(x) = NaN for |x| > 1 */
        {
          MPFR_SAVE_EXPO_FREE (expo);
          MPFR_SET_NAN (asin);
          MPFR_RET_NAN;
        }
      else                              /* x = 1 or x = -1 */
        {
          if (MPFR_IS_POS (x)) /* asin(+1) = Pi/2 */
            inexact = mpfr_const_pi (asin, rnd_mode);
          else /* asin(-1) = -Pi/2 */
            {
              inexact = -mpfr_const_pi (asin, MPFR_INVERT_RND(rnd_mode));
              MPFR_CHANGE_SIGN (asin);
            }
          mpfr_div_2ui (asin, asin, 1, rnd_mode);
        }
    }
  else
    {
      /* Compute exponent of 1 - ABS(x) */
      mpfr_ui_sub (xp, 1, xp, MPFR_RNDD);
      MPFR_ASSERTD (MPFR_GET_EXP (xp) <= 0);
      MPFR_ASSERTD (MPFR_GET_EXP (x) <= 0);
      xp_exp = 2 - MPFR_GET_EXP (xp);

      /* Set up initial prec */
      prec = MPFR_PREC (asin) + 10 + xp_exp;

      /* use asin(x) = atan(x/sqrt(1-x^2)) */
      MPFR_ZIV_INIT (loop, prec);
      for (;;)
        {
          mpfr_set_prec (xp, prec);
          mpfr_sqr (xp, x, MPFR_RNDN);
          mpfr_ui_sub (xp, 1, xp, MPFR_RNDN);
          mpfr_sqrt (xp, xp, MPFR_RNDN);
          mpfr_div (xp, x, xp, MPFR_RNDN);
          mpfr_atan (xp, xp, MPFR_RNDN);
          if (MPFR_LIKELY (MPFR_CAN_ROUND (xp, prec - xp_exp,
                                           MPFR_PREC (asin), rnd_mode)))
            break;
          MPFR_ZIV_NEXT (loop, prec);
        }
      MPFR_ZIV_FREE (loop);
      inexact = mpfr_set (asin, xp, rnd_mode);

      mpfr_clear (xp);
    }

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (asin, inexact, rnd_mode);
}
Ejemplo n.º 14
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("atan....");
    fflush(stdout);

    flint_randinit(state);

    /* Compare with MPFR */
    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        arb_t a, b;
        fmpq_t q;
        mpfr_t t;
        slong 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_atan(t, t, MPFR_RNDN);

        arb_atan(b, a, prec);

        if (!arb_contains_mpfr(b, t))
        {
            flint_printf("FAIL: containment\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_abort();
        }

        arb_atan(a, a, prec);

        if (!arb_equal(a, b))
        {
            flint_printf("FAIL: aliasing\n\n");
            flint_abort();
        }

        arb_clear(a);
        arb_clear(b);
        fmpq_clear(q);
        mpfr_clear(t);
    }

    /* Check large arguments. */
    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        arb_t a, b, c, d;
        slong prec1, prec2;

        prec1 = 2 + n_randint(state, 1000);
        prec2 = prec1 + 30;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arb_init(d);

        arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100);

        arb_atan(b, a, prec1);
        arb_atan(c, a, prec2);

        if (!arb_overlaps(b, c))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_printf("c = "); arb_print(c); flint_printf("\n\n");
            flint_abort();
        }

        /* check tan(atan(x)) = x */
        arb_sin_cos(c, d, b, prec1);
        arb_div(c, c, d, prec1);

        if (!arb_contains(c, a))
        {
            flint_printf("FAIL: functional equation\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_printf("c = "); arb_print(c); flint_printf("\n\n");
            flint_printf("d = "); arb_print(d); flint_printf("\n\n");
            flint_abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arb_clear(d);
    }

    /* Compare with MPFR, higher precision. */
    for (iter = 0; iter < 200 * arb_test_multiplier(); iter++)
    {
        arb_t a, b;
        fmpq_t q;
        mpfr_t t;
        slong prec = 2 + n_randint(state, 5000);

        arb_init(a);
        arb_init(b);
        fmpq_init(q);
        mpfr_init2(t, prec + 100);

        arb_randtest(a, state, 1 + n_randint(state, 5000), 8);
        arb_randtest(b, state, 1 + n_randint(state, 5000), 8);
        arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200));

        fmpq_get_mpfr(t, q, MPFR_RNDN);
        mpfr_atan(t, t, MPFR_RNDN);

        arb_atan(b, a, prec);

        if (!arb_contains_mpfr(b, t))
        {
            flint_printf("FAIL: containment\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("a = "); arb_printd(a, 50); flint_printf("\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_printd(b, 50); flint_printf("\n\n");
            flint_abort();
        }

        arb_atan(a, a, prec);

        if (!arb_equal(a, b))
        {
            flint_printf("FAIL: aliasing\n\n");
            flint_abort();
        }

        arb_clear(a);
        arb_clear(b);
        fmpq_clear(q);
        mpfr_clear(t);
    }

    /* Higher precision + large arguments. */
    for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++)
    {
        arb_t a, b, c, d;
        slong prec1, prec2;

        prec1 = 2 + n_randint(state, 5000);
        prec2 = prec1 + 30;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arb_init(d);

        arb_randtest_precise(a, state, 1 + n_randint(state, 5000), 100);

        arb_atan(b, a, prec1);
        arb_atan(c, a, prec2);

        if (!arb_overlaps(b, c))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_printf("c = "); arb_print(c); flint_printf("\n\n");
            flint_abort();
        }

        /* check tan(atan(x)) = x */
        arb_sin_cos(c, d, b, prec1);
        arb_div(c, c, d, prec1);

        if (!arb_contains(c, a))
        {
            flint_printf("FAIL: functional equation\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_printf("c = "); arb_print(c); flint_printf("\n\n");
            flint_printf("d = "); arb_print(d); flint_printf("\n\n");
            flint_abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arb_clear(d);
    }

    /* Check wide arguments. */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        arb_t a, b, c, d;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arb_init(d);

        arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100);
        arb_randtest_precise(b, state, 1 + n_randint(state, 1000), 100);
        if (n_randint(state, 2))
            arb_add(a, a, b, 2 + n_randint(state, 1000));
        arb_union(d, a, b, 2 + n_randint(state, 1000));

        arb_atan(a, a, 2 + n_randint(state, 2000));
        arb_atan(b, b, 2 + n_randint(state, 2000));
        arb_atan(c, d, 2 + n_randint(state, 2000));

        if (!arb_overlaps(c, a) || !arb_overlaps(c, b))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("d = "); arb_print(d); flint_printf("\n\n");
            flint_printf("a = "); arb_print(a); flint_printf("\n\n");
            flint_printf("b = "); arb_print(b); flint_printf("\n\n");
            flint_printf("c = "); arb_print(c); flint_printf("\n\n");
            flint_abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arb_clear(d);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Ejemplo n.º 15
0
Archivo: acos.c Proyecto: MiKTeX/miktex
int
mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_t xp, arcc, tmp;
  mpfr_exp_t supplement;
  mpfr_prec_t prec;
  int sign, compared, inexact;
  MPFR_SAVE_EXPO_DECL (expo);
  MPFR_ZIV_DECL (loop);

  MPFR_LOG_FUNC
    (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
     ("acos[%Pu]=%.*Rg inexact=%d",
      mpfr_get_prec(acos), mpfr_log_prec, acos, inexact));

  /* Singular cases */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
        {
          MPFR_SET_NAN (acos);
          MPFR_RET_NAN;
        }
      else /* necessarily x=0 */
        {
          MPFR_ASSERTD(MPFR_IS_ZERO(x));
          /* acos(0)=Pi/2 */
          MPFR_SAVE_EXPO_MARK (expo);
          inexact = mpfr_const_pi (acos, rnd_mode);
          mpfr_div_2ui (acos, acos, 1, rnd_mode); /* exact */
          MPFR_SAVE_EXPO_FREE (expo);
          return mpfr_check_range (acos, inexact, rnd_mode);
        }
    }

  /* Set x_p=|x| */
  sign = MPFR_SIGN (x);
  mpfr_init2 (xp, MPFR_PREC (x));
  mpfr_abs (xp, x, MPFR_RNDN); /* Exact */

  compared = mpfr_cmp_ui (xp, 1);

  if (MPFR_UNLIKELY (compared >= 0))
    {
      mpfr_clear (xp);
      if (compared > 0) /* acos(x) = NaN for x > 1 */
        {
          MPFR_SET_NAN(acos);
          MPFR_RET_NAN;
        }
      else
        {
          if (MPFR_IS_POS_SIGN (sign)) /* acos(+1) = +0 */
            return mpfr_set_ui (acos, 0, rnd_mode);
          else /* acos(-1) = Pi */
            return mpfr_const_pi (acos, rnd_mode);
        }
    }

  MPFR_SAVE_EXPO_MARK (expo);

  /* Compute the supplement */
  mpfr_ui_sub (xp, 1, xp, MPFR_RNDD);
  if (MPFR_IS_POS_SIGN (sign))
    supplement = 2 - 2 * MPFR_GET_EXP (xp);
  else
    supplement = 2 - MPFR_GET_EXP (xp);
  mpfr_clear (xp);

  prec = MPFR_PREC (acos);
  prec += MPFR_INT_CEIL_LOG2(prec) + 10 + supplement;

  /* VL: The following change concerning prec comes from r3145
     "Optimize mpfr_acos by choosing a better initial precision."
     but it doesn't seem to be correct and leads to problems (assertion
     failure or very important inefficiency) with tiny arguments.
     Therefore, I've disabled it. */
  /* If x ~ 2^-N, acos(x) ~ PI/2 - x - x^3/6
     If Prec < 2*N, we can't round since x^3/6 won't be counted. */
#if 0
  if (MPFR_PREC (acos) >= MPFR_PREC (x) && MPFR_GET_EXP (x) < 0)
    {
      mpfr_uexp_t pmin = (mpfr_uexp_t) (-2 * MPFR_GET_EXP (x)) + 5;
      MPFR_ASSERTN (pmin <= MPFR_PREC_MAX);
      if (prec < pmin)
        prec = pmin;
    }
#endif

  mpfr_init2 (tmp, prec);
  mpfr_init2 (arcc, prec);

  MPFR_ZIV_INIT (loop, prec);
  for (;;)
    {
      /* acos(x) = Pi/2 - asin(x) = Pi/2 - atan(x/sqrt(1-x^2)) */
      mpfr_sqr (tmp, x, MPFR_RNDN);
      mpfr_ui_sub (tmp, 1, tmp, MPFR_RNDN);
      mpfr_sqrt (tmp, tmp, MPFR_RNDN);
      mpfr_div (tmp, x, tmp, MPFR_RNDN);
      mpfr_atan (arcc, tmp, MPFR_RNDN);
      mpfr_const_pi (tmp, MPFR_RNDN);
      mpfr_div_2ui (tmp, tmp, 1, MPFR_RNDN);
      mpfr_sub (arcc, tmp, arcc, MPFR_RNDN);

      if (MPFR_LIKELY (MPFR_CAN_ROUND (arcc, prec - supplement,
                                       MPFR_PREC (acos), rnd_mode)))
        break;
      MPFR_ZIV_NEXT (loop, prec);
      mpfr_set_prec (tmp, prec);
      mpfr_set_prec (arcc, prec);
    }
  MPFR_ZIV_FREE (loop);

  inexact = mpfr_set (acos, arcc, rnd_mode);
  mpfr_clear (tmp);
  mpfr_clear (arcc);

  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (acos, inexact, rnd_mode);
}
Ejemplo n.º 16
0
 void bvisit(const ATan &x) {
     apply(result_, *(x.get_arg()));
     mpfr_atan(result_, result_, rnd_);
 }
Ejemplo n.º 17
0
int
mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpfr_t tmp, pi;
  int inexact;
  mpfr_prec_t prec;
  mpfr_exp_t e;
  MPFR_SAVE_EXPO_DECL (expo);
  MPFR_ZIV_DECL (loop);

  MPFR_LOG_FUNC
    (("y[%Pu]=%.*Rg x[%Pu]=%.*Rg rnd=%d",
      mpfr_get_prec (y), mpfr_log_prec, y,
      mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
     ("atan[%Pu]=%.*Rg inexact=%d",
      mpfr_get_prec (dest), mpfr_log_prec, dest, inexact));

  /* Special cases */
  if (MPFR_ARE_SINGULAR (x, y))
    {
      /* atan2(0, 0) does not raise the "invalid" floating-point
         exception, nor does atan2(y, 0) raise the "divide-by-zero"
         floating-point exception.
         -- atan2(±0, -0) returns ±pi.313)
         -- atan2(±0, +0) returns ±0.
         -- atan2(±0, x) returns ±pi, for x < 0.
         -- atan2(±0, x) returns ±0, for x > 0.
         -- atan2(y, ±0) returns -pi/2 for y < 0.
         -- atan2(y, ±0) returns pi/2 for y > 0.
         -- atan2(±oo, -oo) returns ±3pi/4.
         -- atan2(±oo, +oo) returns ±pi/4.
         -- atan2(±oo, x) returns ±pi/2, for finite x.
         -- atan2(±y, -oo) returns ±pi, for finite y > 0.
         -- atan2(±y, +oo) returns ±0, for finite y > 0.
      */
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y))
        {
          MPFR_SET_NAN (dest);
          MPFR_RET_NAN;
        }
      if (MPFR_IS_ZERO (y))
        {
          if (MPFR_IS_NEG (x)) /* +/- PI */
            {
            set_pi:
              if (MPFR_IS_NEG (y))
                {
                  inexact =  mpfr_const_pi (dest, MPFR_INVERT_RND (rnd_mode));
                  MPFR_CHANGE_SIGN (dest);
                  return -inexact;
                }
              else
                return mpfr_const_pi (dest, rnd_mode);
            }
          else /* +/- 0 */
            {
            set_zero:
              MPFR_SET_ZERO (dest);
              MPFR_SET_SAME_SIGN (dest, y);
              return 0;
            }
        }
      if (MPFR_IS_ZERO (x))
        {
          return pi_div_2ui (dest, 1, MPFR_IS_NEG (y), rnd_mode);
        }
      if (MPFR_IS_INF (y))
        {
          if (!MPFR_IS_INF (x)) /* +/- PI/2 */
            return pi_div_2ui (dest, 1, MPFR_IS_NEG (y), rnd_mode);
          else if (MPFR_IS_POS (x)) /* +/- PI/4 */
            return pi_div_2ui (dest, 2, MPFR_IS_NEG (y), rnd_mode);
          else /* +/- 3*PI/4: Ugly since we have to round properly */
            {
              mpfr_t tmp2;
              MPFR_ZIV_DECL (loop2);
              mpfr_prec_t prec2 = MPFR_PREC (dest) + 10;

              MPFR_SAVE_EXPO_MARK (expo);
              mpfr_init2 (tmp2, prec2);
              MPFR_ZIV_INIT (loop2, prec2);
              for (;;)
                {
                  mpfr_const_pi (tmp2, MPFR_RNDN);
                  mpfr_mul_ui (tmp2, tmp2, 3, MPFR_RNDN); /* Error <= 2  */
                  mpfr_div_2ui (tmp2, tmp2, 2, MPFR_RNDN);
                  if (mpfr_round_p (MPFR_MANT (tmp2), MPFR_LIMB_SIZE (tmp2),
                                    MPFR_PREC (tmp2) - 2,
                                    MPFR_PREC (dest) + (rnd_mode == MPFR_RNDN)))
                    break;
                  MPFR_ZIV_NEXT (loop2, prec2);
                  mpfr_set_prec (tmp2, prec2);
                }
              MPFR_ZIV_FREE (loop2);
              if (MPFR_IS_NEG (y))
                MPFR_CHANGE_SIGN (tmp2);
              inexact = mpfr_set (dest, tmp2, rnd_mode);
              mpfr_clear (tmp2);
              MPFR_SAVE_EXPO_FREE (expo);
              return mpfr_check_range (dest, inexact, rnd_mode);
            }
        }
      MPFR_ASSERTD (MPFR_IS_INF (x));
      if (MPFR_IS_NEG (x))
        goto set_pi;
      else
        goto set_zero;
    }

  /* When x is a power of two, we call directly atan(y/x) since y/x is
     exact. */
  if (MPFR_UNLIKELY (MPFR_IS_POWER_OF_2 (x)))
    {
      int r;
      mpfr_t yoverx;
      unsigned int saved_flags = __gmpfr_flags;

      mpfr_init2 (yoverx, MPFR_PREC (y));
      if (MPFR_LIKELY (mpfr_div_2si (yoverx, y, MPFR_GET_EXP (x) - 1,
                                     MPFR_RNDN) == 0))
        {
          /* Here the flags have not changed due to mpfr_div_2si. */
          r = mpfr_atan (dest, yoverx, rnd_mode);
          mpfr_clear (yoverx);
          return r;
        }
      else
        {
          /* Division is inexact because of a small exponent range */
          mpfr_clear (yoverx);
          __gmpfr_flags = saved_flags;
        }
    }

  MPFR_SAVE_EXPO_MARK (expo);

  /* Set up initial prec */
  prec = MPFR_PREC (dest) + 3 + MPFR_INT_CEIL_LOG2 (MPFR_PREC (dest));
  mpfr_init2 (tmp, prec);

  MPFR_ZIV_INIT (loop, prec);
  if (MPFR_IS_POS (x))
    /* use atan2(y,x) = atan(y/x) */
    for (;;)
      {
        int div_inex;
        MPFR_BLOCK_DECL (flags);

        MPFR_BLOCK (flags, div_inex = mpfr_div (tmp, y, x, MPFR_RNDN));
        if (div_inex == 0)
          {
            /* Result is exact. */
            inexact = mpfr_atan (dest, tmp, rnd_mode);
            goto end;
          }

        /* Error <= ulp (tmp) except in case of underflow or overflow. */

        /* If the division underflowed, since |atan(z)/z| < 1, we have
           an underflow. */
        if (MPFR_UNDERFLOW (flags))
          {
            int sign;

            /* In the case MPFR_RNDN with 2^(emin-2) < |y/x| < 2^(emin-1):
               The smallest significand value S > 1 of |y/x| is:
                 * 1 / (1 - 2^(-px))                        if py <= px,
                 * (1 - 2^(-px) + 2^(-py)) / (1 - 2^(-px))  if py >= px.
               Therefore S - 1 > 2^(-pz), where pz = max(px,py). We have:
               atan(|y/x|) > atan(z), where z = 2^(emin-2) * (1 + 2^(-pz)).
                           > z - z^3 / 3.
                           > 2^(emin-2) * (1 + 2^(-pz) - 2^(2 emin - 5))
               Assuming pz <= -2 emin + 5, we can round away from zero
               (this is what mpfr_underflow always does on MPFR_RNDN).
               In the case MPFR_RNDN with |y/x| <= 2^(emin-2), we round
               toward zero, as |atan(z)/z| < 1. */
            MPFR_ASSERTN (MPFR_PREC_MAX <=
                          2 * (mpfr_uexp_t) - MPFR_EMIN_MIN + 5);
            if (rnd_mode == MPFR_RNDN && MPFR_IS_ZERO (tmp))
              rnd_mode = MPFR_RNDZ;
            sign = MPFR_SIGN (tmp);
            mpfr_clear (tmp);
            MPFR_SAVE_EXPO_FREE (expo);
            return mpfr_underflow (dest, rnd_mode, sign);
          }

        mpfr_atan (tmp, tmp, MPFR_RNDN);   /* Error <= 2*ulp (tmp) since
                                             abs(D(arctan)) <= 1 */
        /* TODO: check that the error bound is correct in case of overflow. */
        /* FIXME: Error <= ulp(tmp) ? */
        if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - 2, MPFR_PREC (dest),
                                         rnd_mode)))
          break;
        MPFR_ZIV_NEXT (loop, prec);
        mpfr_set_prec (tmp, prec);
      }
  else /* x < 0 */
    /*  Use sign(y)*(PI - atan (|y/x|)) */
    {
      mpfr_init2 (pi, prec);
      for (;;)
        {
          mpfr_div (tmp, y, x, MPFR_RNDN);   /* Error <= ulp (tmp) */
          /* If tmp is 0, we have |y/x| <= 2^(-emin-2), thus
             atan|y/x| < 2^(-emin-2). */
          MPFR_SET_POS (tmp);               /* no error */
          mpfr_atan (tmp, tmp, MPFR_RNDN);   /* Error <= 2*ulp (tmp) since
                                               abs(D(arctan)) <= 1 */
          mpfr_const_pi (pi, MPFR_RNDN);     /* Error <= ulp(pi) /2 */
          e = MPFR_NOTZERO(tmp) ? MPFR_GET_EXP (tmp) : __gmpfr_emin - 1;
          mpfr_sub (tmp, pi, tmp, MPFR_RNDN);          /* see above */
          if (MPFR_IS_NEG (y))
            MPFR_CHANGE_SIGN (tmp);
          /* Error(tmp) <= (1/2+2^(EXP(pi)-EXP(tmp)-1)+2^(e-EXP(tmp)+1))*ulp
                        <= 2^(MAX (MAX (EXP(PI)-EXP(tmp)-1, e-EXP(tmp)+1),
                                        -1)+2)*ulp(tmp) */
          e = MAX (MAX (MPFR_GET_EXP (pi)-MPFR_GET_EXP (tmp) - 1,
                        e - MPFR_GET_EXP (tmp) + 1), -1) + 2;
          if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - e, MPFR_PREC (dest),
                                           rnd_mode)))
            break;
          MPFR_ZIV_NEXT (loop, prec);
          mpfr_set_prec (tmp, prec);
          mpfr_set_prec (pi, prec);
        }
      mpfr_clear (pi);
    }
  inexact = mpfr_set (dest, tmp, rnd_mode);

 end:
  MPFR_ZIV_FREE (loop);
  mpfr_clear (tmp);
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (dest, inexact, rnd_mode);
}
Ejemplo n.º 18
0
Archivo: asin.c Proyecto: mahdiz/mpclib
int
mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
  mpfr_t xp;
  mpfr_t arcs;

  int signe, suplement;

  mpfr_t tmp;
  int Prec;
  int prec_asin;
  int good = 0;
  int realprec;
  int estimated_delta;
  int compared; 

  /* Trivial cases */
  if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
    {
      MPFR_SET_NAN(asin);
      MPFR_RET_NAN;
    }

  /* Set x_p=|x| */
  signe = MPFR_SIGN(x);
  mpfr_init2 (xp, MPFR_PREC(x));
  mpfr_set (xp, x, rnd_mode);
  if (signe == -1)
    MPFR_CHANGE_SIGN(xp);

  compared = mpfr_cmp_ui (xp, 1);

  if (compared > 0) /* asin(x) = NaN for |x| > 1 */
    {
      MPFR_SET_NAN(asin);
      mpfr_clear (xp);
      MPFR_RET_NAN;
    }

  if (compared == 0) /* x = 1 or x = -1 */
    {
      if (signe > 0) /* asin(+1) = Pi/2 */
        mpfr_const_pi (asin, rnd_mode);
      else /* asin(-1) = -Pi/2 */
        {
          if (rnd_mode == GMP_RNDU)
            rnd_mode = GMP_RNDD;
          else if (rnd_mode == GMP_RNDD)
            rnd_mode = GMP_RNDU;
          mpfr_const_pi (asin, rnd_mode);
          mpfr_neg (asin, asin, rnd_mode);
        }
      MPFR_EXP(asin)--;
      mpfr_clear (xp);
      return 1; /* inexact */
    }

  if (MPFR_IS_ZERO(x)) /* x = 0 */
    {
      mpfr_set_ui (asin, 0, GMP_RNDN);
      mpfr_clear(xp);
      return 0; /* exact result */
    }

  prec_asin = MPFR_PREC(asin);
  mpfr_ui_sub (xp, 1, xp, GMP_RNDD);
  
  suplement = 2 - MPFR_EXP(xp);
#ifdef DEBUG
  printf("suplement=%d\n", suplement);
#endif
  realprec = prec_asin + 10;

  while (!good)
    {
      estimated_delta = 1 + suplement;
      Prec = realprec+estimated_delta;

      /* Initialisation    */
      mpfr_init2 (tmp, Prec);
      mpfr_init2 (arcs, Prec);

#ifdef DEBUG
      printf("Prec=%d\n", Prec);
      printf("              x=");
      mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
      printf ("\n");
#endif
      mpfr_mul (tmp, x, x, GMP_RNDN);
#ifdef DEBUG
      printf("            x^2=");
      mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
      printf ("\n");
#endif
      mpfr_ui_sub (tmp, 1, tmp, GMP_RNDN);
#ifdef DEBUG
      printf("          1-x^2=");
      mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
      printf ("\n");
      printf("10:          1-x^2=");
      mpfr_out_str (stdout, 10, 0, tmp, GMP_RNDN);
      printf ("\n");
#endif
      mpfr_sqrt (tmp, tmp, GMP_RNDN);
#ifdef DEBUG
      printf("  sqrt(1-x^2)=");
      mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
      printf ("\n");
      printf("10:  sqrt(1-x^2)=");
      mpfr_out_str (stdout, 10, 0, tmp, GMP_RNDN);
      printf ("\n");
#endif
      mpfr_div (tmp, x, tmp, GMP_RNDN);
#ifdef DEBUG
      printf("x/sqrt(1-x^2)=");
      mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
      printf ("\n");
#endif
      mpfr_atan (arcs, tmp, GMP_RNDN);
#ifdef DEBUG
      printf("atan(x/..x^2)=");
      mpfr_out_str (stdout, 2, 0, arcs, GMP_RNDN);
      printf ("\n");
#endif
      if (mpfr_can_round (arcs, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(asin)))
	{
	  mpfr_set (asin, arcs, rnd_mode);
#ifdef DEBUG
	  printf("asin         =");
	  mpfr_out_str (stdout, 2, prec_asin, asin, GMP_RNDN);
	  printf ("\n");
#endif
	  good = 1;
	}
      else
	{
	  realprec += _mpfr_ceil_log2 ((double) realprec);
#ifdef DEBUG
	  printf("RETRY\n");
#endif
	}
      mpfr_clear (tmp);
      mpfr_clear (arcs);
  }

  mpfr_clear (xp);

  return 1; /* inexact result */
}
Ejemplo n.º 19
0
int
mpc_atan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
{
    int s_re;
    int s_im;
    int inex_re;
    int inex_im;
    int inex;

    inex_re = 0;
    inex_im = 0;
    s_re = mpfr_signbit (mpc_realref (op));
    s_im = mpfr_signbit (mpc_imagref (op));

    /* special values */
    if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
    {
        if (mpfr_nan_p (mpc_realref (op)))
        {
            mpfr_set_nan (mpc_realref (rop));
            if (mpfr_zero_p (mpc_imagref (op)) || mpfr_inf_p (mpc_imagref (op)))
            {
                mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
                if (s_im)
                    mpc_conj (rop, rop, MPC_RNDNN);
            }
            else
                mpfr_set_nan (mpc_imagref (rop));
        }
        else
        {
            if (mpfr_inf_p (mpc_realref (op)))
            {
                inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
                mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
            }
            else
            {
                mpfr_set_nan (mpc_realref (rop));
                mpfr_set_nan (mpc_imagref (rop));
            }
        }
        return MPC_INEX (inex_re, 0);
    }

    if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
    {
        inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));

        mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
        if (s_im)
            mpc_conj (rop, rop, GMP_RNDN);

        return MPC_INEX (inex_re, 0);
    }

    /* pure real argument */
    if (mpfr_zero_p (mpc_imagref (op)))
    {
        inex_re = mpfr_atan (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));

        mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
        if (s_im)
            mpc_conj (rop, rop, GMP_RNDN);

        return MPC_INEX (inex_re, 0);
    }

    /* pure imaginary argument */
    if (mpfr_zero_p (mpc_realref (op)))
    {
        int cmp_1;

        if (s_im)
            cmp_1 = -mpfr_cmp_si (mpc_imagref (op), -1);
        else
            cmp_1 = mpfr_cmp_ui (mpc_imagref (op), +1);

        if (cmp_1 < 0)
        {
            /* atan(+0+iy) = +0 +i*atanh(y), if |y| < 1
               atan(-0+iy) = -0 +i*atanh(y), if |y| < 1 */

            mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
            if (s_re)
                mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN);

            inex_im = mpfr_atanh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
        }
        else if (cmp_1 == 0)
        {
            /* atan(+/-0+i) = NaN +i*inf
               atan(+/-0-i) = NaN -i*inf */
            mpfr_set_nan (mpc_realref (rop));
            mpfr_set_inf (mpc_imagref (rop), s_im ? -1 : +1);
        }
        else
        {
            /* atan(+0+iy) = +pi/2 +i*atanh(1/y), if |y| > 1
               atan(-0+iy) = -pi/2 +i*atanh(1/y), if |y| > 1 */
            mpfr_rnd_t rnd_im, rnd_away;
            mpfr_t y;
            mpfr_prec_t p, p_im;
            int ok;

            rnd_im = MPC_RND_IM (rnd);
            mpfr_init (y);
            p_im = mpfr_get_prec (mpc_imagref (rop));
            p = p_im;

            /* a = o(1/y)      with error(a) < 1 ulp(a)
               b = o(atanh(a)) with error(b) < (1+2^{1+Exp(a)-Exp(b)}) ulp(b)

               As |atanh (1/y)| > |1/y| we have Exp(a)-Exp(b) <=0 so, at most,
               2 bits of precision are lost.

               We round atanh(1/y) away from 0.
            */
            do
            {
                p += mpc_ceil_log2 (p) + 2;
                mpfr_set_prec (y, p);
                rnd_away = s_im == 0 ? GMP_RNDU : GMP_RNDD;
                inex_im = mpfr_ui_div (y, 1, mpc_imagref (op), rnd_away);
                /* FIXME: should we consider the case with unreasonably huge
                   precision prec(y)>3*exp_min, where atanh(1/Im(op)) could be
                   representable while 1/Im(op) underflows ?
                   This corresponds to |y| = 0.5*2^emin, in which case the
                   result may be wrong. */

                /* atanh cannot underflow: |atanh(x)| > |x| for |x| < 1 */
                inex_im |= mpfr_atanh (y, y, rnd_away);

                ok = inex_im == 0
                     || mpfr_can_round (y, p - 2, rnd_away, GMP_RNDZ,
                                        p_im + (rnd_im == GMP_RNDN));
            } while (ok == 0);

            inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
            inex_im = mpfr_set (mpc_imagref (rop), y, rnd_im);
            mpfr_clear (y);
        }
        return MPC_INEX (inex_re, inex_im);
    }

    /* regular number argument */
    {
        mpfr_t a, b, x, y;
        mpfr_prec_t prec, p;
        mpfr_exp_t err, expo;
        int ok = 0;
        mpfr_t minus_op_re;
        mpfr_exp_t op_re_exp, op_im_exp;
        mpfr_rnd_t rnd1, rnd2;

        mpfr_inits2 (MPFR_PREC_MIN, a, b, x, y, (mpfr_ptr) 0);

        /* real part: Re(arctan(x+i*y)) = [arctan2(x,1-y) - arctan2(-x,1+y)]/2 */
        minus_op_re[0] = mpc_realref (op)[0];
        MPFR_CHANGE_SIGN (minus_op_re);
        op_re_exp = mpfr_get_exp (mpc_realref (op));
        op_im_exp = mpfr_get_exp (mpc_imagref (op));

        prec = mpfr_get_prec (mpc_realref (rop)); /* result precision */

        /* a = o(1-y)         error(a) < 1 ulp(a)
           b = o(atan2(x,a))  error(b) < [1+2^{3+Exp(x)-Exp(a)-Exp(b)}] ulp(b)
                                         = kb ulp(b)
           c = o(1+y)         error(c) < 1 ulp(c)
           d = o(atan2(-x,c)) error(d) < [1+2^{3+Exp(x)-Exp(c)-Exp(d)}] ulp(d)
                                         = kd ulp(d)
           e = o(b - d)       error(e) < [1 + kb*2^{Exp(b}-Exp(e)}
                                            + kd*2^{Exp(d)-Exp(e)}] ulp(e)
                              error(e) < [1 + 2^{4+Exp(x)-Exp(a)-Exp(e)}
                                            + 2^{4+Exp(x)-Exp(c)-Exp(e)}] ulp(e)
                              because |atan(u)| < |u|
                                       < [1 + 2^{5+Exp(x)-min(Exp(a),Exp(c))
                                                 -Exp(e)}] ulp(e)
           f = e/2            exact
        */

        /* p: working precision */
        p = (op_im_exp > 0 || prec > SAFE_ABS (mpfr_prec_t, op_im_exp)) ? prec
            : (prec - op_im_exp);
        rnd1 = mpfr_sgn (mpc_realref (op)) > 0 ? GMP_RNDD : GMP_RNDU;
        rnd2 = mpfr_sgn (mpc_realref (op)) < 0 ? GMP_RNDU : GMP_RNDD;

        do
        {
            p += mpc_ceil_log2 (p) + 2;
            mpfr_set_prec (a, p);
            mpfr_set_prec (b, p);
            mpfr_set_prec (x, p);

            /* x = upper bound for atan (x/(1-y)). Since atan is increasing, we
               need an upper bound on x/(1-y), i.e., a lower bound on 1-y for
               x positive, and an upper bound on 1-y for x negative */
            mpfr_ui_sub (a, 1, mpc_imagref (op), rnd1);
            if (mpfr_sgn (a) == 0) /* y is near 1, thus 1+y is near 2, and
                                  expo will be 1 or 2 below */
            {
                MPC_ASSERT (mpfr_cmp_ui (mpc_imagref(op), 1) == 0);
                /* check for intermediate underflow */
                err = 2; /* ensures err will be expo below */
            }
            else
                err = mpfr_get_exp (a); /* err = Exp(a) with the notations above */
            mpfr_atan2 (x, mpc_realref (op), a, GMP_RNDU);

            /* b = lower bound for atan (-x/(1+y)): for x negative, we need a
               lower bound on -x/(1+y), i.e., an upper bound on 1+y */
            mpfr_add_ui (a, mpc_imagref(op), 1, rnd2);
            /* if a is exactly zero, i.e., Im(op) = -1, then the error on a is 0,
               and we can simply ignore the terms involving Exp(a) in the error */
            if (mpfr_sgn (a) == 0)
            {
                MPC_ASSERT (mpfr_cmp_si (mpc_imagref(op), -1) == 0);
                /* check for intermediate underflow */
                expo = err; /* will leave err unchanged below */
            }
            else
                expo = mpfr_get_exp (a); /* expo = Exp(c) with the notations above */
            mpfr_atan2 (b, minus_op_re, a, GMP_RNDD);

            err = err < expo ? err : expo; /* err = min(Exp(a),Exp(c)) */
            mpfr_sub (x, x, b, GMP_RNDU);

            err = 5 + op_re_exp - err - mpfr_get_exp (x);
            /* error is bounded by [1 + 2^err] ulp(e) */
            err = err < 0 ? 1 : err + 1;

            mpfr_div_2ui (x, x, 1, GMP_RNDU);

            /* Note: using RND2=RNDD guarantees that if x is exactly representable
               on prec + ... bits, mpfr_can_round will return 0 */
            ok = mpfr_can_round (x, p - err, GMP_RNDU, GMP_RNDD,
                                 prec + (MPC_RND_RE (rnd) == GMP_RNDN));
        } while (ok == 0);

        /* Imaginary part
           Im(atan(x+I*y)) = 1/4 * [log(x^2+(1+y)^2) - log (x^2 +(1-y)^2)] */
        prec = mpfr_get_prec (mpc_imagref (rop)); /* result precision */

        /* a = o(1+y)    error(a) < 1 ulp(a)
           b = o(a^2)    error(b) < 5 ulp(b)
           c = o(x^2)    error(c) < 1 ulp(c)
           d = o(b+c)    error(d) < 7 ulp(d)
           e = o(log(d)) error(e) < [1 + 7*2^{2-Exp(e)}] ulp(e) = ke ulp(e)
           f = o(1-y)    error(f) < 1 ulp(f)
           g = o(f^2)    error(g) < 5 ulp(g)
           h = o(c+f)    error(h) < 7 ulp(h)
           i = o(log(h)) error(i) < [1 + 7*2^{2-Exp(i)}] ulp(i) = ki ulp(i)
           j = o(e-i)    error(j) < [1 + ke*2^{Exp(e)-Exp(j)}
                                       + ki*2^{Exp(i)-Exp(j)}] ulp(j)
                         error(j) < [1 + 2^{Exp(e)-Exp(j)} + 2^{Exp(i)-Exp(j)}
                                       + 7*2^{3-Exp(j)}] ulp(j)
                                  < [1 + 2^{max(Exp(e),Exp(i))-Exp(j)+1}
                                       + 7*2^{3-Exp(j)}] ulp(j)
           k = j/4       exact
        */
        err = 2;
        p = prec; /* working precision */

        do
        {
            p += mpc_ceil_log2 (p) + err;
            mpfr_set_prec (a, p);
            mpfr_set_prec (b, p);
            mpfr_set_prec (y, p);

            /* a = upper bound for log(x^2 + (1+y)^2) */
            ROUND_AWAY (mpfr_add_ui (a, mpc_imagref (op), 1, MPFR_RNDA), a);
            mpfr_sqr (a, a, GMP_RNDU);
            mpfr_sqr (y, mpc_realref (op), GMP_RNDU);
            mpfr_add (a, a, y, GMP_RNDU);
            mpfr_log (a, a, GMP_RNDU);

            /* b = lower bound for log(x^2 + (1-y)^2) */
            mpfr_ui_sub (b, 1, mpc_imagref (op), GMP_RNDZ); /* round to zero */
            mpfr_sqr (b, b, GMP_RNDZ);
            /* we could write mpfr_sqr (y, mpc_realref (op), GMP_RNDZ) but it is
               more efficient to reuse the value of y (x^2) above and subtract
               one ulp */
            mpfr_nextbelow (y);
            mpfr_add (b, b, y, GMP_RNDZ);
            mpfr_log (b, b, GMP_RNDZ);

            mpfr_sub (y, a, b, GMP_RNDU);

            if (mpfr_zero_p (y))
                /* FIXME: happens when x and y have very different magnitudes;
                   could be handled more efficiently                           */
                ok = 0;
            else
            {
                expo = MPC_MAX (mpfr_get_exp (a), mpfr_get_exp (b));
                expo = expo - mpfr_get_exp (y) + 1;
                err = 3 - mpfr_get_exp (y);
                /* error(j) <= [1 + 2^expo + 7*2^err] ulp(j) */
                if (expo <= err) /* error(j) <= [1 + 2^{err+1}] ulp(j) */
                    err = (err < 0) ? 1 : err + 2;
                else
                    err = (expo < 0) ? 1 : expo + 2;

                mpfr_div_2ui (y, y, 2, GMP_RNDN);
                MPC_ASSERT (!mpfr_zero_p (y));
                /* FIXME: underflow. Since the main term of the Taylor series
                   in y=0 is 1/(x^2+1) * y, this means that y is very small
                   and/or x very large; but then the mpfr_zero_p (y) above
                   should be true. This needs a proof, or better yet,
                   special code.                                              */

                ok = mpfr_can_round (y, p - err, GMP_RNDU, GMP_RNDD,
                                     prec + (MPC_RND_IM (rnd) == GMP_RNDN));
            }
        } while (ok == 0);

        inex = mpc_set_fr_fr (rop, x, y, rnd);

        mpfr_clears (a, b, x, y, (mpfr_ptr) 0);
        return inex;
    }
}
Ejemplo n.º 20
0
 void bvisit(const ACot &x) {
     apply(result_, *(x.get_arg()));
     mpfr_ui_div(result_, 1, result_, rnd_);
     mpfr_atan(result_, result_, rnd_);
 }
Ejemplo n.º 21
0
	FixAtan2ByCORDIC::FixAtan2ByCORDIC(Target* target_, int wIn_, int wOut_, map<string, double> inputDelays_) :
 		FixAtan2(target_, wIn_, wOut_, inputDelays_)
	{
		int stage;
		srcFileName="FixAtan2ByCORDIC";
		setCopyrightString ( "Matei Istoan, Florent de Dinechin (2012-...)" );
		useNumericStd_Unsigned();

		ostringstream name;
		name << "FixAtan2ByCORDIC_" << wIn_ << "_" << wOut_ << "_uid" << getNewUId();
		setNameWithFreq( name.str() );
	
		mpfr_t  zatan; 
		mpfr_init2(zatan, 10*wOut);
	
		computeGuardBits();

		//Defining the various parameters according to method


		///////////// VHDL GENERATION
	
		/////////////////////////////////////////////////////////////////////////////
		// 
		//    First range reduction
		//
		/////////////////////////////////////////////////////////////////////////////

		buildQuadrantRangeReduction();

		// No scaling RR: just a copy
		vhdl << tab << declare("XRS", wIn-1) << " <=  XR;" << endl;
		vhdl << tab << declare("YRS", wIn-1) << " <=  YR;" << endl;
		
		int sizeZ=wOut-2+gA; // w-2 because two bits come from arg red 

		////////////////////////////////////////////////////////////////////////////
		// 
		//   	 CORDIC iterations	
		//
		////////////////////////////////////////////////////////////////////////////
		
		// Fixed-point considerations:
		// Y -> 0 and X -> K.sqrt(x1^2+y1^2)
		// Max value attained by X is sqrt(2)*K which is smaller than 2
		
		int zMSB=-1;      // -1 because these two bits have weight 0 and -1, but we must keep the sign
		int zLSB = zMSB-sizeZ+1;
		int sizeX = wIn+gXY;
		int sizeY = sizeX;
		
		
		vhdl << tab << declare("X1", sizeX) << " <= '0' & XRS & " << zg(sizeX-(wIn-1)-1) << ";" <<endl;			
		vhdl << tab << declare("Y1", sizeY) << " <= '0' & YRS & " << zg(sizeY-(wIn-1)-1) << ";" <<endl;			
		stage=1; 
 
		manageCriticalPath( getTarget()->adderDelay(sizeX));
		vhdl << tab << "--- Iteration " << stage << " : sign is known positive ---" << endl;
		vhdl << tab << declare(join("YShift", stage), sizeX) << " <= " << rangeAssign(sizeX-1, sizeX-stage, "'0'") << " & Y" << stage << range(sizeX-1, stage) << ";" << endl;
		vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " 
				 << join("X", stage) << " + " << join("YShift", stage) << " ;" << endl;
		
		vhdl << tab << declare(join("XShift", stage), sizeY) << " <= " << zg(stage) << " & X" << stage << range(sizeY-1, stage) << ";" <<endl;			
		vhdl << tab << declare(join("Y", stage+1), sizeY) << " <= " 
				 << join("Y", stage) << " - " << join("XShift", stage) << " ;" << endl;
		

		//create the constant signal for the arctan
		mpfr_set_d(zatan, 1.0, GMP_RNDN);
		mpfr_div_2si(zatan, zatan, stage, GMP_RNDN);
		mpfr_atan(zatan, zatan, GMP_RNDN);
		mpfr_div(zatan, zatan, constPi, GMP_RNDN);
		mpfr_t roundbit;
		mpfr_init2(roundbit, 30); // should be enough for anybody
		mpfr_set_d(roundbit, 1.0, GMP_RNDN);
		mpfr_div_2si(roundbit, roundbit, wOut, GMP_RNDN); // roundbit is in position 2^-wOut
		
		REPORT(DEBUG, "stage=" << stage << "  atancst=" << printMPFR(zatan));
		
		mpfr_add(zatan, zatan, roundbit, GMP_RNDN);
		vhdl << tab << declare("Z2", sizeZ) << " <= " << unsignedFixPointNumber(zatan, zMSB, zLSB) << "; -- initial atan, plus round bit" <<endl;
		

		for(stage=2; stage<=maxIterations;    stage++, sizeY--){
			// Invariant: sizeX-sizeY = stage-2
			vhdl << tab << "--- Iteration " << stage << " ---" << endl;
			
			manageCriticalPath( getTarget()->localWireDelay(sizeX+1) + getTarget()->adderDelay(max(sizeX,sizeZ)) );
			vhdl << tab << declare(join("sgnY", stage))  << " <= " <<  join("Y", stage)  <<  of(sizeY-1) << ";" << endl;
			
			if(-2*stage+1 >= -wIn+1-gXY) { 
				vhdl << tab << declare(join("YShift", stage), sizeX) 
						 << " <= " << rangeAssign(sizeX-1, sizeX -(sizeX-sizeY+stage), join("sgnY", stage))   
						 << " & Y" << stage << range(sizeY-1, stage) << ";" << endl;
				
				vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " 
						 << join("X", stage) << " - " << join("YShift", stage) << " when " << join("sgnY", stage) << "=\'1\'     else "
						 << join("X", stage) << " + " << join("YShift", stage) << " ;" << endl;
			}
			else {	// autant pisser dans un violon
				vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " << join("X", stage) << " ;" << endl;
			}
			
			vhdl << tab << declare(join("XShift", stage), sizeY) << " <= " << zg(2) << " & X" << stage << range(sizeX-1, sizeX - sizeY + 2) << ";" <<endl;			
			vhdl << tab << declare(join("YY", stage+1), sizeY) << " <= " 
					 << join("Y", stage) << " + " << join("XShift", stage) << " when " << join("sgnY", stage) << "=\'1\'     else "
					 << join("Y", stage) << " - " << join("XShift", stage) << " ;" << endl;
			vhdl << tab << declare(join("Y", stage+1), sizeY-1) << " <= " << join("YY", stage+1) << range(sizeY-2, 0) << ";" <<endl;
			
			
			//create the constant signal for the arctan
			mpfr_set_d(zatan, 1.0, GMP_RNDN);
			mpfr_div_2si(zatan, zatan, stage, GMP_RNDN);
			mpfr_atan(zatan, zatan, GMP_RNDN);
			mpfr_div(zatan, zatan, constPi, GMP_RNDN);
			REPORT(DEBUG, "stage=" << stage << "  atancst=" << printMPFR(zatan));		
			// rounding here in unsignedFixPointNumber()
			vhdl << tab << declare(join("atan2PowStage", stage), sizeZ) << " <= " << unsignedFixPointNumber(zatan, zMSB, zLSB) << ";" <<endl;
			vhdl << tab << declare(join("Z", stage+1), sizeZ) << " <= " 
					 << join("Z", stage) << " + " << join("atan2PowStage", stage) << " when " << join("sgnY", stage) << "=\'0\'      else "
					 << join("Z", stage) << " - " << join("atan2PowStage", stage) << " ;" << endl;
			
		} //end for loop
		
			// Give the time to finish the last rotation
			// manageCriticalPath( getTarget()->localWireDelay(w+1) + getTarget()->adderDelay(w+1) // actual CP delay
			//                     - (getTarget()->localWireDelay(sizeZ+1) + getTarget()->adderDelay(sizeZ+1))); // CP delay that was already added
		
		manageCriticalPath( getTarget()->localWireDelay(wOut+1) + getTarget()->adderDelay(2) );

		vhdl << tab << declare("finalZ", wOut) << " <= Z" << stage << of(sizeZ-1) << " & Z" << stage << range(sizeZ-1, sizeZ-wOut+1) << "; -- sign-extended and rounded" << endl;

		buildQuadrantReconstruction();
	};
Ejemplo n.º 22
0
CGAL::Gmpfr atan(const CGAL::Gmpfr &x)
{
    CGAL::Gmpfr result(0, gmp_result_precision(x));
    mpfr_atan(result.fr(), x.fr(), gmp_rounding_mode(CGAL::Gmpfr::get_default_rndmode()));
    return result;
}