void arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec) { if (arb_is_zero(y)) { arb_one(z); return; } if (arb_is_zero(x)) { if (arb_is_positive(y)) arb_zero(z); else arb_indeterminate(z); return; } if (arb_is_exact(y) && !arf_is_special(arb_midref(x))) { const arf_struct * ymid = arb_midref(y); /* small half-integer or integer */ if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 && arf_is_int_2exp_si(ymid, -1)) { fmpz_t e; fmpz_init(e); if (arf_is_int(ymid)) { arf_get_fmpz_fixed_si(e, ymid, 0); arb_pow_fmpz_binexp(z, x, e, prec); } else { arf_get_fmpz_fixed_si(e, ymid, -1); arb_sqrt(z, x, prec + fmpz_bits(e)); arb_pow_fmpz_binexp(z, z, e, prec); } fmpz_clear(e); return; } else if (arf_is_int(ymid) && arf_sgn(arb_midref(x)) < 0) { /* use (-x)^n = (-1)^n * x^n to avoid NaNs at least at high enough precision */ int odd = !arf_is_int_2exp_si(ymid, 1); _arb_pow_exp(z, x, 1, y, prec); if (odd) arb_neg(z, z); return; } } _arb_pow_exp(z, x, 0, y, prec); }
void arf_ceil(arf_t z, const arf_t x) { if (arf_is_special(x) || arf_is_int(x)) { arf_set(z, x); } else { slong exp = ARF_EXP(x); /* now exp cannot be too large, as we would have caught this in arf_is_int() */ if (COEFF_IS_MPZ(exp) || exp <= 0) { if (ARF_SGNBIT(x)) arf_zero(z); else arf_one(z); } else if (exp == 1) { arf_set_si(z, ARF_SGNBIT(x) ? -1 : 2); } else { arf_set_round(z, x, exp, ARF_RND_CEIL); } } }
void acb_pow_arb(acb_t z, const acb_t x, const arb_t y, long prec) { const arf_struct * ymid = arb_midref(y); const mag_struct * yrad = arb_radref(y); if (arb_is_zero(y)) { acb_one(z); return; } if (mag_is_zero(yrad)) { /* small half-integer or integer */ if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 && arf_is_int_2exp_si(ymid, -1)) { fmpz_t e; fmpz_init(e); if (arf_is_int(ymid)) { arf_get_fmpz_fixed_si(e, ymid, 0); acb_pow_fmpz_binexp(z, x, e, prec); } else { /* hack: give something finite here (should fix sqrt/rsqrt etc) */ if (arb_contains_zero(acb_imagref(x)) && arb_contains_nonpositive(acb_realref(x))) { _acb_pow_arb_exp(z, x, y, prec); fmpz_clear(e); return; } arf_get_fmpz_fixed_si(e, ymid, -1); acb_sqrt(z, x, prec + fmpz_bits(e)); acb_pow_fmpz_binexp(z, z, e, prec); } fmpz_clear(e); return; } } _acb_pow_arb_exp(z, x, y, prec); }
int main() { slong iter; flint_rand_t state; flint_printf("is_int_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; fmpz_t t; slong e; int res1, res2; arf_init(x); arf_init(y); fmpz_init(t); arf_randtest_special(x, state, 2000, 100); e = n_randtest(state); arf_mul_2exp_si(y, x, e); res1 = arf_is_int(x); res2 = arf_is_int_2exp_si(y, e); if (res1 != res2) { flint_printf("FAIL! (1)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); abort(); } if (res1) { if (n_randint(state, 2)) arf_floor(y, x); else arf_ceil(y, x); if (!arf_equal(x, y) || !arf_is_finite(x)) { flint_printf("FAIL! (2)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d\n\n", res1); abort(); } } if (arf_is_finite(x) && !arf_is_zero(x)) { arf_bot(t, x); fmpz_neg(t, t); arf_mul_2exp_fmpz(x, x, t); res1 = arf_is_int(x); arf_mul_2exp_si(y, x, -1); res2 = arf_is_int(y); if (!arf_is_int(x) || arf_is_int(y)) { flint_printf("FAIL! (3)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); abort(); } } arf_clear(x); arf_clear(y); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
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("floor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { arf_t x, y; int result; arf_init(x); arf_init(y); arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_floor(y, x); result = 1; if (arf_is_int(x) || !arf_is_finite(x)) { result = arf_equal(y, x); } else if (!arf_is_int(y)) { result = 0; } else if (arf_cmp(y, x) >= 0) { result = 0; } else { arf_t s, t[3]; /* check floor(x) - x + 1 > 0 */ arf_init(s); arf_init(t[0]); arf_init(t[1]); arf_init(t[2]); arf_set(t[0], y); arf_neg(t[1], x); arf_one(t[2]); arf_sum(s, (arf_ptr) t, 3, 32, ARF_RND_DOWN); result = arf_sgn(s) > 0; arf_clear(s); arf_clear(t[0]); arf_clear(t[1]); arf_clear(t[2]); } if (!result) { flint_printf("FAIL!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); abort(); } arf_floor(x, x); if (!arf_equal(x, y)) { flint_printf("FAIL (aliasing)!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }