void arb_sin_cos_pi(arb_t s, arb_t c, const arb_t x, long prec) { arb_t t; arb_t u; fmpz_t v; if (arf_cmpabs_2exp_si(arb_midref(x), FLINT_MAX(65536, (4*prec))) > 0) { arf_zero(arb_midref(s)); mag_one(arb_radref(s)); arf_zero(arb_midref(c)); mag_one(arb_radref(c)); return; } arb_init(t); arb_init(u); fmpz_init(v); arb_mul_2exp_si(t, x, 1); arf_get_fmpz(v, arb_midref(t), ARF_RND_NEAR); arb_sub_fmpz(t, t, v, prec); arb_const_pi(u, prec); arb_mul(t, t, u, prec); arb_mul_2exp_si(t, t, -1); switch (fmpz_fdiv_ui(v, 4)) { case 0: arb_sin_cos(s, c, t, prec); break; case 1: arb_sin_cos(c, s, t, prec); arb_neg(c, c); break; case 2: arb_sin_cos(s, c, t, prec); arb_neg(s, s); arb_neg(c, c); break; default: arb_sin_cos(c, s, t, prec); arb_neg(s, s); break; } fmpz_clear(v); arb_clear(t); arb_clear(u); }
int arb_get_unique_fmpz(fmpz_t z, const arb_t x) { if (!arb_is_finite(x)) { return 0; } else if (arb_is_exact(x)) { /* x = b*2^e, e >= 0 */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } else { return 0; } } /* if the radius is >= 1, there are at least two integers */ else if (mag_cmp_2exp_si(arb_radref(x), 0) >= 0) { return 0; } /* there are 0 or 1 integers if the radius is < 1 */ else { fmpz_t a, b, exp; int res; /* if the midpoint is exactly an integer, it is what we want */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } fmpz_init(a); fmpz_init(b); fmpz_init(exp); /* if the radius is tiny, it can't be an integer */ arf_bot(a, arb_midref(x)); if (fmpz_cmp(a, MAG_EXPREF(arb_radref(x))) > 0) { res = 0; } else { arb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { flint_printf("arb_get_unique_fmpz: input too large\n"); abort(); } if (*exp >= 0) { res = fmpz_equal(a, b); if (res) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } } else { fmpz_cdiv_q_2exp(a, a, -(*exp)); fmpz_fdiv_q_2exp(b, b, -(*exp)); res = fmpz_equal(a, b); } if (res) fmpz_set(z, a); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); return res; } }
int main() { slong iter; flint_rand_t state; flint_printf("get_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, x2; fmpz_t z, z2, e; int ret1, ret2; arf_init(x); arf_init(x2); fmpz_init(z); fmpz_init(z2); fmpz_init(e); arf_randtest(x, state, 2 + n_randint(state, 1000), 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); fmpz_randtest(z2, state, 1 + n_randint(state, 1000)); fmpz_randtest(e, state, 1 + n_randint(state, 200)); arf_mul_2exp_fmpz(x2, x, e); ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = arf_get_fmpz_fixed_fmpz(z2, x2, e); if (!fmpz_equal(z, z2) || (ret1 != ret2)) { flint_printf("FAIL (fixed_fmpz)\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("x2 = "); arf_print(x2); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(x2); fmpz_clear(z); fmpz_clear(z2); fmpz_clear(e); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, x2; fmpz_t z, z2; slong e; int ret1, ret2; arf_init(x); arf_init(x2); fmpz_init(z); fmpz_init(z2); arf_randtest(x, state, 2 + n_randint(state, 1000), 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); fmpz_randtest(z2, state, 1 + n_randint(state, 1000)); e = n_randtest(state); arf_mul_2exp_si(x2, x, e); ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = arf_get_fmpz_fixed_si(z2, x2, e); if (!fmpz_equal(z, z2) || (ret1 != ret2)) { flint_printf("FAIL (fixed_si)\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("x2 = "); arf_print(x2); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(x2); fmpz_clear(z); fmpz_clear(z2); } for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong bits; arf_t x; mpfr_t y; fmpz_t z, z2; mpz_t w; int ret1, ret2; bits = 2 + n_randint(state, 1000); arf_init(x); mpfr_init2(y, bits); fmpz_init(z); fmpz_init(z2); mpz_init(w); arf_randtest(x, state, bits, 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); arf_get_mpfr(y, x, MPFR_RNDN); switch (n_randint(state, 5)) { case 0: ret1 = arf_get_fmpz(z, x, ARF_RND_FLOOR); ret2 = mpfr_get_z(w, y, MPFR_RNDD); break; case 1: ret1 = arf_get_fmpz(z, x, ARF_RND_CEIL); ret2 = mpfr_get_z(w, y, MPFR_RNDU); break; case 2: ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = mpfr_get_z(w, y, MPFR_RNDZ); break; case 3: ret1 = arf_get_fmpz(z, x, ARF_RND_UP); ret2 = mpfr_get_z(w, y, MPFR_RNDA); break; default: ret1 = arf_get_fmpz(z, x, ARF_RND_NEAR); ret2 = mpfr_get_z(w, y, MPFR_RNDN); break; } fmpz_set_mpz(z2, w); if (!fmpz_equal(z, z2) || (ret1 != (ret2 != 0))) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); mpfr_clear(y); fmpz_clear(z); fmpz_clear(z2); mpz_clear(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }