File indexing completed on 2026-11-07 10:15:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ARF_H
0013 #define ARF_H
0014
0015 #ifdef ARF_INLINES_C
0016 #define ARF_INLINE
0017 #else
0018 #define ARF_INLINE static inline
0019 #endif
0020
0021 #include <gmp.h>
0022 #include "longlong.h"
0023 #include "mag.h"
0024 #include "arf_types.h"
0025
0026 #ifdef __cplusplus
0027 extern "C" {
0028 #endif
0029
0030 typedef enum
0031 {
0032 ARF_RND_DOWN = 0,
0033 ARF_RND_UP = 1,
0034 ARF_RND_FLOOR = 2,
0035 ARF_RND_CEIL = 3,
0036 ARF_RND_NEAR = 4
0037 }
0038 arf_rnd_t;
0039
0040 ARF_INLINE int
0041 arf_rounds_down(arf_rnd_t rnd, int sgnbit)
0042 {
0043 if (rnd == ARF_RND_DOWN) return 1;
0044 if (rnd == ARF_RND_UP) return 0;
0045 if (rnd == ARF_RND_FLOOR) return !sgnbit;
0046 return sgnbit;
0047 }
0048
0049 ARF_INLINE int
0050 arf_rounds_up(arf_rnd_t rnd, int sgnbit)
0051 {
0052 if (rnd == ARF_RND_DOWN) return 0;
0053 if (rnd == ARF_RND_UP) return 1;
0054 if (rnd == ARF_RND_FLOOR) return sgnbit;
0055 return !sgnbit;
0056 }
0057
0058 #ifdef __MPFR_H
0059 ARF_INLINE mpfr_rnd_t
0060 arf_rnd_to_mpfr(arf_rnd_t rnd)
0061 {
0062 if (rnd == ARF_RND_DOWN) return MPFR_RNDZ;
0063 else if (rnd == ARF_RND_UP) return MPFR_RNDA;
0064 else if (rnd == ARF_RND_FLOOR) return MPFR_RNDD;
0065 else if (rnd == ARF_RND_CEIL) return MPFR_RNDU;
0066 else return MPFR_RNDN;
0067 }
0068 #endif
0069
0070
0071 #define ARF_PREC_EXACT WORD_MAX
0072
0073 #define ARF_PREC_ADD(prec,extra) ((prec) == ARF_PREC_EXACT ? ARF_PREC_EXACT : (prec) + (extra))
0074
0075 #define ARF_RESULT_EXACT 0
0076 #define ARF_RESULT_INEXACT 1
0077
0078
0079 #define ARF_MAX_LAGOM_EXP MAG_MAX_LAGOM_EXP
0080 #define ARF_MIN_LAGOM_EXP MAG_MIN_LAGOM_EXP
0081
0082
0083 #define ARF_EXP_ZERO 0
0084 #define ARF_EXP_NAN COEFF_MIN
0085 #define ARF_EXP_POS_INF (COEFF_MIN+1)
0086 #define ARF_EXP_NEG_INF (COEFF_MIN+2)
0087
0088
0089 #define ARF_EXP(x) ((x)->exp)
0090 #define ARF_EXPREF(x) (&(x)->exp)
0091
0092
0093 #define ARF_IS_LAGOM(x) (ARF_EXP(x) >= ARF_MIN_LAGOM_EXP && \
0094 ARF_EXP(x) <= ARF_MAX_LAGOM_EXP)
0095
0096
0097 #define ARF_HAS_PTR(x) ((x)->size > ((2 << 1) + 1))
0098
0099
0100 #define ARF_XSIZE(x) ((x)->size)
0101
0102
0103 #define ARF_MAKE_XSIZE(size, sgnbit) ((((slong) size) << 1) | (sgnbit))
0104
0105
0106 #define ARF_SIZE(x) (ARF_XSIZE(x) >> 1)
0107 #define ARF_SGNBIT(x) (ARF_XSIZE(x) & 1)
0108
0109
0110 #define ARF_NEG(x) (ARF_XSIZE(x) ^= 1)
0111
0112
0113 #define ARF_NOPTR_D(x) ((x)->d.noptr.d)
0114 #define ARF_PTR_D(x) ((x)->d.ptr.d)
0115 #define ARF_PTR_ALLOC(x) ((x)->d.ptr.alloc)
0116
0117
0118 #define ARF_IS_SPECIAL(x) (ARF_XSIZE(x) == 0)
0119
0120
0121 #define ARF_IS_POW2(x) (ARF_SIZE(x) == 1) && (ARF_NOPTR_D(x)[0] == LIMB_TOP)
0122
0123
0124 #define ARF_MAKE_SPECIAL(x) \
0125 do { \
0126 fmpz_clear(ARF_EXPREF(x)); \
0127 ARF_DEMOTE(x); \
0128 ARF_XSIZE(x) = 0; \
0129 } while (0)
0130
0131
0132 void _arf_promote(arf_t x, slong n);
0133
0134 void _arf_demote(arf_t x);
0135
0136
0137
0138 #define ARF_DEMOTE(x) \
0139 do { \
0140 if (ARF_HAS_PTR(x)) \
0141 _arf_demote(x); \
0142 } while (0)
0143
0144
0145 #define ARF_GET_MPN_READONLY(xptr, xn, x) \
0146 do { \
0147 xn = ARF_SIZE(x); \
0148 if (xn <= ARF_NOPTR_LIMBS) \
0149 xptr = ARF_NOPTR_D(x); \
0150 else \
0151 xptr = ARF_PTR_D(x); \
0152 } while (0)
0153
0154
0155 #define ARF_GET_TOP_LIMB(lmb, x) \
0156 do { \
0157 nn_srcptr __xptr; \
0158 slong __xn; \
0159 ARF_GET_MPN_READONLY(__xptr, __xn, (x)); \
0160 (lmb) = __xptr[__xn - 1]; \
0161 } while (0)
0162
0163
0164 #define ARF_GET_MPN_WRITE(xptr, xn, x) \
0165 do { \
0166 slong __xn = (xn); \
0167 if ((__xn) <= ARF_NOPTR_LIMBS) \
0168 { \
0169 ARF_DEMOTE(x); \
0170 xptr = ARF_NOPTR_D(x); \
0171 } \
0172 else \
0173 { \
0174 if (!ARF_HAS_PTR(x)) \
0175 { \
0176 _arf_promote(x, __xn); \
0177 } \
0178 else if (ARF_PTR_ALLOC(x) < (__xn)) \
0179 { \
0180 ARF_PTR_D(x) = (nn_ptr) \
0181 flint_realloc(ARF_PTR_D(x), \
0182 (xn) * sizeof(ulong)); \
0183 ARF_PTR_ALLOC(x) = (__xn); \
0184 } \
0185 xptr = ARF_PTR_D(x); \
0186 } \
0187 ARF_XSIZE(x) = ARF_MAKE_XSIZE(__xn, 0); \
0188 } while (0)
0189
0190 ARF_INLINE void
0191 arf_init(arf_t x)
0192 {
0193 fmpz_init(ARF_EXPREF(x));
0194 ARF_XSIZE(x) = 0;
0195 }
0196
0197 void arf_clear(arf_t x);
0198
0199 arf_ptr _arf_vec_init(slong n);
0200 void _arf_vec_clear(arf_ptr v, slong n);
0201
0202 ARF_INLINE void
0203 arf_zero(arf_t x)
0204 {
0205 ARF_MAKE_SPECIAL(x);
0206 ARF_EXP(x) = ARF_EXP_ZERO;
0207 }
0208
0209 ARF_INLINE void
0210 arf_pos_inf(arf_t x)
0211 {
0212 ARF_MAKE_SPECIAL(x);
0213 ARF_EXP(x) = ARF_EXP_POS_INF;
0214 }
0215
0216 ARF_INLINE void
0217 arf_neg_inf(arf_t x)
0218 {
0219 ARF_MAKE_SPECIAL(x);
0220 ARF_EXP(x) = ARF_EXP_NEG_INF;
0221 }
0222
0223 ARF_INLINE void
0224 arf_nan(arf_t x)
0225 {
0226 ARF_MAKE_SPECIAL(x);
0227 ARF_EXP(x) = ARF_EXP_NAN;
0228 }
0229
0230 ARF_INLINE int
0231 arf_is_special(const arf_t x)
0232 {
0233 return ARF_IS_SPECIAL(x);
0234 }
0235
0236 ARF_INLINE int
0237 arf_is_zero(const arf_t x)
0238 {
0239 return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_ZERO);
0240 }
0241
0242 ARF_INLINE int
0243 arf_is_pos_inf(const arf_t x)
0244 {
0245 return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_POS_INF);
0246 }
0247
0248 ARF_INLINE int
0249 arf_is_neg_inf(const arf_t x)
0250 {
0251 return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_NEG_INF);
0252 }
0253
0254 ARF_INLINE int
0255 arf_is_nan(const arf_t x)
0256 {
0257 return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_NAN);
0258 }
0259
0260 ARF_INLINE int
0261 arf_is_normal(const arf_t x)
0262 {
0263 return !ARF_IS_SPECIAL(x);
0264 }
0265
0266 ARF_INLINE int
0267 arf_is_finite(const arf_t x)
0268 {
0269 return !ARF_IS_SPECIAL(x) || (ARF_EXP(x) == ARF_EXP_ZERO);
0270 }
0271
0272 ARF_INLINE int
0273 arf_is_inf(const arf_t x)
0274 {
0275 return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_POS_INF ||
0276 ARF_EXP(x) == ARF_EXP_NEG_INF);
0277 }
0278
0279 ARF_INLINE void
0280 arf_one(arf_t x)
0281 {
0282 fmpz_clear(ARF_EXPREF(x));
0283 ARF_DEMOTE(x);
0284 ARF_EXP(x) = 1;
0285 ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0);
0286 ARF_NOPTR_D(x)[0] = LIMB_TOP;
0287 }
0288
0289 ARF_INLINE int
0290 arf_is_one(const arf_t x)
0291 {
0292 return (ARF_EXP(x) == 1) && (ARF_XSIZE(x) == ARF_MAKE_XSIZE(1, 0))
0293 && ARF_NOPTR_D(x)[0] == LIMB_TOP;
0294 }
0295
0296 ARF_INLINE int
0297 arf_sgn(const arf_t x)
0298 {
0299 if (arf_is_special(x))
0300 {
0301 if (arf_is_zero(x) || arf_is_nan(x))
0302 return 0;
0303 return arf_is_pos_inf(x) ? 1 : -1;
0304 }
0305 else
0306 {
0307 return ARF_SGNBIT(x) ? -1 : 1;
0308 }
0309 }
0310
0311 int arf_cmp(const arf_t x, const arf_t y);
0312
0313 int arf_cmpabs(const arf_t x, const arf_t y);
0314
0315 int arf_cmpabs_ui(const arf_t x, ulong y);
0316
0317 int arf_cmpabs_d(const arf_t x, double y);
0318
0319 int arf_cmp_si(const arf_t x, slong y);
0320
0321 int arf_cmp_ui(const arf_t x, ulong y);
0322
0323 int arf_cmp_d(const arf_t x, double y);
0324
0325 ARF_INLINE void
0326 arf_swap(arf_t y, arf_t x)
0327 {
0328 FLINT_SWAP(arf_struct, *x, *y);
0329 }
0330
0331 void arf_set(arf_t y, const arf_t x);
0332
0333 ARF_INLINE void
0334 arf_neg(arf_t y, const arf_t x)
0335 {
0336 arf_set(y, x);
0337
0338 if (arf_is_special(y))
0339 {
0340 if (arf_is_pos_inf(y))
0341 arf_neg_inf(y);
0342 else if (arf_is_neg_inf(y))
0343 arf_pos_inf(y);
0344 }
0345 else
0346 {
0347 ARF_NEG(y);
0348 }
0349 }
0350
0351 ARF_INLINE void
0352 arf_init_set_ui(arf_t x, ulong v)
0353 {
0354 if (v == 0)
0355 {
0356 ARF_EXP(x) = ARF_EXP_ZERO;
0357 ARF_XSIZE(x) = 0;
0358 }
0359 else
0360 {
0361 unsigned int c;
0362 c = flint_clz(v);
0363 ARF_EXP(x) = FLINT_BITS - c;
0364 ARF_NOPTR_D(x)[0] = v << c;
0365 ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0);
0366 }
0367 }
0368
0369 ARF_INLINE void
0370 arf_init_set_si(arf_t x, slong v)
0371 {
0372 arf_init_set_ui(x, FLINT_UABS(v));
0373 if (v < 0)
0374 ARF_NEG(x);
0375 }
0376
0377 ARF_INLINE void
0378 arf_set_ui(arf_t x, ulong v)
0379 {
0380 ARF_DEMOTE(x);
0381 _fmpz_demote(ARF_EXPREF(x));
0382
0383 if (v == 0)
0384 {
0385 ARF_EXP(x) = ARF_EXP_ZERO;
0386 ARF_XSIZE(x) = 0;
0387 }
0388 else
0389 {
0390 unsigned int c;
0391 c = flint_clz(v);
0392 ARF_EXP(x) = FLINT_BITS - c;
0393 ARF_NOPTR_D(x)[0] = v << c;
0394 ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0);
0395 }
0396 }
0397
0398 ARF_INLINE void
0399 arf_set_si(arf_t x, slong v)
0400 {
0401 arf_set_ui(x, FLINT_UABS(v));
0402 if (v < 0)
0403 ARF_NEG(x);
0404 }
0405
0406 ARF_INLINE void
0407 arf_init_set_shallow(arf_t z, const arf_t x)
0408 {
0409 *z = *x;
0410 }
0411
0412 ARF_INLINE void
0413 arf_init_neg_shallow(arf_t z, const arf_t x)
0414 {
0415 *z = *x;
0416 arf_neg(z, z);
0417 }
0418
0419 ARF_INLINE void
0420 arf_init_set_mag_shallow(arf_t y, const mag_t x)
0421 {
0422 ulong t = MAG_MAN(x);
0423 ARF_XSIZE(y) = ARF_MAKE_XSIZE(t != 0, 0);
0424 ARF_EXP(y) = MAG_EXP(x);
0425 ARF_NOPTR_D(y)[0] = t << (FLINT_BITS - MAG_BITS);
0426 }
0427
0428 ARF_INLINE void
0429 arf_init_neg_mag_shallow(arf_t z, const mag_t x)
0430 {
0431 arf_init_set_mag_shallow(z, x);
0432 arf_neg(z, z);
0433 }
0434
0435 ARF_INLINE int
0436 arf_cmpabs_mag(const arf_t x, const mag_t y)
0437 {
0438 arf_t t;
0439 arf_init_set_mag_shallow(t, y);
0440 return arf_cmpabs(x, t);
0441 }
0442
0443 ARF_INLINE int
0444 arf_mag_cmpabs(const mag_t x, const arf_t y)
0445 {
0446 arf_t t;
0447 arf_init_set_mag_shallow(t, x);
0448 return arf_cmpabs(t, y);
0449 }
0450
0451
0452
0453 void arf_set_mpn(arf_t y, nn_srcptr x, slong xn, int sgnbit);
0454
0455 ARF_INLINE void
0456 arf_set_mpz(arf_t y, const mpz_t x)
0457 {
0458 slong size = x->_mp_size;
0459
0460 if (size == 0)
0461 arf_zero(y);
0462 else
0463 arf_set_mpn(y, x->_mp_d, FLINT_ABS(size), size < 0);
0464 }
0465
0466 ARF_INLINE void
0467 arf_set_fmpz(arf_t y, const fmpz_t x)
0468 {
0469 if (!COEFF_IS_MPZ(*x))
0470 arf_set_si(y, *x);
0471 else
0472 arf_set_mpz(y, COEFF_TO_PTR(*x));
0473 }
0474
0475 int _arf_set_round_ui(arf_t x, ulong v, int sgnbit, slong prec, arf_rnd_t rnd);
0476
0477 int _arf_set_round_uiui(arf_t z, slong * fix, ulong hi, ulong lo, int sgnbit, slong prec, arf_rnd_t rnd);
0478
0479 int
0480 _arf_set_round_mpn(arf_t y, slong * exp_shift, nn_srcptr x, slong xn,
0481 int sgnbit, slong prec, arf_rnd_t rnd);
0482
0483 ARF_INLINE int
0484 arf_set_round_ui(arf_t x, ulong v, slong prec, arf_rnd_t rnd)
0485 {
0486 return _arf_set_round_ui(x, v, 0, prec, rnd);
0487 }
0488
0489 ARF_INLINE int
0490 arf_set_round_si(arf_t x, slong v, slong prec, arf_rnd_t rnd)
0491 {
0492 return _arf_set_round_ui(x, FLINT_UABS(v), v < 0, prec, rnd);
0493 }
0494
0495 ARF_INLINE int
0496 arf_set_round_mpz(arf_t y, const mpz_t x, slong prec, arf_rnd_t rnd)
0497 {
0498 int inexact;
0499 slong size = x->_mp_size;
0500 slong fix;
0501
0502 if (size == 0)
0503 {
0504 arf_zero(y);
0505 return 0;
0506 }
0507
0508 inexact = _arf_set_round_mpn(y, &fix, x->_mp_d, FLINT_ABS(size),
0509 (size < 0), prec, rnd);
0510 _fmpz_demote(ARF_EXPREF(y));
0511 ARF_EXP(y) = FLINT_ABS(size) * FLINT_BITS + fix;
0512 return inexact;
0513 }
0514
0515 ARF_INLINE int
0516 arf_set_round_fmpz(arf_t y, const fmpz_t x, slong prec, arf_rnd_t rnd)
0517 {
0518 if (!COEFF_IS_MPZ(*x))
0519 return arf_set_round_si(y, *x, prec, rnd);
0520 else
0521 return arf_set_round_mpz(y, COEFF_TO_PTR(*x), prec, rnd);
0522 }
0523
0524 int arf_set_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd);
0525
0526 int arf_neg_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd);
0527
0528 #ifdef __MPFR_H
0529 int arf_get_mpfr(mpfr_t x, const arf_t y, mpfr_rnd_t rnd);
0530 void arf_set_mpfr(arf_t x, const mpfr_t y);
0531 int _arf_call_mpfr_func(arf_ptr r1, arf_ptr r2, int (*func)(void), arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0532 #endif
0533
0534 int arf_equal(const arf_t x, const arf_t y);
0535 int arf_equal_si(const arf_t x, slong y);
0536 int arf_equal_ui(const arf_t x, ulong y);
0537 int arf_equal_d(const arf_t x, double y);
0538
0539 ARF_INLINE void
0540 arf_min(arf_t z, const arf_t a, const arf_t b)
0541 {
0542 if (arf_cmp(a, b) <= 0)
0543 arf_set(z, a);
0544 else
0545 arf_set(z, b);
0546 }
0547
0548 ARF_INLINE void
0549 arf_max(arf_t z, const arf_t a, const arf_t b)
0550 {
0551 if (arf_cmp(a, b) > 0)
0552 arf_set(z, a);
0553 else
0554 arf_set(z, b);
0555 }
0556
0557 ARF_INLINE void
0558 arf_abs(arf_t y, const arf_t x)
0559 {
0560 if (arf_sgn(x) < 0)
0561 arf_neg(y, x);
0562 else
0563 arf_set(y, x);
0564 }
0565
0566 ARF_INLINE slong
0567 arf_bits(const arf_t x)
0568 {
0569 if (arf_is_special(x))
0570 return 0;
0571 else
0572 {
0573 nn_srcptr xp;
0574 slong xn;
0575 slong c;
0576
0577 ARF_GET_MPN_READONLY(xp, xn, x);
0578 c = flint_ctz(xp[0]);
0579 return xn * FLINT_BITS - c;
0580 }
0581 }
0582
0583 ARF_INLINE void
0584 arf_bot(fmpz_t e, const arf_t x)
0585 {
0586 if (arf_is_special(x))
0587 fmpz_zero(e);
0588 else
0589 fmpz_sub_si(e, ARF_EXPREF(x), arf_bits(x));
0590 }
0591
0592 int arf_is_int(const arf_t x);
0593
0594 int arf_is_int_2exp_si(const arf_t x, slong e);
0595
0596 int arf_cmp_2exp_si(const arf_t x, slong e);
0597
0598 int arf_cmpabs_2exp_si(const arf_t x, slong e);
0599
0600 ARF_INLINE void
0601 arf_set_si_2exp_si(arf_t x, slong man, slong exp)
0602 {
0603 arf_set_si(x, man);
0604 if (man != 0)
0605 fmpz_add_si_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp);
0606 }
0607
0608 ARF_INLINE void
0609 arf_set_ui_2exp_si(arf_t x, ulong man, slong exp)
0610 {
0611 arf_set_ui(x, man);
0612 if (man != 0)
0613 fmpz_add_si_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp);
0614 }
0615
0616 ARF_INLINE void
0617 arf_mul_2exp_si(arf_t y, const arf_t x, slong e)
0618 {
0619 arf_set(y, x);
0620 if (!arf_is_special(y))
0621 fmpz_add_si_inline(ARF_EXPREF(y), ARF_EXPREF(y), e);
0622 }
0623
0624 ARF_INLINE void
0625 arf_mul_2exp_fmpz(arf_t y, const arf_t x, const fmpz_t e)
0626 {
0627 arf_set(y, x);
0628 if (!arf_is_special(y))
0629 fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), e);
0630 }
0631
0632 ARF_INLINE int
0633 arf_set_round_fmpz_2exp(arf_t y, const fmpz_t x, const fmpz_t exp, slong prec, arf_rnd_t rnd)
0634 {
0635 if (fmpz_is_zero(x))
0636 {
0637 arf_zero(y);
0638 return 0;
0639 }
0640 else
0641 {
0642 int r = arf_set_round_fmpz(y, x, prec, rnd);
0643 fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), exp);
0644 return r;
0645 }
0646 }
0647
0648 ARF_INLINE void
0649 arf_abs_bound_lt_2exp_fmpz(fmpz_t b, const arf_t x)
0650 {
0651 if (arf_is_special(x))
0652 fmpz_zero(b);
0653 else
0654 fmpz_set(b, ARF_EXPREF(x));
0655 }
0656
0657 ARF_INLINE void
0658 arf_abs_bound_le_2exp_fmpz(fmpz_t b, const arf_t x)
0659 {
0660 if (arf_is_special(x))
0661 fmpz_zero(b);
0662 else if (ARF_IS_POW2(x))
0663 fmpz_sub_ui(b, ARF_EXPREF(x), 1);
0664 else
0665 fmpz_set(b, ARF_EXPREF(x));
0666 }
0667
0668 slong arf_abs_bound_lt_2exp_si(const arf_t x);
0669
0670 void arf_frexp(arf_t man, fmpz_t exp, const arf_t x);
0671
0672 void arf_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const arf_t x);
0673
0674 int _arf_get_integer_mpn(nn_ptr y, nn_srcptr x, slong xn, slong exp);
0675
0676 int _arf_set_mpn_fixed(arf_t z, nn_srcptr xp, slong xn,
0677 slong fixn, int negative, slong prec, arf_rnd_t rnd);
0678
0679 int arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd);
0680
0681 slong arf_get_si(const arf_t x, arf_rnd_t rnd);
0682
0683 int arf_get_fmpz_fixed_fmpz(fmpz_t y, const arf_t x, const fmpz_t e);
0684
0685 int arf_get_fmpz_fixed_si(fmpz_t y, const arf_t x, slong e);
0686
0687 ARF_INLINE void
0688 arf_set_fmpz_2exp(arf_t x, const fmpz_t man, const fmpz_t exp)
0689 {
0690 arf_set_fmpz(x, man);
0691 if (!arf_is_zero(x))
0692 fmpz_add_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp);
0693 }
0694
0695 void arf_floor(arf_t z, const arf_t x);
0696 void arf_ceil(arf_t z, const arf_t x);
0697 void arf_nint(arf_t z, const arf_t x);
0698
0699 void arf_debug(const arf_t x);
0700
0701 char * arf_get_str(const arf_t x, slong d);
0702
0703 #ifdef FLINT_HAVE_FILE
0704 void arf_fprint(FILE * file, const arf_t x);
0705 void arf_fprintd(FILE * file, const arf_t y, slong d);
0706 #endif
0707
0708 void arf_print(const arf_t x);
0709 void arf_printd(const arf_t y, slong d);
0710
0711 void arf_randtest(arf_t x, flint_rand_t state, slong bits, slong mag_bits);
0712
0713 void arf_randtest_not_zero(arf_t x, flint_rand_t state, slong bits, slong mag_bits);
0714
0715 void arf_randtest_special(arf_t x, flint_rand_t state, slong bits, slong mag_bits);
0716
0717 void arf_urandom(arf_t x, flint_rand_t state, slong bits, arf_rnd_t rnd);
0718
0719 #define MUL_MPFR_MIN_LIMBS 25
0720
0721 #if FLINT_HAVE_FFT_SMALL
0722 #define MUL_MPFR_MAX_LIMBS 800
0723 #else
0724 #define MUL_MPFR_MAX_LIMBS 10000
0725 #endif
0726
0727 #define ARF_MUL_STACK_ALLOC 40
0728 #define ARF_MUL_TLS_ALLOC 1000
0729
0730 extern FLINT_TLS_PREFIX nn_ptr __arf_mul_tmp;
0731 extern FLINT_TLS_PREFIX slong __arf_mul_alloc;
0732
0733 extern void _arf_mul_tmp_cleanup(void);
0734
0735 #define ARF_MUL_TMP_DECL \
0736 ulong tmp_stack[ARF_MUL_STACK_ALLOC]; \
0737
0738 #define ARF_MUL_TMP_ALLOC(tmp, alloc) \
0739 if (alloc <= ARF_MUL_STACK_ALLOC) \
0740 { \
0741 tmp = tmp_stack; \
0742 } \
0743 else if (alloc <= ARF_MUL_TLS_ALLOC) \
0744 { \
0745 if (__arf_mul_alloc < alloc) \
0746 { \
0747 if (__arf_mul_alloc == 0) \
0748 { \
0749 flint_register_cleanup_function(_arf_mul_tmp_cleanup); \
0750 } \
0751 __arf_mul_tmp = flint_realloc(__arf_mul_tmp, sizeof(ulong) * alloc); \
0752 __arf_mul_alloc = alloc; \
0753 } \
0754 tmp = __arf_mul_tmp; \
0755 } \
0756 else \
0757 { \
0758 tmp = flint_malloc(sizeof(ulong) * alloc); \
0759 }
0760
0761 #define ARF_MUL_TMP_FREE(tmp, alloc) \
0762 if (alloc > ARF_MUL_TLS_ALLOC) \
0763 flint_free(tmp);
0764
0765 void arf_mul_special(arf_t z, const arf_t x, const arf_t y);
0766
0767 int arf_mul_via_mpfr(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd);
0768
0769 int arf_mul_rnd_any(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0770
0771 int arf_mul_rnd_down(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec);
0772
0773 #define arf_mul(z, x, y, prec, rnd) \
0774 ((rnd == ARF_RND_DOWN) \
0775 ? arf_mul_rnd_down(z, x, y, prec) \
0776 : arf_mul_rnd_any(z, x, y, prec, rnd))
0777
0778 ARF_INLINE int
0779 arf_neg_mul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
0780 {
0781 if (arf_is_special(y))
0782 {
0783 arf_mul(z, x, y, prec, rnd);
0784 arf_neg(z, z);
0785 return 0;
0786 }
0787 else
0788 {
0789 arf_t t;
0790 *t = *y;
0791 ARF_NEG(t);
0792 return arf_mul(z, x, t, prec, rnd);
0793 }
0794 }
0795
0796 ARF_INLINE int
0797 arf_mul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd)
0798 {
0799 arf_t t;
0800 arf_init_set_ui(t, y);
0801 return arf_mul(z, x, t, prec, rnd);
0802 }
0803
0804 ARF_INLINE int
0805 arf_mul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd)
0806 {
0807 arf_t t;
0808 arf_init_set_si(t, y);
0809 return arf_mul(z, x, t, prec, rnd);
0810 }
0811
0812 int arf_mul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd);
0813
0814 ARF_INLINE int
0815 arf_mul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd)
0816 {
0817 if (!COEFF_IS_MPZ(*y))
0818 return arf_mul_si(z, x, *y, prec, rnd);
0819 else
0820 return arf_mul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd);
0821 }
0822
0823 #define ARF_ADD_STACK_ALLOC 40
0824 #define ARF_ADD_TLS_ALLOC 1000
0825
0826 extern FLINT_TLS_PREFIX nn_ptr __arf_add_tmp;
0827 extern FLINT_TLS_PREFIX slong __arf_add_alloc;
0828
0829 extern void _arf_add_tmp_cleanup(void);
0830
0831 #define ARF_ADD_TMP_DECL \
0832 ulong tmp_stack[ARF_ADD_STACK_ALLOC]; \
0833
0834 #define ARF_ADD_TMP_ALLOC(tmp, alloc) \
0835 if (alloc <= ARF_ADD_STACK_ALLOC) \
0836 { \
0837 tmp = tmp_stack; \
0838 } \
0839 else if (alloc <= ARF_ADD_TLS_ALLOC) \
0840 { \
0841 if (__arf_add_alloc < alloc) \
0842 { \
0843 if (__arf_add_alloc == 0) \
0844 { \
0845 flint_register_cleanup_function(_arf_add_tmp_cleanup); \
0846 } \
0847 __arf_add_tmp = flint_realloc(__arf_add_tmp, sizeof(ulong) * alloc); \
0848 __arf_add_alloc = alloc; \
0849 } \
0850 tmp = __arf_add_tmp; \
0851 } \
0852 else \
0853 { \
0854 tmp = flint_malloc(sizeof(ulong) * alloc); \
0855 }
0856
0857 #define ARF_ADD_TMP_FREE(tmp, alloc) \
0858 if (alloc > ARF_ADD_TLS_ALLOC) \
0859 flint_free(tmp);
0860
0861 int _arf_add_mpn(arf_t z, nn_srcptr xp, slong xn, int xsgnbit,
0862 const fmpz_t xexp, nn_srcptr yp, slong yn, int ysgnbit,
0863 flint_bitcnt_t shift, slong prec, arf_rnd_t rnd);
0864
0865 int arf_add(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0866 int arf_add_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd);
0867 int arf_add_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd);
0868 int arf_add_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd);
0869
0870 int arf_add_fmpz_2exp(arf_ptr z, arf_srcptr x, const fmpz_t y, const fmpz_t exp, slong prec, arf_rnd_t rnd);
0871
0872 int arf_sub(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0873 int arf_sub_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd);
0874 int arf_sub_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd);
0875 int arf_sub_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd);
0876
0877 int arf_addmul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0878
0879 ARF_INLINE int
0880 arf_addmul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd)
0881 {
0882 arf_t t;
0883 arf_init_set_ui(t, y);
0884 return arf_addmul(z, x, t, prec, rnd);
0885 }
0886
0887 ARF_INLINE int
0888 arf_addmul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd)
0889 {
0890 arf_t t;
0891 arf_init_set_si(t, y);
0892 return arf_addmul(z, x, t, prec, rnd);
0893 }
0894
0895 int arf_addmul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd);
0896
0897 ARF_INLINE int
0898 arf_addmul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd)
0899 {
0900 if (!COEFF_IS_MPZ(*y))
0901 return arf_addmul_si(z, x, *y, prec, rnd);
0902 else
0903 return arf_addmul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd);
0904 }
0905
0906 int arf_submul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0907
0908 ARF_INLINE int
0909 arf_submul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd)
0910 {
0911 arf_t t;
0912 arf_init_set_ui(t, y);
0913 return arf_submul(z, x, t, prec, rnd);
0914 }
0915
0916 ARF_INLINE int
0917 arf_submul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd)
0918 {
0919 arf_t t;
0920 arf_init_set_si(t, y);
0921 return arf_submul(z, x, t, prec, rnd);
0922 }
0923
0924 int arf_submul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd);
0925
0926 ARF_INLINE int
0927 arf_submul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd)
0928 {
0929 if (!COEFF_IS_MPZ(*y))
0930 return arf_submul_si(z, x, *y, prec, rnd);
0931 else
0932 return arf_submul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd);
0933 }
0934
0935 int arf_fma(arf_ptr res, arf_srcptr x, arf_srcptr y, arf_srcptr z, slong prec, arf_rnd_t rnd);
0936
0937 int arf_sosq(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd);
0938
0939 int arf_div(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd);
0940
0941 ARF_INLINE int
0942 arf_div_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd)
0943 {
0944 arf_t t;
0945 arf_init_set_ui(t, y);
0946 return arf_div(z, x, t, prec, rnd);
0947 }
0948
0949 ARF_INLINE int
0950 arf_ui_div(arf_ptr z, ulong x, arf_srcptr y, slong prec, arf_rnd_t rnd)
0951 {
0952 arf_t t;
0953 arf_init_set_ui(t, x);
0954 return arf_div(z, t, y, prec, rnd);
0955 }
0956
0957 ARF_INLINE int
0958 arf_div_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd)
0959 {
0960 arf_t t;
0961 arf_init_set_si(t, y);
0962 return arf_div(z, x, t, prec, rnd);
0963 }
0964
0965 ARF_INLINE int
0966 arf_si_div(arf_ptr z, slong x, arf_srcptr y, slong prec, arf_rnd_t rnd)
0967 {
0968 arf_t t;
0969 arf_init_set_si(t, x);
0970 return arf_div(z, t, y, prec, rnd);
0971 }
0972
0973 ARF_INLINE int
0974 arf_div_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd)
0975 {
0976 arf_t t;
0977 int r;
0978 arf_init(t);
0979 arf_set_fmpz(t, y);
0980 r = arf_div(z, x, t, prec, rnd);
0981 arf_clear(t);
0982 return r;
0983 }
0984
0985 ARF_INLINE int
0986 arf_fmpz_div(arf_ptr z, const fmpz_t x, arf_srcptr y, slong prec, arf_rnd_t rnd)
0987 {
0988 arf_t t;
0989 int r;
0990 arf_init(t);
0991 arf_set_fmpz(t, x);
0992 r = arf_div(z, t, y, prec, rnd);
0993 arf_clear(t);
0994 return r;
0995 }
0996
0997 ARF_INLINE int
0998 arf_fmpz_div_fmpz(arf_ptr z, const fmpz_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
0999 {
1000 arf_t t, u;
1001 int r;
1002 arf_init(t);
1003 arf_init(u);
1004 arf_set_fmpz(t, x);
1005 arf_set_fmpz(u, y);
1006 r = arf_div(z, t, u, prec, rnd);
1007 arf_clear(t);
1008 arf_clear(u);
1009 return r;
1010 }
1011
1012 int arf_sqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd);
1013
1014 int arf_sqrt_ui(arf_t z, ulong x, slong prec, arf_rnd_t rnd);
1015
1016 int arf_sqrt_fmpz(arf_t z, const fmpz_t x, slong prec, arf_rnd_t rnd);
1017
1018 int arf_rsqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd);
1019
1020 int arf_root(arf_ptr z, arf_srcptr x, ulong k, slong prec, arf_rnd_t rnd);
1021
1022
1023
1024 void arf_get_mag(mag_t y, const arf_t x);
1025
1026 void arf_get_mag_lower(mag_t y, const arf_t x);
1027
1028 ARF_INLINE void
1029 arf_set_mag(arf_t y, const mag_t x)
1030 {
1031 if (mag_is_zero(x))
1032 {
1033 arf_zero(y);
1034 }
1035 else if (mag_is_inf(x))
1036 {
1037 arf_pos_inf(y);
1038 }
1039 else
1040 {
1041 _fmpz_set_fast(ARF_EXPREF(y), MAG_EXPREF(x));
1042 ARF_DEMOTE(y);
1043 ARF_XSIZE(y) = ARF_MAKE_XSIZE(1, 0);
1044 ARF_NOPTR_D(y)[0] = MAG_MAN(x) << (FLINT_BITS - MAG_BITS);
1045 }
1046 }
1047
1048 ARF_INLINE void
1049 mag_init_set_arf(mag_t y, const arf_t x)
1050 {
1051 mag_init(y);
1052 arf_get_mag(y, x);
1053 }
1054
1055 ARF_INLINE void
1056 mag_fast_init_set_arf(mag_t y, const arf_t x)
1057 {
1058 if (ARF_IS_SPECIAL(x))
1059 {
1060 mag_fast_zero(y);
1061 }
1062 else
1063 {
1064 nn_srcptr xp;
1065 slong xn;
1066
1067 ARF_GET_MPN_READONLY(xp, xn, x);
1068
1069 MAG_MAN(y) = (xp[xn - 1] >> (FLINT_BITS - MAG_BITS)) + LIMB_ONE;
1070 MAG_EXP(y) = ARF_EXP(x);
1071
1072 MAG_FAST_ADJUST_ONE_TOO_LARGE(y);
1073 }
1074 }
1075
1076 ARF_INLINE void
1077 arf_mag_fast_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec)
1078 {
1079 mag_fast_add_2exp_si(z, x, ARF_EXP(y) - prec);
1080 }
1081
1082 ARF_INLINE void
1083 arf_mag_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec)
1084 {
1085 if (ARF_IS_SPECIAL(y))
1086 {
1087 flint_throw(FLINT_ERROR, "error: ulp error not defined for special value!\n");
1088 }
1089 else if (MAG_IS_LAGOM(z) && MAG_IS_LAGOM(x) && ARF_IS_LAGOM(y))
1090 {
1091 arf_mag_fast_add_ulp(z, x, y, prec);
1092 }
1093 else
1094 {
1095 fmpz_t e;
1096 fmpz_init(e);
1097 fmpz_sub_ui(e, ARF_EXPREF(y), prec);
1098 mag_add_2exp_fmpz(z, x, e);
1099 fmpz_clear(e);
1100 }
1101 }
1102
1103 ARF_INLINE void
1104 arf_mag_set_ulp(mag_t z, const arf_t y, slong prec)
1105 {
1106 if (ARF_IS_SPECIAL(y))
1107 {
1108 flint_throw(FLINT_ERROR, "error: ulp error not defined for special value!\n");
1109 }
1110 else
1111 {
1112 _fmpz_add_fast(MAG_EXPREF(z), ARF_EXPREF(y), 1 - prec);
1113 MAG_MAN(z) = MAG_ONE_HALF;
1114 }
1115 }
1116
1117 void arf_get_fmpq(fmpq_t y, const arf_t x);
1118
1119 ARF_INLINE int
1120 arf_set_fmpq(arf_t y, const fmpq_t x, slong prec, arf_rnd_t rnd)
1121 {
1122 return arf_fmpz_div_fmpz(y, fmpq_numref(x), fmpq_denref(x), prec, rnd);
1123 }
1124
1125 int arf_complex_mul(arf_t e, arf_t f, const arf_t a, const arf_t b,
1126 const arf_t c, const arf_t d,
1127 slong prec, arf_rnd_t rnd);
1128
1129 int arf_complex_mul_fallback(arf_t e, arf_t f,
1130 const arf_t a, const arf_t b,
1131 const arf_t c, const arf_t d,
1132 slong prec, arf_rnd_t rnd);
1133
1134 int arf_complex_sqr(arf_t e, arf_t f, const arf_t a, const arf_t b,
1135 slong prec, arf_rnd_t rnd);
1136
1137 int arf_sum(arf_t s, arf_srcptr terms, slong len, slong prec, arf_rnd_t rnd);
1138
1139 double arf_get_d(const arf_t x, arf_rnd_t rnd);
1140 void arf_set_d(arf_t x, double v);
1141
1142 ARF_INLINE slong
1143 arf_allocated_bytes(const arf_t x)
1144 {
1145 slong size = fmpz_allocated_bytes(ARF_EXPREF(x));
1146
1147 if (ARF_HAS_PTR(x))
1148 size += ARF_PTR_ALLOC(x) * sizeof(ulong);
1149
1150 return size;
1151 }
1152
1153 int arf_load_str(arf_t res, const char * data);
1154 char * arf_dump_str(const arf_t x);
1155
1156 #ifdef FLINT_HAVE_FILE
1157 int arf_load_file(arf_t res, FILE *stream);
1158 int arf_dump_file(FILE* stream, const arf_t x);
1159 #endif
1160
1161 int arf_dot(arf_t res, const arf_t initial, int subtract,
1162 arf_srcptr x, slong xstep, arf_srcptr y, slong ystep, slong len, slong prec, arf_rnd_t rnd);
1163
1164 void arf_approx_dot(arf_t res, const arf_t initial, int subtract,
1165 arf_srcptr x, slong xstep, arf_srcptr y, slong ystep, slong len, slong prec, arf_rnd_t rnd);
1166
1167 #ifdef __cplusplus
1168 }
1169 #endif
1170
1171 #endif