static void testmul (long a, long b, long c, long d, mpfr_prec_t prec, mpc_rnd_t rnd) { mpc_t x, y; mpc_init2 (x, prec); mpc_init2 (y, prec); mpc_set_si_si (x, a, b, rnd); mpc_set_si_si (y, c, d, rnd); cmpmul (x, y, rnd); mpc_clear (x); mpc_clear (y); }
static void test_reuse (void) { mpc_t z; mpfr_t y; int inex; mpfr_init2 (y, 2); mpc_init2 (z, 2); mpc_set_si_si (z, 0, -1, MPC_RNDNN); mpfr_neg (mpc_realref (z), mpc_realref (z), MPFR_RNDN); mpc_div_2ui (z, z, 4, MPC_RNDNN); mpfr_set_ui (y, 512, MPFR_RNDN); inex = mpc_pow_fr (z, z, y, MPC_RNDNN); if (MPC_INEX_RE(inex) != 0 || MPC_INEX_IM(inex) != 0 || mpfr_cmp_ui_2exp (mpc_realref(z), 1, -2048) != 0 || mpfr_cmp_ui (mpc_imagref(z), 0) != 0 || mpfr_signbit (mpc_imagref(z)) == 0) { printf ("Error in test_reuse, wrong ternary value or output\n"); printf ("inex=(%d %d)\n", MPC_INEX_RE(inex), MPC_INEX_IM(inex)); printf ("z="); mpc_out_str (stdout, 2, 0, z, MPC_RNDNN); printf ("\n"); exit (1); } mpfr_clear (y); mpc_clear (z); }
int main (void) { mpc_t z, x; mp_prec_t prec; test_start (); mpc_init2 (z, 1000); mpc_init2 (x, 1000); check_file ("inp_str.dat"); for (prec = 2; prec <= 1000; prec+=7) { mpc_set_prec (z, prec); mpc_set_prec (x, prec); mpc_set_si_si (x, 1, 1, MPC_RNDNN); check_io_str (z, x); mpc_set_si_si (x, -1, 1, MPC_RNDNN); check_io_str (z, x); mpfr_set_inf (MPC_RE(x), -1); mpfr_set_inf (MPC_IM(x), +1); check_io_str (z, x); test_default_random (x, -1024, 1024, 128, 25); check_io_str (z, x); } #ifndef NO_STREAM_REDIRECTION mpc_set_si_si (x, 1, -4, MPC_RNDNN); mpc_div_ui (x, x, 3, MPC_RNDDU); check_stdout(z, x); #endif mpc_clear (z); mpc_clear (x); test_end (); return 0; }
static void testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd) { mpc_t x; mpc_init2 (x, prec); mpc_set_si_si (x, a, b, rnd); cmpsqr (x, rnd); mpc_clear (x); }
int main (void) { mpc_t z; test_start (); mpc_init2 (z, 11); mpc_set_ui_ui (z, 2, 3, MPC_RNDNN); mpc_pow_d (z, z, 3.0, MPC_RNDNN); if (mpc_cmp_si_si (z, -46, 9) != 0) { printf ("Error for mpc_pow_d (1)\n"); exit (1); } mpc_set_si_si (z, -3, 4, MPC_RNDNN); mpc_pow_d (z, z, 0.5, MPC_RNDNN); if (mpc_cmp_si_si (z, 1, 2) != 0) { printf ("Error for mpc_pow_d (2)\n"); exit (1); } mpc_set_ui_ui (z, 2, 3, MPC_RNDNN); mpc_pow_d (z, z, 6.0, MPC_RNDNN); if (mpc_cmp_si_si (z, 2035, -828) != 0) { printf ("Error for mpc_pow_d (3)\n"); exit (1); } mpc_clear (z); test_end (); return 0; }
/* put in rop the value of exp(2*i*pi*k/n) rounded according to rnd */ int mpc_rootofunity (mpc_ptr rop, unsigned long n, unsigned long k, mpc_rnd_t rnd) { unsigned long g; mpq_t kn; mpfr_t t, s, c; mpfr_prec_t prec; int inex_re, inex_im; mpfr_rnd_t rnd_re, rnd_im; if (n == 0) { /* Compute exp (0 + i*inf). */ mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); return MPC_INEX (0, 0); } /* Eliminate common denominator. */ k %= n; g = gcd (k, n); k /= g; n /= g; /* Now 0 <= k < n and gcd(k,n)=1. */ /* We assume that only n=1, 2, 3, 4, 6 and 12 may yield exact results and treat them separately; n=8 is also treated here for efficiency reasons. */ if (n == 1) { /* necessarily k=0 thus we want exp(0)=1 */ MPC_ASSERT (k == 0); return mpc_set_ui_ui (rop, 1, 0, rnd); } else if (n == 2) { /* since gcd(k,n)=1, necessarily k=1, thus we want exp(i*pi)=-1 */ MPC_ASSERT (k == 1); return mpc_set_si_si (rop, -1, 0, rnd); } else if (n == 4) { /* since gcd(k,n)=1, necessarily k=1 or k=3, thus we want exp(2*i*pi/4)=i or exp(2*i*pi*3/4)=-i */ MPC_ASSERT (k == 1 || k == 3); if (k == 1) return mpc_set_ui_ui (rop, 0, 1, rnd); else return mpc_set_si_si (rop, 0, -1, rnd); } else if (n == 3 || n == 6) { MPC_ASSERT ((n == 3 && (k == 1 || k == 2)) || (n == 6 && (k == 1 || k == 5))); /* for n=3, necessarily k=1 or k=2: -1/2+/-1/2*sqrt(3)*i; for n=6, necessarily k=1 or k=5: 1/2+/-1/2*sqrt(3)*i */ inex_re = mpfr_set_si (mpc_realref (rop), (n == 3 ? -1 : 1), MPC_RND_RE (rnd)); /* inverse the rounding mode for -sqrt(3)/2 for zeta_3^2 and zeta_6^5 */ rnd_im = MPC_RND_IM (rnd); if (k != 1) rnd_im = INV_RND (rnd_im); inex_im = mpfr_sqrt_ui (mpc_imagref (rop), 3, rnd_im); mpc_div_2ui (rop, rop, 1, MPC_RNDNN); if (k != 1) { mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), MPFR_RNDN); inex_im = -inex_im; } return MPC_INEX (inex_re, inex_im); } else if (n == 12) { /* necessarily k=1, 5, 7, 11: k=1: 1/2*sqrt(3) + 1/2*I k=5: -1/2*sqrt(3) + 1/2*I k=7: -1/2*sqrt(3) - 1/2*I k=11: 1/2*sqrt(3) - 1/2*I */ MPC_ASSERT (k == 1 || k == 5 || k == 7 || k == 11); /* inverse the rounding mode for -sqrt(3)/2 for zeta_12^5 and zeta_12^7 */ rnd_re = MPC_RND_RE (rnd); if (k == 5 || k == 7) rnd_re = INV_RND (rnd_re); inex_re = mpfr_sqrt_ui (mpc_realref (rop), 3, rnd_re); inex_im = mpfr_set_si (mpc_imagref (rop), k < 6 ? 1 : -1, MPC_RND_IM (rnd)); mpc_div_2ui (rop, rop, 1, MPC_RNDNN); if (k == 5 || k == 7) { mpfr_neg (mpc_realref (rop), mpc_realref (rop), MPFR_RNDN); inex_re = -inex_re; } return MPC_INEX (inex_re, inex_im); } else if (n == 8) { /* k=1, 3, 5 or 7: k=1: (1/2*I + 1/2)*sqrt(2) k=3: (1/2*I - 1/2)*sqrt(2) k=5: -(1/2*I + 1/2)*sqrt(2) k=7: -(1/2*I - 1/2)*sqrt(2) */ MPC_ASSERT (k == 1 || k == 3 || k == 5 || k == 7); rnd_re = MPC_RND_RE (rnd); if (k == 3 || k == 5) rnd_re = INV_RND (rnd_re); rnd_im = MPC_RND_IM (rnd); if (k > 4) rnd_im = INV_RND (rnd_im); inex_re = mpfr_sqrt_ui (mpc_realref (rop), 2, rnd_re); inex_im = mpfr_sqrt_ui (mpc_imagref (rop), 2, rnd_im); mpc_div_2ui (rop, rop, 1, MPC_RNDNN); if (k == 3 || k == 5) { mpfr_neg (mpc_realref (rop), mpc_realref (rop), MPFR_RNDN); inex_re = -inex_re; } if (k > 4) { mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), MPFR_RNDN); inex_im = -inex_im; } return MPC_INEX (inex_re, inex_im); } prec = MPC_MAX_PREC(rop); /* For the error analysis justifying the following algorithm, see algorithms.tex. */ mpfr_init2 (t, 67); mpfr_init2 (s, 67); mpfr_init2 (c, 67); mpq_init (kn); mpq_set_ui (kn, k, n); mpq_mul_2exp (kn, kn, 1); /* kn=2*k/n < 2 */ do { prec += mpc_ceil_log2 (prec) + 5; /* prec >= 6 */ mpfr_set_prec (t, prec); mpfr_set_prec (s, prec); mpfr_set_prec (c, prec); mpfr_const_pi (t, MPFR_RNDN); mpfr_mul_q (t, t, kn, MPFR_RNDN); mpfr_sin_cos (s, c, t, MPFR_RNDN); } while ( !mpfr_can_round (c, prec - (4 - mpfr_get_exp (c)), MPFR_RNDN, MPFR_RNDZ, MPC_PREC_RE(rop) + (MPC_RND_RE(rnd) == MPFR_RNDN)) || !mpfr_can_round (s, prec - (4 - mpfr_get_exp (s)), MPFR_RNDN, MPFR_RNDZ, MPC_PREC_IM(rop) + (MPC_RND_IM(rnd) == MPFR_RNDN))); inex_re = mpfr_set (mpc_realref(rop), c, MPC_RND_RE(rnd)); inex_im = mpfr_set (mpc_imagref(rop), s, MPC_RND_IM(rnd)); mpfr_clear (t); mpfr_clear (s); mpfr_clear (c); mpq_clear (kn); return MPC_INEX(inex_re, inex_im); }
int mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { mpc_t x, y; mpfr_prec_t prec; mpfr_exp_t err; int ok = 0; int inex; /* special values */ if (!mpc_fin_p (op)) { if (mpfr_nan_p (mpc_realref (op))) { if (mpfr_inf_p (mpc_imagref (op))) /* tan(NaN -i*Inf) = +/-0 -i */ /* tan(NaN +i*Inf) = +/-0 +i */ { /* exact unless 1 is not in exponent range */ inex = mpc_set_si_si (rop, 0, (MPFR_SIGN (mpc_imagref (op)) < 0) ? -1 : +1, rnd); } else /* tan(NaN +i*y) = NaN +i*NaN, when y is finite */ /* tan(NaN +i*NaN) = NaN +i*NaN */ { mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); inex = MPC_INEX (0, 0); /* always exact */ } } else if (mpfr_nan_p (mpc_imagref (op))) { if (mpfr_cmp_ui (mpc_realref (op), 0) == 0) /* tan(-0 +i*NaN) = -0 +i*NaN */ /* tan(+0 +i*NaN) = +0 +i*NaN */ { mpc_set (rop, op, rnd); inex = MPC_INEX (0, 0); /* always exact */ } else /* tan(x +i*NaN) = NaN +i*NaN, when x != 0 */ { mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); inex = MPC_INEX (0, 0); /* always exact */ } } else if (mpfr_inf_p (mpc_realref (op))) { if (mpfr_inf_p (mpc_imagref (op))) /* tan(-Inf -i*Inf) = -/+0 -i */ /* tan(-Inf +i*Inf) = -/+0 +i */ /* tan(+Inf -i*Inf) = +/-0 -i */ /* tan(+Inf +i*Inf) = +/-0 +i */ { const int sign_re = mpfr_signbit (mpc_realref (op)); int inex_im; mpfr_set_ui (mpc_realref (rop), 0, MPC_RND_RE (rnd)); mpfr_setsign (mpc_realref (rop), mpc_realref (rop), sign_re, MPFR_RNDN); /* exact, unless 1 is not in exponent range */ inex_im = mpfr_set_si (mpc_imagref (rop), mpfr_signbit (mpc_imagref (op)) ? -1 : +1, MPC_RND_IM (rnd)); inex = MPC_INEX (0, inex_im); } else /* tan(-Inf +i*y) = tan(+Inf +i*y) = NaN +i*NaN, when y is finite */ { mpfr_set_nan (mpc_realref (rop)); mpfr_set_nan (mpc_imagref (rop)); inex = MPC_INEX (0, 0); /* always exact */ } } else /* tan(x -i*Inf) = +0*sin(x)*cos(x) -i, when x is finite */ /* tan(x +i*Inf) = +0*sin(x)*cos(x) +i, when x is finite */ { mpfr_t c; mpfr_t s; int inex_im; mpfr_init (c); mpfr_init (s); mpfr_sin_cos (s, c, mpc_realref (op), MPFR_RNDN); mpfr_set_ui (mpc_realref (rop), 0, MPC_RND_RE (rnd)); mpfr_setsign (mpc_realref (rop), mpc_realref (rop), mpfr_signbit (c) != mpfr_signbit (s), MPFR_RNDN); /* exact, unless 1 is not in exponent range */ inex_im = mpfr_set_si (mpc_imagref (rop), (mpfr_signbit (mpc_imagref (op)) ? -1 : +1), MPC_RND_IM (rnd)); inex = MPC_INEX (0, inex_im); mpfr_clear (s); mpfr_clear (c); } return inex; } if (mpfr_zero_p (mpc_realref (op))) /* tan(-0 -i*y) = -0 +i*tanh(y), when y is finite. */ /* tan(+0 +i*y) = +0 +i*tanh(y), when y is finite. */ { int inex_im; mpfr_set (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd)); inex_im = mpfr_tanh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd)); return MPC_INEX (0, inex_im); } if (mpfr_zero_p (mpc_imagref (op))) /* tan(x -i*0) = tan(x) -i*0, when x is finite. */ /* tan(x +i*0) = tan(x) +i*0, when x is finite. */ { int inex_re; inex_re = mpfr_tan (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd)); mpfr_set (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd)); return MPC_INEX (inex_re, 0); } /* ordinary (non-zero) numbers */ /* tan(op) = sin(op) / cos(op). We use the following algorithm with rounding away from 0 for all operations, and working precision w: (1) x = A(sin(op)) (2) y = A(cos(op)) (3) z = A(x/y) the error on Im(z) is at most 81 ulp, the error on Re(z) is at most 7 ulp if k < 2, 8 ulp if k = 2, else 5+k ulp, where k = Exp(Re(x))+Exp(Re(y))-2min{Exp(Re(y)), Exp(Im(y))}-Exp(Re(x/y)) see proof in algorithms.tex. */ prec = MPC_MAX_PREC(rop); mpc_init2 (x, 2); mpc_init2 (y, 2); err = 7; do { mpfr_exp_t k, exr, eyr, eyi, ezr; ok = 0; /* FIXME: prevent addition overflow */ prec += mpc_ceil_log2 (prec) + err; mpc_set_prec (x, prec); mpc_set_prec (y, prec); /* rounding away from zero: except in the cases x=0 or y=0 (processed above), sin x and cos y are never exact, so rounding away from 0 is rounding towards 0 and adding one ulp to the absolute value */ mpc_sin_cos (x, y, op, MPC_RNDZZ, MPC_RNDZZ); MPFR_ADD_ONE_ULP (mpc_realref (x)); MPFR_ADD_ONE_ULP (mpc_imagref (x)); MPFR_ADD_ONE_ULP (mpc_realref (y)); MPFR_ADD_ONE_ULP (mpc_imagref (y)); MPC_ASSERT (mpfr_zero_p (mpc_realref (x)) == 0); if ( mpfr_inf_p (mpc_realref (x)) || mpfr_inf_p (mpc_imagref (x)) || mpfr_inf_p (mpc_realref (y)) || mpfr_inf_p (mpc_imagref (y))) { /* If the real or imaginary part of x is infinite, it means that Im(op) was large, in which case the result is sign(tan(Re(op)))*0 + sign(Im(op))*I, where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)). */ int inex_re, inex_im; mpfr_set_ui (mpc_realref (rop), 0, MPFR_RNDN); if (mpfr_sgn (mpc_realref (x)) * mpfr_sgn (mpc_realref (y)) < 0) { mpfr_neg (mpc_realref (rop), mpc_realref (rop), MPFR_RNDN); inex_re = 1; } else inex_re = -1; /* +0 is rounded down */ if (mpfr_sgn (mpc_imagref (op)) > 0) { mpfr_set_ui (mpc_imagref (rop), 1, MPFR_RNDN); inex_im = 1; } else { mpfr_set_si (mpc_imagref (rop), -1, MPFR_RNDN); inex_im = -1; } inex = MPC_INEX(inex_re, inex_im); goto end; } exr = mpfr_get_exp (mpc_realref (x)); eyr = mpfr_get_exp (mpc_realref (y)); eyi = mpfr_get_exp (mpc_imagref (y)); /* some parts of the quotient may be exact */ inex = mpc_div (x, x, y, MPC_RNDZZ); /* OP is no pure real nor pure imaginary, so in theory the real and imaginary parts of its tangent cannot be null. However due to rouding errors this might happen. Consider for example tan(1+14*I) = 1.26e-10 + 1.00*I. For small precision sin(op) and cos(op) differ only by a factor I, thus after mpc_div x = I and its real part is zero. */ if (mpfr_zero_p (mpc_realref (x)) || mpfr_zero_p (mpc_imagref (x))) { err = prec; /* double precision */ continue; } if (MPC_INEX_RE (inex)) MPFR_ADD_ONE_ULP (mpc_realref (x)); if (MPC_INEX_IM (inex)) MPFR_ADD_ONE_ULP (mpc_imagref (x)); MPC_ASSERT (mpfr_zero_p (mpc_realref (x)) == 0); ezr = mpfr_get_exp (mpc_realref (x)); /* FIXME: compute k = Exp(Re(x))+Exp(Re(y))-2min{Exp(Re(y)), Exp(Im(y))}-Exp(Re(x/y)) avoiding overflow */ k = exr - ezr + MPC_MAX(-eyr, eyr - 2 * eyi); err = k < 2 ? 7 : (k == 2 ? 8 : (5 + k)); /* Can the real part be rounded? */ ok = (!mpfr_number_p (mpc_realref (x))) || mpfr_can_round (mpc_realref(x), prec - err, MPFR_RNDN, MPFR_RNDZ, MPC_PREC_RE(rop) + (MPC_RND_RE(rnd) == MPFR_RNDN)); if (ok) { /* Can the imaginary part be rounded? */ ok = (!mpfr_number_p (mpc_imagref (x))) || mpfr_can_round (mpc_imagref(x), prec - 6, MPFR_RNDN, MPFR_RNDZ, MPC_PREC_IM(rop) + (MPC_RND_IM(rnd) == MPFR_RNDN)); } } while (ok == 0); inex = mpc_set (rop, x, rnd); end: mpc_clear (x); mpc_clear (y); return inex; }
static void check_set (void) { long int lo; mpz_t mpz; mpq_t mpq; mpf_t mpf; mpfr_t fr; mpc_t x, z; mpfr_prec_t prec; mpz_init (mpz); mpq_init (mpq); mpf_init2 (mpf, 1000); mpfr_init2 (fr, 1000); mpc_init2 (x, 1000); mpc_init2 (z, 1000); mpz_set_ui (mpz, 0x4217); mpq_set_si (mpq, -1, 0x4321); mpf_set_q (mpf, mpq); for (prec = 2; prec <= 1000; prec++) { unsigned long int u = (unsigned long int) prec; mpc_set_prec (z, prec); mpfr_set_prec (fr, prec); lo = -prec; mpfr_set_d (fr, 1.23456789, GMP_RNDN); mpc_set_d (z, 1.23456789, MPC_RNDNN); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_si (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_d", prec, z); #if defined _MPC_H_HAVE_COMPLEX mpc_set_dc (z, I*1.23456789+1.23456789, MPC_RNDNN); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0) PRINT_ERROR ("mpc_set_c", prec, z); #endif mpc_set_ui (z, u, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_ui", prec, z); mpc_set_d_d (z, 1.23456789, 1.23456789, MPC_RNDNN); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0) PRINT_ERROR ("mpc_set_d_d", prec, z); mpc_set_si (z, lo, MPC_RNDNN); if (mpfr_cmp_si (MPC_RE(z), lo) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_si", prec, z); mpfr_set_ld (fr, 1.23456789L, GMP_RNDN); mpc_set_ld_ld (z, 1.23456789L, 1.23456789L, MPC_RNDNN); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0) PRINT_ERROR ("mpc_set_ld_ld", prec, z); #if defined _MPC_H_HAVE_COMPLEX mpc_set_ldc (z, I*1.23456789L+1.23456789L, MPC_RNDNN); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0) PRINT_ERROR ("mpc_set_lc", prec, z); #endif mpc_set_ui_ui (z, u, u, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), u) != 0) PRINT_ERROR ("mpc_set_ui_ui", prec, z); mpc_set_ld (z, 1.23456789L, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_ld", prec, z); mpc_set_prec (x, prec); mpfr_set_ui(fr, 1, GMP_RNDN); mpfr_div_ui(fr, fr, 3, GMP_RNDN); mpfr_set(MPC_RE(x), fr, GMP_RNDN); mpfr_set(MPC_IM(x), fr, GMP_RNDN); mpc_set (z, x, MPC_RNDNN); mpfr_clear_flags (); /* mpc_cmp set erange flag when an operand is a NaN */ if (mpc_cmp (z, x) != 0 || mpfr_erangeflag_p()) { printf ("Error in mpc_set for prec = %lu\n", (unsigned long int) prec); MPC_OUT(z); MPC_OUT(x); exit (1); } mpc_set_si_si (z, lo, lo, MPC_RNDNN); if (mpfr_cmp_si (MPC_RE(z), lo) != 0 || mpfr_cmp_si (MPC_IM(z), lo) != 0) PRINT_ERROR ("mpc_set_si_si", prec, z); mpc_set_fr (z, fr, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_fr", prec, z); mpfr_set_z (fr, mpz, GMP_RNDN); mpc_set_z_z (z, mpz, mpz, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_z_z", prec, z); mpc_set_fr_fr (z, fr, fr, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_fr_fr", prec, z); mpc_set_z (z, mpz, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_z", prec, z); mpfr_set_q (fr, mpq, GMP_RNDN); mpc_set_q_q (z, mpq, mpq, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_q_q", prec, z); mpc_set_ui_fr (z, u, fr, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp_ui (MPC_RE (z), u) != 0 || mpfr_cmp (MPC_IM (z), fr) != 0 || mpfr_erangeflag_p ()) PRINT_ERROR ("mpc_set_ui_fr", prec, z); mpc_set_fr_ui (z, fr, u, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE (z), fr) != 0 || mpfr_cmp_ui (MPC_IM (z), u) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_fr_ui", prec, z); mpc_set_q (z, mpq, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_q", prec, z); mpfr_set_f (fr, mpf, GMP_RNDN); mpc_set_f_f (z, mpf, mpf, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp (MPC_IM(z), fr) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_f_f", prec, z); mpc_set_f (z, mpf, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE(z), fr) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0 || mpfr_erangeflag_p()) PRINT_ERROR ("mpc_set_f", prec, z); mpc_set_f_si (z, mpf, lo, MPC_RNDNN); mpfr_clear_flags (); if (mpfr_cmp (MPC_RE (z), fr) != 0 || mpfr_cmp_si (MPC_IM (z), lo) != 0 || mpfr_erangeflag_p ()) PRINT_ERROR ("mpc_set_f", prec, z); mpc_set_nan (z); if (!mpfr_nan_p (MPC_RE(z)) || !mpfr_nan_p (MPC_IM(z))) PRINT_ERROR ("mpc_set_nan", prec, z); #ifdef _MPC_H_HAVE_INTMAX_T { uintmax_t uim = (uintmax_t) prec; intmax_t im = (intmax_t) prec; mpc_set_uj (z, uim, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_uj", prec, z); mpc_set_sj (z, im, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_sj (1)", prec, z); mpc_set_uj_uj (z, uim, uim, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), u) != 0) PRINT_ERROR ("mpc_set_uj_uj", prec, z); mpc_set_sj_sj (z, im, im, MPC_RNDNN); if (mpfr_cmp_ui (MPC_RE(z), u) != 0 || mpfr_cmp_ui (MPC_IM(z), u) != 0) PRINT_ERROR ("mpc_set_sj_sj (1)", prec, z); im = LONG_MAX; if (sizeof (intmax_t) == 2 * sizeof (unsigned long)) im = 2 * im * im + 4 * im + 1; /* gives 2^(2n-1)-1 from 2^(n-1)-1 */ mpc_set_sj (z, im, MPC_RNDNN); if (mpfr_get_sj (MPC_RE(z), GMP_RNDN) != im || mpfr_cmp_ui (MPC_IM(z), 0) != 0) PRINT_ERROR ("mpc_set_sj (2)", im, z); mpc_set_sj_sj (z, im, im, MPC_RNDNN); if (mpfr_get_sj (MPC_RE(z), GMP_RNDN) != im || mpfr_get_sj (MPC_IM(z), GMP_RNDN) != im) PRINT_ERROR ("mpc_set_sj_sj (2)", im, z); } #endif /* _MPC_H_HAVE_INTMAX_T */ #if defined _MPC_H_HAVE_COMPLEX { double _Complex c = 1.0 - 2.0*I; long double _Complex lc = c; mpc_set_dc (z, c, MPC_RNDNN); if (mpc_get_dc (z, MPC_RNDNN) != c) PRINT_ERROR ("mpc_get_c", prec, z); mpc_set_ldc (z, lc, MPC_RNDNN); if (mpc_get_ldc (z, MPC_RNDNN) != lc) PRINT_ERROR ("mpc_get_lc", prec, z); } #endif } mpz_clear (mpz); mpq_clear (mpq); mpf_clear (mpf); mpfr_clear (fr); mpc_clear (x); mpc_clear (z); }