diff --git a/doc/source/fmpcb.rst b/doc/source/fmpcb.rst index b3fd513a..a810d06d 100644 --- a/doc/source/fmpcb.rst +++ b/doc/source/fmpcb.rst @@ -151,6 +151,13 @@ Precision and comparisons Returns nonzero iff zero is contained in *x*. +.. function:: long fmpcb_bits(const fmpcb_t x) + + Returns the maximum of *fmprb_bits* applied to the real + and imaginary parts of *x*, i.e. the minimum precision sufficient + to represent *x* exactly. + + Complex parts ------------------------------------------------------------------------------- diff --git a/doc/source/fmpr.rst b/doc/source/fmpr.rst index 2816e333..66ce056b 100644 --- a/doc/source/fmpr.rst +++ b/doc/source/fmpr.rst @@ -298,6 +298,12 @@ Comparisons Sets *z* respectively to the minimum and the maximum of *a* and *b*. +.. function:: long fmpr_bits(const fmpr_t x) + + Returns the number of bits needed to represent the absolute value + of the mantissa of *x*, i.e. the minimum precision sufficient to represent + *x* exactly. Returns 0 if *x* is a special value. + Random number generation ------------------------------------------------------------------------------- @@ -321,8 +327,6 @@ Random number generation is set to an infinity or NaN. - - Input and output ------------------------------------------------------------------------------- diff --git a/doc/source/fmprb.rst b/doc/source/fmprb.rst index 51fcf54c..d4655745 100644 --- a/doc/source/fmprb.rst +++ b/doc/source/fmprb.rst @@ -321,6 +321,13 @@ Precision and comparisons Sets *z* to a ball containing both *x* and *y*. +.. function:: long fmprb_bits(const fmprb_t x) + + Returns the number of bits needed to represent the absolute value + of the mantissa of the midpoint of *x*, i.e. the minimum precision + sufficient to represent *x* exactly. Returns 0 if the midpoint + of *x* is a special value. + Arithmetic ------------------------------------------------------------------------------- diff --git a/fmpcb.h b/fmpcb.h index 80081325..66475651 100644 --- a/fmpcb.h +++ b/fmpcb.h @@ -691,4 +691,19 @@ void fmpcb_printd(const fmpcb_t z, long digits); void fmpcb_randtest(fmpcb_t z, flint_rand_t state, long prec, long mag_bits); +static __inline__ long +fmpcb_bits(const fmpcb_t x) +{ + long b1, b2; + b1 = fmprb_bits(fmpcb_realref(x)); + b2 = fmprb_bits(fmpcb_imagref(x)); + return FLINT_MAX(b1, b2); +} + +static __inline__ long +_fmpcb_vec_bits(const fmpcb_struct * vec, long len) +{ + return _fmprb_vec_bits((const fmprb_struct *) vec, 2 * len); +} + #endif diff --git a/fmpr.h b/fmpr.h index 0b7889b4..13b3aff2 100644 --- a/fmpr.h +++ b/fmpr.h @@ -562,6 +562,15 @@ fmpr_max(fmpr_t z, const fmpr_t a, const fmpr_t b) fmpr_set(z, b); } +static __inline__ long +fmpr_bits(const fmpr_t x) +{ + if (fmpr_is_special(x)) + return 0; + else + return fmpz_bits(fmpr_manref(x)); +} + #define CALL_MPFR_FUNC(r, func, y, x, prec, rnd) \ do { \ mpfr_t __t, __u; \ diff --git a/fmprb.h b/fmprb.h index 45691250..73b2897f 100644 --- a/fmprb.h +++ b/fmprb.h @@ -489,6 +489,12 @@ fmprb_rel_accuracy_bits(const fmprb_t x) return -fmprb_rel_error_bits(x); } +static __inline__ long +fmprb_bits(const fmprb_t x) +{ + return fmpr_bits(fmprb_midref(x)); +} + void fmprb_add_error_fmpr(fmprb_t x, const fmpr_t err); void fmprb_add_error_2exp_si(fmprb_t x, long err); void fmprb_add_error(fmprb_t x, const fmprb_t error); @@ -616,4 +622,19 @@ _fmprb_vec_get_abs_ubound_fmpr(fmpr_t bound, const fmprb_struct * vec, } } +static __inline__ long +_fmprb_vec_bits(const fmprb_struct * x, long len) +{ + long i, b, c; + + b = 0; + for (i = 0; i < len; i++) + { + c = fmprb_bits(x + i); + b = FLINT_MAX(b, c); + } + + return b; +} + #endif diff --git a/fmprb_poly/evaluate.c b/fmprb_poly/evaluate.c index 3d6a2ae9..d8483921 100644 --- a/fmprb_poly/evaluate.c +++ b/fmprb_poly/evaluate.c @@ -25,36 +25,14 @@ #include "fmprb_poly.h" -long -_fmprb_bits(const fmprb_t x) -{ - return fmpz_bits(fmpr_manref(fmprb_midref(x))); -} - -long -_fmprb_vec_bits(const fmprb_struct * x, long len) -{ - long i, b, c; - - b = 0; - for (i = 0; i < len; i++) - { - c = _fmprb_bits(x + i); - b = FLINT_MAX(b, c); - } - - return b; -} - void _fmprb_poly_evaluate(fmprb_t res, const fmprb_struct * f, long len, const fmprb_t x, long prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { - long fbits, xbits; + long fbits; - xbits = _fmprb_bits(x); fbits = _fmprb_vec_bits(f, len); if (fbits <= prec / 2) diff --git a/fmprb_poly/evaluate2.c b/fmprb_poly/evaluate2.c index bdbbfa2f..f56556cb 100644 --- a/fmprb_poly/evaluate2.c +++ b/fmprb_poly/evaluate2.c @@ -25,18 +25,13 @@ #include "fmprb_poly.h" -long _fmprb_bits(const fmprb_t x); - -long _fmprb_vec_bits(const fmprb_struct * x, long len); - void _fmprb_poly_evaluate2(fmprb_t y, fmprb_t z, const fmprb_struct * f, long len, const fmprb_t x, long prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { - long fbits, xbits; + long fbits; - xbits = _fmprb_bits(x); fbits = _fmprb_vec_bits(f, len); if (fbits <= prec / 2) diff --git a/gamma/rising_fmpcb_ui_bsplit.c b/gamma/rising_fmpcb_ui_bsplit.c index cf411f78..bdf00747 100644 --- a/gamma/rising_fmpcb_ui_bsplit.c +++ b/gamma/rising_fmpcb_ui_bsplit.c @@ -28,7 +28,7 @@ void gamma_rising_fmpcb_ui_bsplit(fmpcb_t y, const fmpcb_t x, ulong n, long prec) { - if (n < 8) + if (n < 8 || fmpcb_bits(x) < prec / 8) { gamma_rising_fmpcb_ui_bsplit_simple(y, x, n, prec); } diff --git a/gamma/rising_fmprb_ui_bsplit.c b/gamma/rising_fmprb_ui_bsplit.c index 2abaf4b0..0f851046 100644 --- a/gamma/rising_fmprb_ui_bsplit.c +++ b/gamma/rising_fmprb_ui_bsplit.c @@ -28,7 +28,7 @@ void gamma_rising_fmprb_ui_bsplit(fmprb_t y, const fmprb_t x, ulong n, long prec) { - if (prec < 768 || n < 8) + if (prec < 768 || n < 8 || fmprb_bits(x) < prec / 8) { gamma_rising_fmprb_ui_bsplit_simple(y, x, n, prec); }