Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:28

0001 /*
0002     Copyright (C) 2014 Fredrik Johansson
0003 
0004     This file is part of FLINT.
0005 
0006     FLINT is free software: you can redistribute it and/or modify it under
0007     the terms of the GNU Lesser General Public License (LGPL) as published
0008     by the Free Software Foundation; either version 3 of the License, or
0009     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0010 */
0011 
0012 #ifndef MAG_H
0013 #define MAG_H
0014 
0015 #ifdef MAG_INLINES_C
0016 #define MAG_INLINE
0017 #else
0018 #define MAG_INLINE static inline
0019 #endif
0020 
0021 #include "fmpz_extras.h"
0022 #include "arb_types.h"
0023 
0024 #ifdef __cplusplus
0025 extern "C" {
0026 #endif
0027 
0028 #define LIMB_ONE ((ulong) 1)
0029 #define LIMB_ONES (-(ulong) 1)
0030 #define LIMB_TOP (((ulong) 1) << (FLINT_BITS - 1))
0031 #define MASK_LIMB(n, c) ((n) & (LIMB_ONES << (c)))
0032 
0033 #define MAG_MAX_LAGOM_EXP (COEFF_MAX / 4)
0034 #define MAG_MIN_LAGOM_EXP (-MAG_MAX_LAGOM_EXP)
0035 
0036 #define ADD2_FAST_MAX (COEFF_MAX / 4)
0037 #define ADD2_FAST_MIN (-ADD2_FAST_MAX)
0038 
0039 /* TODO: rename these and move them to fmpz_extras */
0040 
0041 static inline void
0042 _fmpz_set_fast(fmpz_t f, const fmpz_t g)
0043 {
0044     if (!COEFF_IS_MPZ(*f) && !COEFF_IS_MPZ(*g))
0045         *f = *g;
0046     else
0047         fmpz_set(f, g);
0048 }
0049 
0050 static inline void
0051 _fmpz_add_fast(fmpz_t z, const fmpz_t x, slong c)
0052 {
0053     fmpz ze, xe;
0054 
0055     ze = *z;
0056     xe = *x;
0057 
0058     if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX))
0059         *z = xe + c;
0060     else
0061         fmpz_add_si(z, x, c);
0062 }
0063 
0064 static inline void
0065 _fmpz_add2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c)
0066 {
0067     fmpz ze, xe, ye;
0068 
0069     ze = *z;
0070     xe = *x;
0071     ye = *y;
0072 
0073     if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) &&
0074                              (ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX))
0075     {
0076         *z = xe + ye + c;
0077     }
0078     else
0079     {
0080         fmpz_add(z, x, y);
0081         fmpz_add_si(z, z, c);
0082     }
0083 }
0084 
0085 static inline void
0086 _fmpz_sub2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c)
0087 {
0088     fmpz ze, xe, ye;
0089 
0090     ze = *z;
0091     xe = *x;
0092     ye = *y;
0093 
0094     if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) &&
0095                              (ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX))
0096     {
0097         *z = xe - ye + c;
0098     }
0099     else
0100     {
0101         fmpz_sub(z, x, y);
0102         fmpz_add_si(z, z, c);
0103     }
0104 }
0105 
0106 
0107 #define MAG_EXP_POS_INF (COEFF_MIN+1)
0108 
0109 /* Finite and with lagom big exponents. */
0110 #define MAG_IS_LAGOM(x) (MAG_EXP(x) >= MAG_MIN_LAGOM_EXP && \
0111                          MAG_EXP(x) <= MAG_MAX_LAGOM_EXP)
0112 
0113 #define MAG_EXPREF(x) (&(x)->exp)
0114 #define MAG_EXP(x) ((x)->exp)
0115 #define MAG_MAN(x) ((x)->man)
0116 
0117 #define MAG_BITS 30
0118 
0119 #define MAG_ONE_HALF (UWORD(1) << (MAG_BITS - 1))
0120 
0121 #if FLINT_BITS == 64
0122 # define MAG_FIXMUL(x, y) (((x) * (y)) >> MAG_BITS)
0123 #else
0124 # define MAG_FIXMUL(x, y) ((ulong) (((unsigned long long int) (x) * (unsigned long long int) (y)) >> MAG_BITS))
0125 #endif
0126 
0127 #define MAG_CHECK_BITS(rr) \
0128     if (MAG_MAN(rr) != 0 && FLINT_BIT_COUNT(MAG_MAN(rr)) != MAG_BITS) \
0129     { \
0130         flint_throw(FLINT_ERROR, "FAIL: wrong number of bits in mantissa!\n"); \
0131     }
0132 
0133 /* Note: assumes mantissa either has the right number of bits, or
0134    one more bit (but in that case must not be all ones, as that
0135    would round up to one extra bit again, requiring a second
0136    correction). */
0137 
0138 #define MAG_ADJUST_ONE_TOO_LARGE(x) \
0139     do { \
0140         ulong __t = MAG_MAN(x) >> MAG_BITS; \
0141         MAG_MAN(x) = (MAG_MAN(x) >> __t) + (__t & MAG_MAN(x)); \
0142         if (__t) \
0143             fmpz_add_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \
0144     } while (0)
0145 
0146 #define MAG_FAST_ADJUST_ONE_TOO_LARGE(x) \
0147     do { \
0148         ulong __t = MAG_MAN(x) >> MAG_BITS; \
0149         MAG_MAN(x) = (MAG_MAN(x) >> __t) + (__t & MAG_MAN(x)); \
0150         MAG_EXP(x) += __t; \
0151     } while (0)
0152 
0153 #define MAG_ADJUST_ONE_TOO_SMALL(x) \
0154     do { \
0155         ulong __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \
0156         MAG_MAN(x) = (MAG_MAN(x) << __t); \
0157         if (__t) \
0158             fmpz_sub_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \
0159     } while (0)
0160 
0161 #define MAG_FAST_ADJUST_ONE_TOO_SMALL(x) \
0162     do { \
0163         ulong __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \
0164         MAG_MAN(x) = (MAG_MAN(x) << __t); \
0165         MAG_EXP(x) -= __t; \
0166     } while (0)
0167 
0168 
0169 MAG_INLINE void
0170 mag_init(mag_t x)
0171 {
0172     fmpz_init(MAG_EXPREF(x));
0173     MAG_MAN(x) = 0;
0174 }
0175 
0176 MAG_INLINE void
0177 mag_init_set(mag_t x, const mag_t y)
0178 {
0179     fmpz_init_set(MAG_EXPREF(x), MAG_EXPREF(y));
0180     MAG_MAN(x) = MAG_MAN(y);
0181 }
0182 
0183 void mag_clear(mag_t x);
0184 
0185 MAG_INLINE void
0186 mag_swap(mag_t x, mag_t y)
0187 {
0188     mag_struct t = *x;
0189     *x = *y;
0190     *y = t;
0191 }
0192 
0193 MAG_INLINE void
0194 mag_set(mag_t x, const mag_t y)
0195 {
0196     _fmpz_set_fast(MAG_EXPREF(x), MAG_EXPREF(y));
0197     x->man = y->man;
0198 }
0199 
0200 MAG_INLINE void
0201 mag_zero(mag_t x)
0202 {
0203     fmpz_zero(MAG_EXPREF(x));
0204     MAG_MAN(x) = 0;
0205 }
0206 
0207 MAG_INLINE void
0208 mag_one(mag_t x)
0209 {
0210     fmpz_one(MAG_EXPREF(x));
0211     MAG_MAN(x) = MAG_ONE_HALF;
0212 }
0213 
0214 MAG_INLINE int
0215 mag_is_special(const mag_t x)
0216 {
0217     return MAG_MAN(x) == 0;
0218 }
0219 
0220 MAG_INLINE int
0221 mag_is_zero(const mag_t x)
0222 {
0223     return (MAG_MAN(x) == 0) && (MAG_EXP(x) == 0);
0224 }
0225 
0226 MAG_INLINE void
0227 mag_inf(mag_t x)
0228 {
0229     fmpz_clear(MAG_EXPREF(x));
0230     MAG_EXP(x) = MAG_EXP_POS_INF;
0231     MAG_MAN(x) = 0;
0232 }
0233 
0234 MAG_INLINE int
0235 mag_is_inf(const mag_t x)
0236 {
0237     return (MAG_MAN(x) == 0) && (MAG_EXP(x) != 0);
0238 }
0239 
0240 MAG_INLINE int
0241 mag_is_finite(const mag_t x)
0242 {
0243     return !mag_is_inf(x);
0244 }
0245 
0246 MAG_INLINE int
0247 mag_equal(const mag_t x, const mag_t y)
0248 {
0249     return (MAG_MAN(x) == MAG_MAN(y))
0250         && fmpz_equal(MAG_EXPREF(x), MAG_EXPREF(y));
0251 }
0252 
0253 /* general versions */
0254 
0255 void mag_mul(mag_t z, const mag_t x, const mag_t y);
0256 
0257 void mag_mul_lower(mag_t z, const mag_t x, const mag_t y);
0258 
0259 void mag_addmul(mag_t z, const mag_t x, const mag_t y);
0260 
0261 void mag_add_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t e);
0262 
0263 void mag_add(mag_t z, const mag_t x, const mag_t y);
0264 
0265 void mag_add_lower(mag_t z, const mag_t x, const mag_t y);
0266 
0267 void mag_add_ui(mag_t z, const mag_t x, ulong y);
0268 void mag_add_ui_lower(mag_t res, const mag_t x, ulong y);
0269 
0270 void mag_add_ui_2exp_si(mag_t z, const mag_t x, ulong y, slong e);
0271 
0272 void mag_div(mag_t z, const mag_t x, const mag_t y);
0273 void mag_div_lower(mag_t z, const mag_t x, const mag_t y);
0274 
0275 MAG_INLINE void
0276 mag_inv(mag_t res, const mag_t x)
0277 {
0278     mag_t t;
0279     mag_init(t); /* no need to free */
0280     mag_one(t);
0281     mag_div(res, t, x);
0282 }
0283 
0284 MAG_INLINE void
0285 mag_inv_lower(mag_t res, const mag_t x)
0286 {
0287     mag_t t;
0288     mag_init(t); /* no need to free */
0289     mag_one(t);
0290     mag_div_lower(res, t, x);
0291 }
0292 
0293 void mag_mul_2exp_si(mag_t z, const mag_t x, slong y);
0294 
0295 void mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y);
0296 
0297 void mag_sub(mag_t z, const mag_t x, const mag_t y);
0298 
0299 void mag_sub_lower(mag_t z, const mag_t x, const mag_t y);
0300 
0301 /* Fast versions (no infs/nans, small exponents). Note that this
0302    applies to outputs too! */
0303 
0304 MAG_INLINE void
0305 mag_fast_init_set(mag_t x, const mag_t y)
0306 {
0307     MAG_EXP(x) = MAG_EXP(y);
0308     MAG_MAN(x) = MAG_MAN(y);
0309 }
0310 
0311 MAG_INLINE void
0312 mag_fast_zero(mag_t x)
0313 {
0314     MAG_EXP(x) = 0;
0315     MAG_MAN(x) = 0;
0316 }
0317 
0318 MAG_INLINE int
0319 mag_fast_is_zero(const mag_t x)
0320 {
0321     return MAG_MAN(x) == 0;
0322 }
0323 
0324 MAG_INLINE void
0325 mag_fast_mul(mag_t z, const mag_t x, const mag_t y)
0326 {
0327     if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0)
0328     {
0329         mag_fast_zero(z);
0330     }
0331     else
0332     {
0333         MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + LIMB_ONE;
0334         MAG_EXP(z) = MAG_EXP(x) + MAG_EXP(y);
0335         MAG_FAST_ADJUST_ONE_TOO_SMALL(z);
0336     }
0337 }
0338 
0339 MAG_INLINE void
0340 mag_fast_mul_2exp_si(mag_t z, const mag_t x, slong y)
0341 {
0342     if (MAG_MAN(x) == 0)
0343     {
0344         mag_fast_zero(z);
0345     }
0346     else
0347     {
0348         MAG_MAN(z) = MAG_MAN(x);
0349         MAG_EXP(z) = MAG_EXP(x) + y;
0350     }
0351 }
0352 
0353 MAG_INLINE void
0354 mag_fast_addmul(mag_t z, const mag_t x, const mag_t y)
0355 {
0356     if (MAG_MAN(z) == 0)
0357     {
0358         mag_fast_mul(z, x, y);
0359     }
0360     else if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0)
0361     {
0362         return;
0363     }
0364     else
0365     {
0366         slong shift, e;
0367 
0368         /* x*y < 2^e */
0369         e = MAG_EXP(x) + MAG_EXP(y);
0370         shift = MAG_EXP(z) - e;
0371 
0372         if (shift >= 0)
0373         {
0374             if (shift >= MAG_BITS)
0375                 MAG_MAN(z)++;
0376             else
0377                 MAG_MAN(z) = MAG_MAN(z) + (MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) >> shift) + 1;
0378         }
0379         else
0380         {
0381             shift = -shift;
0382             MAG_EXP(z) = e;
0383 
0384             if (shift >= MAG_BITS)
0385                 MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + 2;
0386             else
0387                 MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + (MAG_MAN(z) >> shift) + 2;
0388 
0389             MAG_FAST_ADJUST_ONE_TOO_SMALL(z);
0390         }
0391 
0392         MAG_FAST_ADJUST_ONE_TOO_LARGE(z);
0393     }
0394 }
0395 
0396 MAG_INLINE void
0397 mag_fast_add_2exp_si(mag_t z, const mag_t x, slong e)
0398 {
0399     /* Must be zero */
0400     if (mag_is_special(x))
0401     {
0402         MAG_MAN(z) = MAG_ONE_HALF;
0403         MAG_EXP(z) = e + 1;
0404     }
0405     else
0406     {
0407         slong shift;
0408         shift = MAG_EXP(x) - e;
0409 
0410         if (shift > 0)
0411         {
0412             MAG_EXP(z) = MAG_EXP(x);
0413 
0414             if (shift >= MAG_BITS)
0415                 MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE;
0416             else
0417                 MAG_MAN(z) = MAG_MAN(x) + (LIMB_ONE << (MAG_BITS - shift));
0418         }
0419         else
0420         {
0421             shift = -shift;
0422 
0423             MAG_EXP(z) = e + 1;
0424 
0425             if (shift >= MAG_BITS)
0426                 MAG_MAN(z) = MAG_ONE_HALF + LIMB_ONE;
0427             else
0428                 MAG_MAN(z) = MAG_ONE_HALF + (MAG_MAN(x) >> (shift + 1)) + LIMB_ONE;
0429         }
0430 
0431         MAG_FAST_ADJUST_ONE_TOO_LARGE(z);
0432     }
0433 }
0434 
0435 /* requires that x is positive and finite */
0436 #define MAG_SET_D_2EXP(man, exp, x, xexp) \
0437     do { \
0438         int __cexp; \
0439         double __x; \
0440         int __fix; \
0441         ulong __man; \
0442         __x = frexp((x), &__cexp); \
0443         __man = (ulong)(__x * (double)(LIMB_ONE << MAG_BITS)) + 1; \
0444         __fix = __man >> (MAG_BITS); \
0445         __man = (__man >> __fix) + __fix; \
0446         (man) = __man; \
0447         (exp) = (xexp) + __cexp + __fix; \
0448     } while (0);
0449 
0450 /* requires that x is positive and finite */
0451 #define MAG_SET_D_2EXP_LOWER(man, exp, x, xexp) \
0452     do { \
0453         int __cexp; \
0454         double __x; \
0455         int __fix; \
0456         ulong __man; \
0457         __x = frexp((x), &__cexp); \
0458         __man = (ulong)(__x * (double)(LIMB_ONE << MAG_BITS)) - 1; \
0459         __fix = __man < MAG_ONE_HALF; \
0460         __man = (__man << __fix); \
0461         (man) = __man; \
0462         (exp) = (xexp) + __cexp - __fix; \
0463     } while (0);
0464 
0465 void mag_set_d(mag_t z, double x);
0466 void mag_set_d_lower(mag_t z, double x);
0467 void mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp);
0468 void mag_set_d_2exp_fmpz_lower(mag_t z, double c, const fmpz_t exp);
0469 
0470 void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp);
0471 
0472 void mag_randtest_special(mag_t x, flint_rand_t state, slong expbits);
0473 
0474 void mag_randtest(mag_t x, flint_rand_t state, slong expbits);
0475 
0476 #ifdef FLINT_HAVE_FILE
0477 void mag_fprint(FILE * file, const mag_t x);
0478 void mag_fprintd(FILE * file, const mag_t x, slong d);
0479 #endif
0480 
0481 void mag_print(const mag_t x);
0482 void mag_printd(const mag_t x, slong d);
0483 
0484 void mag_get_fmpq(fmpq_t y, const mag_t x);
0485 
0486 void mag_get_fmpz(fmpz_t res, const mag_t x);
0487 void mag_get_fmpz_lower(fmpz_t res, const mag_t x);
0488 
0489 int mag_cmp(const mag_t x, const mag_t y);
0490 
0491 int mag_cmp_2exp_si(const mag_t x, slong e);
0492 
0493 MAG_INLINE void
0494 mag_min(mag_t z, const mag_t x, const mag_t y)
0495 {
0496     if (mag_cmp(x, y) <= 0)
0497         mag_set(z, x);
0498     else
0499         mag_set(z, y);
0500 }
0501 
0502 MAG_INLINE void
0503 mag_max(mag_t z, const mag_t x, const mag_t y)
0504 {
0505     if (mag_cmp(x, y) >= 0)
0506         mag_set(z, x);
0507     else
0508         mag_set(z, y);
0509 }
0510 
0511 MAG_INLINE mag_ptr
0512 _mag_vec_init(slong n)
0513 {
0514     slong i;
0515     mag_ptr v = (mag_ptr) flint_malloc(sizeof(mag_struct) * n);
0516 
0517     for (i = 0; i < n; i++)
0518         mag_init(v + i);
0519 
0520     return v;
0521 }
0522 
0523 MAG_INLINE void
0524 _mag_vec_clear(mag_ptr v, slong n)
0525 {
0526     slong i;
0527     for (i = 0; i < n; i++)
0528         mag_clear(v + i);
0529     flint_free(v);
0530 }
0531 
0532 double mag_get_d(const mag_t z);
0533 
0534 double mag_get_d_log2_approx(const mag_t x);
0535 
0536 /* TODO: document */
0537 double mag_d_log_upper_bound(double x);
0538 double mag_d_log_lower_bound(double x);
0539 
0540 void mag_log1p(mag_t z, const mag_t x);
0541 
0542 void mag_log_ui(mag_t t, ulong n);
0543 
0544 void mag_log(mag_t z, const mag_t x);
0545 void mag_log_lower(mag_t z, const mag_t x);
0546 void mag_neg_log(mag_t z, const mag_t x);
0547 void mag_neg_log_lower(mag_t z, const mag_t x);
0548 
0549 void mag_exp(mag_t y, const mag_t x);
0550 void mag_exp_lower(mag_t y, const mag_t x);
0551 
0552 void mag_expinv(mag_t res, const mag_t x);
0553 void mag_expinv_lower(mag_t y, const mag_t x);
0554 
0555 void mag_expm1(mag_t y, const mag_t x);
0556 void mag_exp_tail(mag_t z, const mag_t x, ulong N);
0557 
0558 void mag_sinh(mag_t y, const mag_t x);
0559 void mag_sinh_lower(mag_t y, const mag_t x);
0560 
0561 void mag_cosh(mag_t y, const mag_t x);
0562 void mag_cosh_lower(mag_t y, const mag_t x);
0563 
0564 void mag_pow_ui(mag_t z, const mag_t x, ulong e);
0565 void mag_pow_ui_lower(mag_t z, const mag_t x, ulong e);
0566 void mag_pow_fmpz(mag_t z, const mag_t x, const fmpz_t e);
0567 void mag_pow_fmpz_lower(mag_t z, const mag_t x, const fmpz_t e);
0568 
0569 void mag_const_pi(mag_t res);
0570 void mag_const_pi_lower(mag_t res);
0571 
0572 void mag_atan(mag_t res, const mag_t x);
0573 void mag_atan_lower(mag_t res, const mag_t x);
0574 
0575 void mag_fac_ui(mag_t z, ulong n);
0576 void mag_rfac_ui(mag_t z, ulong n);
0577 void mag_bin_uiui(mag_t res, ulong n, ulong k);
0578 
0579 /* TODO: test */
0580 void mag_bernoulli_div_fac_ui(mag_t z, ulong n);
0581 
0582 /* TODO: test */
0583 void mag_set_fmpz_2exp_fmpz_lower(mag_t z, const fmpz_t man, const fmpz_t exp);
0584 
0585 void mag_sqrt(mag_t y, const mag_t x);
0586 void mag_sqrt_lower(mag_t y, const mag_t x);
0587 void mag_rsqrt(mag_t y, const mag_t x);
0588 void mag_rsqrt_lower(mag_t y, const mag_t x);
0589 
0590 void mag_root(mag_t y, const mag_t x, ulong n);
0591 
0592 void mag_hypot(mag_t z, const mag_t x, const mag_t y);
0593 
0594 void mag_binpow_uiui(mag_t b, ulong m, ulong n);
0595 
0596 void mag_polylog_tail(mag_t u, const mag_t z, slong sigma, ulong d, ulong N);
0597 
0598 void mag_geom_series(mag_t res, const mag_t x, ulong n);
0599 
0600 void mag_hurwitz_zeta_uiui(mag_t res, ulong s, ulong a);
0601 
0602 void mag_set_ui(mag_t z, ulong x);
0603 void mag_set_ui_lower(mag_t z, ulong x);
0604 
0605 /* TODO: test functions below */
0606 void mag_set_ui_2exp_si(mag_t z, ulong v, slong e);
0607 
0608 MAG_INLINE void
0609 mag_set_fmpz(mag_t z, const fmpz_t x)
0610 {
0611     fmpz_t exp;
0612     *exp = 0;
0613     mag_set_fmpz_2exp_fmpz(z, x, exp);
0614 }
0615 
0616 MAG_INLINE void
0617 mag_set_fmpz_lower(mag_t z, const fmpz_t x)
0618 {
0619     fmpz_t exp;
0620     *exp = 0;
0621     mag_set_fmpz_2exp_fmpz_lower(z, x, exp);
0622 }
0623 
0624 MAG_INLINE void
0625 mag_mul_ui(mag_t z, const mag_t x, ulong y)
0626 {
0627     mag_t t;
0628     mag_init(t);  /* no need to clear */
0629     mag_set_ui(t, y);
0630     mag_mul(z, x, t);
0631 }
0632 
0633 MAG_INLINE void
0634 mag_mul_ui_lower(mag_t z, const mag_t x, ulong y)
0635 {
0636     mag_t t;
0637     mag_init(t);  /* no need to clear */
0638     mag_set_ui_lower(t, y);
0639     mag_mul_lower(z, x, t);
0640 }
0641 
0642 MAG_INLINE void
0643 mag_mul_fmpz(mag_t z, const mag_t x, const fmpz_t y)
0644 {
0645     mag_t t;
0646     mag_init(t);
0647     mag_set_fmpz(t, y);
0648     mag_mul(z, x, t);
0649     mag_clear(t);
0650 }
0651 
0652 MAG_INLINE void
0653 mag_mul_fmpz_lower(mag_t z, const mag_t x, const fmpz_t y)
0654 {
0655     mag_t t;
0656     mag_init(t);
0657     mag_set_fmpz_lower(t, y);
0658     mag_mul_lower(z, x, t);
0659     mag_clear(t);
0660 }
0661 
0662 MAG_INLINE void
0663 mag_div_ui(mag_t z, const mag_t x, ulong y)
0664 {
0665     mag_t t;
0666     mag_init(t);  /* no need to clear */
0667     mag_set_ui_lower(t, y);
0668     mag_div(z, x, t);
0669 }
0670 
0671 MAG_INLINE void
0672 mag_div_fmpz(mag_t z, const mag_t x, const fmpz_t y)
0673 {
0674     mag_t t;
0675     mag_init(t);
0676     mag_set_fmpz_lower(t, y);
0677     mag_div(z, x, t);
0678     mag_clear(t);
0679 }
0680 
0681 MAG_INLINE slong mag_allocated_bytes(const mag_t x)
0682 {
0683     return fmpz_allocated_bytes(MAG_EXPREF(x));
0684 }
0685 
0686 int mag_load_str(mag_t res, const char * data);
0687 char * mag_dump_str(const mag_t x);
0688 
0689 #ifdef FLINT_HAVE_FILE
0690 int mag_load_file(mag_t res, FILE * stream);
0691 int mag_dump_file(FILE * stream, const mag_t x);
0692 #endif
0693 
0694 #ifdef __cplusplus
0695 }
0696 #endif
0697 
0698 #endif