arb/mag.h

704 lines
14 KiB
C
Raw Normal View History

/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2014 Fredrik Johansson
******************************************************************************/
#ifndef MAG_H
#define MAG_H
2014-12-25 15:50:37 +01:00
#ifdef MAG_INLINES_C
#define MAG_INLINE
#else
#define MAG_INLINE static __inline__
#endif
#include <stdio.h>
#include <math.h>
#include "flint.h"
2014-05-08 14:48:36 +02:00
#include "fmpz.h"
#include "fmpz_extras.h"
#ifdef __cplusplus
extern "C" {
#endif
2014-05-08 14:48:36 +02:00
#define LIMB_ONE ((mp_limb_t) 1)
#define LIMB_ONES (-(mp_limb_t) 1)
#define LIMB_TOP (((mp_limb_t) 1) << (FLINT_BITS - 1))
#define MASK_LIMB(n, c) ((n) & (LIMB_ONES << (c)))
2014-05-08 14:48:36 +02:00
#define MAG_MAX_LAGOM_EXP (COEFF_MAX / 4)
#define MAG_MIN_LAGOM_EXP (-MAG_MAX_LAGOM_EXP)
2014-05-08 14:48:36 +02:00
#define ADD2_FAST_MAX (COEFF_MAX / 4)
#define ADD2_FAST_MIN (-ADD2_FAST_MAX)
2014-05-08 14:48:36 +02:00
/* TODO: rename these and move them to fmpz_extras */
2014-05-08 14:48:36 +02:00
static __inline__ void
_fmpz_set_fast(fmpz_t f, const fmpz_t g)
{
if (!COEFF_IS_MPZ(*f) && !COEFF_IS_MPZ(*g))
*f = *g;
else
fmpz_set(f, g);
}
static __inline__ void
2015-11-06 11:16:52 +00:00
_fmpz_add_fast(fmpz_t z, const fmpz_t x, slong c)
2014-05-08 14:48:36 +02:00
{
fmpz ze, xe;
ze = *z;
xe = *x;
if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX))
*z = xe + c;
else
fmpz_add_si(z, x, c);
}
static __inline__ void
2015-11-06 11:16:52 +00:00
_fmpz_add2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c)
2014-05-08 14:48:36 +02:00
{
fmpz ze, xe, ye;
ze = *z;
xe = *x;
ye = *y;
if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) &&
(ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX))
{
*z = xe + ye + c;
}
else
{
fmpz_add(z, x, y);
fmpz_add_si(z, z, c);
}
}
static __inline__ void
2015-11-06 11:16:52 +00:00
_fmpz_sub2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c)
2014-05-08 14:48:36 +02:00
{
fmpz ze, xe, ye;
ze = *z;
xe = *x;
ye = *y;
if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) &&
(ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX))
{
*z = xe - ye + c;
}
else
{
fmpz_sub(z, x, y);
fmpz_add_si(z, z, c);
}
}
#define MAG_EXP_POS_INF (COEFF_MIN+1)
/* Finite and with lagom big exponents. */
#define MAG_IS_LAGOM(x) (MAG_EXP(x) >= MAG_MIN_LAGOM_EXP && \
MAG_EXP(x) <= MAG_MAX_LAGOM_EXP)
#define MAG_EXPREF(x) (&(x)->exp)
#define MAG_EXP(x) ((x)->exp)
#define MAG_MAN(x) ((x)->man)
#define MAG_BITS 30
2015-11-06 15:34:19 +00:00
#define MAG_ONE_HALF (UWORD(1) << (MAG_BITS - 1))
static __inline__ mp_limb_t
__mag_fixmul32(mp_limb_t x, mp_limb_t y)
{
mp_limb_t u, v;
umul_ppmm(u, v, x, y);
return (u << (32 - MAG_BITS)) | (v >> MAG_BITS);
}
#if FLINT_BITS == 64
#define MAG_FIXMUL(x, y) (((x) * (y)) >> MAG_BITS)
#else
#define MAG_FIXMUL(x, y) __mag_fixmul32((x), (y))
#endif
2014-05-08 16:49:39 +02:00
#define MAG_CHECK_BITS(rr) \
if (MAG_MAN(rr) != 0 && FLINT_BIT_COUNT(MAG_MAN(rr)) != MAG_BITS) \
{ \
flint_printf("FAIL: wrong number of bits in mantissa!\n"); \
2014-05-08 16:49:39 +02:00
abort(); \
}
/* Note: assumes mantissa either has the right number of bits, or
one more bit (but in that case must not be all ones, as that
would round up to one extra bit again, requiring a second
correction). */
2014-05-06 20:38:49 +02:00
#define MAG_ADJUST_ONE_TOO_LARGE(x) \
do { \
mp_limb_t __t = MAG_MAN(x) >> MAG_BITS; \
MAG_MAN(x) = (MAG_MAN(x) >> __t) + __t; \
2014-05-06 20:38:49 +02:00
if (__t) \
fmpz_add_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \
} while (0)
2014-05-08 16:49:39 +02:00
#define MAG_FAST_ADJUST_ONE_TOO_LARGE(x) \
do { \
mp_limb_t __t = MAG_MAN(x) >> MAG_BITS; \
MAG_MAN(x) = (MAG_MAN(x) >> __t) + __t; \
MAG_EXP(x) += __t; \
} while (0)
2014-05-06 20:38:49 +02:00
#define MAG_ADJUST_ONE_TOO_SMALL(x) \
2014-05-06 19:17:29 +02:00
do { \
2014-05-06 20:38:49 +02:00
mp_limb_t __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \
2014-05-06 19:17:29 +02:00
MAG_MAN(x) = (MAG_MAN(x) << __t); \
2014-05-06 20:38:49 +02:00
if (__t) \
fmpz_sub_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \
2014-05-06 19:17:29 +02:00
} while (0)
2014-05-06 20:38:49 +02:00
#define MAG_FAST_ADJUST_ONE_TOO_SMALL(x) \
do { \
mp_limb_t __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \
MAG_MAN(x) = (MAG_MAN(x) << __t); \
MAG_EXP(x) -= __t; \
} while (0)
typedef struct
{
fmpz exp;
mp_limb_t man;
}
mag_struct;
typedef mag_struct mag_t[1];
2014-05-26 14:24:18 +02:00
typedef mag_struct * mag_ptr;
typedef const mag_struct * mag_srcptr;
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_init(mag_t x)
{
fmpz_init(MAG_EXPREF(x));
MAG_MAN(x) = 0;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-06 20:38:49 +02:00
mag_init_set(mag_t x, const mag_t y)
{
fmpz_init_set(MAG_EXPREF(x), MAG_EXPREF(y));
MAG_MAN(x) = MAG_MAN(y);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_clear(mag_t x)
{
fmpz_clear(MAG_EXPREF(x));
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-06 20:38:49 +02:00
mag_swap(mag_t x, mag_t y)
{
mag_struct t = *x;
*x = *y;
*y = t;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-06 20:38:49 +02:00
mag_set(mag_t x, const mag_t y)
{
2014-05-08 14:48:36 +02:00
_fmpz_set_fast(MAG_EXPREF(x), MAG_EXPREF(y));
2014-05-06 20:38:49 +02:00
x->man = y->man;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_zero(mag_t x)
{
fmpz_zero(MAG_EXPREF(x));
MAG_MAN(x) = 0;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-12 11:15:51 +02:00
mag_one(mag_t x)
{
fmpz_one(MAG_EXPREF(x));
MAG_MAN(x) = MAG_ONE_HALF;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
mag_is_special(const mag_t x)
{
return MAG_MAN(x) == 0;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
mag_is_zero(const mag_t x)
{
return (MAG_MAN(x) == 0) && (MAG_EXP(x) == 0);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-08 14:48:36 +02:00
mag_inf(mag_t x)
{
fmpz_clear(MAG_EXPREF(x));
MAG_EXP(x) = MAG_EXP_POS_INF;
2014-05-08 16:49:39 +02:00
MAG_MAN(x) = 0;
2014-05-08 14:48:36 +02:00
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
mag_is_inf(const mag_t x)
{
return (MAG_MAN(x) == 0) && (MAG_EXP(x) != 0);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
2014-05-09 16:50:01 +02:00
mag_is_finite(const mag_t x)
{
return !mag_is_inf(x);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
2014-05-09 16:50:01 +02:00
mag_equal(const mag_t x, const mag_t y)
{
return (MAG_MAN(x) == MAG_MAN(y))
&& fmpz_equal(MAG_EXPREF(x), MAG_EXPREF(y));
}
/* general versions */
2014-05-06 20:38:49 +02:00
void mag_mul(mag_t z, const mag_t x, const mag_t y);
void mag_mul_lower(mag_t z, const mag_t x, const mag_t y);
2014-05-06 20:38:49 +02:00
void mag_addmul(mag_t z, const mag_t x, const mag_t y);
void mag_add_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t e);
2014-05-09 16:50:01 +02:00
void mag_add(mag_t z, const mag_t x, const mag_t y);
2014-06-18 18:21:03 +02:00
void mag_add_lower(mag_t z, const mag_t x, const mag_t y);
void mag_add_ui_2exp_si(mag_t z, const mag_t x, ulong y, slong e);
2014-05-08 14:48:36 +02:00
void mag_div(mag_t z, const mag_t x, const mag_t y);
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2015-11-06 11:16:52 +00:00
mag_mul_2exp_si(mag_t z, const mag_t x, slong y)
2014-05-09 16:50:01 +02:00
{
if (mag_is_special(x))
{
mag_set(z, x);
}
else
{
if (y >= ADD2_FAST_MIN && y <= ADD2_FAST_MAX)
_fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), y);
else
fmpz_add_si(MAG_EXPREF(z), MAG_EXPREF(x), y);
2014-05-09 16:50:01 +02:00
MAG_MAN(z) = MAG_MAN(x);
}
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-05-09 16:50:01 +02:00
mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y)
{
if (mag_is_special(x))
{
mag_set(z, x);
}
else
{
_fmpz_add2_fast(MAG_EXPREF(z), MAG_EXPREF(x), y, 0);
2014-05-09 16:50:01 +02:00
MAG_MAN(z) = MAG_MAN(x);
}
}
void mag_sub_lower(mag_t z, const mag_t x, const mag_t y);
/* Fast versions (no infs/nans, small exponents). Note that this
applies to outputs too! */
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_fast_init_set(mag_t x, const mag_t y)
{
MAG_EXP(x) = MAG_EXP(y);
MAG_MAN(x) = MAG_MAN(y);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_fast_zero(mag_t x)
{
MAG_EXP(x) = 0;
MAG_MAN(x) = 0;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE int
mag_fast_is_zero(const mag_t x)
{
return MAG_MAN(x) == 0;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_fast_mul(mag_t z, const mag_t x, const mag_t y)
{
if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0)
{
mag_fast_zero(z);
}
else
{
MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + LIMB_ONE;
MAG_EXP(z) = MAG_EXP(x) + MAG_EXP(y);
2014-05-06 19:17:29 +02:00
MAG_FAST_ADJUST_ONE_TOO_SMALL(z);
}
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2015-11-06 11:16:52 +00:00
mag_fast_mul_2exp_si(mag_t z, const mag_t x, slong y)
{
if (MAG_MAN(x) == 0)
{
mag_fast_zero(z);
}
else
{
MAG_MAN(z) = MAG_MAN(x);
MAG_EXP(z) = MAG_EXP(x) + y;
}
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_fast_addmul(mag_t z, const mag_t x, const mag_t y)
{
if (MAG_MAN(z) == 0)
{
mag_fast_mul(z, x, y);
}
else if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0)
{
return;
}
else
{
2015-11-06 11:16:52 +00:00
slong shift, e;
/* x*y < 2^e */
e = MAG_EXP(x) + MAG_EXP(y);
shift = MAG_EXP(z) - e;
if (shift >= 0)
{
if (shift >= MAG_BITS)
MAG_MAN(z)++;
else
2014-05-08 14:48:36 +02:00
MAG_MAN(z) = MAG_MAN(z) + (MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) >> shift) + 1;
}
else
{
shift = -shift;
MAG_EXP(z) = e;
if (shift >= MAG_BITS)
2014-05-08 14:48:36 +02:00
MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + 2;
else
2014-05-08 14:48:36 +02:00
MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + (MAG_MAN(z) >> shift) + 2;
MAG_FAST_ADJUST_ONE_TOO_SMALL(z);
}
MAG_FAST_ADJUST_ONE_TOO_LARGE(z);
}
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2015-11-06 11:16:52 +00:00
mag_fast_add_2exp_si(mag_t z, const mag_t x, slong e)
{
/* Must be zero */
if (mag_is_special(x))
{
MAG_MAN(z) = MAG_ONE_HALF;
MAG_EXP(z) = e + 1;
}
else
{
2015-11-06 11:16:52 +00:00
slong shift;
shift = MAG_EXP(x) - e;
2014-05-08 14:48:36 +02:00
if (shift > 0)
{
MAG_EXP(z) = MAG_EXP(x);
if (shift >= MAG_BITS)
MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE;
else
MAG_MAN(z) = MAG_MAN(x) + (LIMB_ONE << (MAG_BITS - shift));
}
else
{
shift = -shift;
2014-05-08 14:48:36 +02:00
MAG_EXP(z) = e + 1;
if (shift >= MAG_BITS)
2014-05-08 14:48:36 +02:00
MAG_MAN(z) = MAG_ONE_HALF + LIMB_ONE;
else
2014-05-08 14:48:36 +02:00
MAG_MAN(z) = MAG_ONE_HALF + (MAG_MAN(x) >> (shift + 1)) + LIMB_ONE;
}
MAG_FAST_ADJUST_ONE_TOO_LARGE(z);
}
}
2014-05-13 20:43:04 +02:00
void mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp);
void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp);
2014-05-08 14:48:36 +02:00
#include "fmpr.h"
void mag_set_fmpr(mag_t x, const fmpr_t y);
void mag_get_fmpr(fmpr_t x, const mag_t r);
2014-05-09 16:50:01 +02:00
2015-11-06 11:16:52 +00:00
void mag_randtest_special(mag_t x, flint_rand_t state, slong expbits);
2014-05-14 12:04:08 +02:00
2015-11-06 11:16:52 +00:00
void mag_randtest(mag_t x, flint_rand_t state, slong expbits);
2014-05-14 12:04:08 +02:00
2015-12-31 18:26:05 -05:00
void mag_fprint(FILE * file, const mag_t x);
void mag_fprintd(FILE * file, const mag_t x, slong d);
MAG_INLINE void
mag_print(const mag_t x)
{
mag_fprint(stdout, x);
}
MAG_INLINE void
mag_printd(const mag_t x, slong d)
{
mag_fprintd(stdout, x, d);
}
void mag_get_fmpq(fmpq_t y, const mag_t x);
2014-05-16 14:04:28 +02:00
int mag_cmp(const mag_t x, const mag_t y);
2014-05-16 14:04:28 +02:00
2015-11-06 11:16:52 +00:00
int mag_cmp_2exp_si(const mag_t x, slong e);
2014-05-16 14:04:28 +02:00
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-08-15 14:03:42 +02:00
mag_min(mag_t z, const mag_t x, const mag_t y)
{
if (mag_cmp(x, y) <= 0)
mag_set(z, x);
else
mag_set(z, y);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-08-15 14:03:42 +02:00
mag_max(mag_t z, const mag_t x, const mag_t y)
{
if (mag_cmp(x, y) >= 0)
mag_set(z, x);
else
mag_set(z, y);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE mag_ptr
2015-11-06 11:16:52 +00:00
_mag_vec_init(slong n)
2014-05-26 14:24:18 +02:00
{
2015-11-06 11:16:52 +00:00
slong i;
2014-05-26 14:24:18 +02:00
mag_ptr v = (mag_ptr) flint_malloc(sizeof(mag_struct) * n);
for (i = 0; i < n; i++)
mag_init(v + i);
return v;
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2015-11-06 11:16:52 +00:00
_mag_vec_clear(mag_ptr v, slong n)
2014-05-26 14:24:18 +02:00
{
2015-11-06 11:16:52 +00:00
slong i;
2014-05-26 14:24:18 +02:00
for (i = 0; i < n; i++)
mag_clear(v + i);
flint_free(v);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void mag_set_d(mag_t z, double x)
{
fmpz_t e;
fmpz_init(e);
mag_set_d_2exp_fmpz(z, x, e);
fmpz_clear(e);
}
/* TODO: test/document */
double mag_get_d(const mag_t z);
/* TODO: document */
double mag_d_log_upper_bound(double x);
double mag_d_log_lower_bound(double x);
2014-05-26 14:24:18 +02:00
2014-06-18 16:50:15 +02:00
void mag_log1p(mag_t z, const mag_t x);
void mag_log_ui(mag_t t, ulong n);
2015-11-06 11:16:52 +00:00
void mag_exp_maglim(mag_t y, const mag_t x, slong maglim);
2014-08-14 22:09:50 +02:00
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2014-08-14 22:09:50 +02:00
mag_exp(mag_t y, const mag_t x)
{
mag_exp_maglim(y, x, 128);
}
2014-09-18 20:45:33 +02:00
void mag_expm1(mag_t y, const mag_t x);
2014-08-15 13:21:02 +02:00
void mag_exp_tail(mag_t z, const mag_t x, ulong N);
void mag_pow_ui(mag_t z, const mag_t x, ulong e);
void mag_pow_ui_lower(mag_t z, const mag_t x, ulong e);
2014-08-14 01:04:48 +02:00
void mag_pow_fmpz(mag_t z, const mag_t x, const fmpz_t e);
void mag_fac_ui(mag_t z, ulong n);
void mag_rfac_ui(mag_t z, ulong n);
2014-06-20 09:27:47 +02:00
/* TODO: test */
void mag_bernoulli_div_fac_ui(mag_t z, ulong n);
2014-06-20 09:27:47 +02:00
/* TODO: test */
void mag_set_fmpz_2exp_fmpz_lower(mag_t z, const fmpz_t man, const fmpz_t exp);
2014-07-08 21:21:28 +02:00
void mag_sqrt(mag_t y, const mag_t x);
void mag_rsqrt(mag_t y, const mag_t x);
2015-07-21 15:09:06 +02:00
void mag_root(mag_t y, const mag_t x, ulong n);
2014-12-20 22:37:43 +01:00
void mag_hypot(mag_t z, const mag_t x, const mag_t y);
void mag_binpow_uiui(mag_t b, ulong m, ulong n);
2015-11-06 11:16:52 +00:00
void mag_polylog_tail(mag_t u, const mag_t z, slong sigma, ulong d, ulong N);
2015-01-16 09:29:10 +01:00
2015-09-17 12:51:02 +02:00
void mag_geom_series(mag_t res, const mag_t x, ulong n);
2016-01-13 15:38:44 +01:00
void mag_hurwitz_zeta_uiui(mag_t res, ulong s, ulong a);
void mag_set_ui(mag_t z, ulong x);
void mag_set_ui_lower(mag_t z, ulong x);
/* TODO: test functions below */
2014-12-25 15:50:37 +01:00
MAG_INLINE void
2015-11-06 11:16:52 +00:00
mag_set_ui_2exp_si(mag_t z, ulong v, slong e)
2014-06-12 20:46:25 +02:00
{
mag_set_ui(z, v);
mag_mul_2exp_si(z, z, e);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_set_fmpz(mag_t z, const fmpz_t x)
{
fmpz_t exp;
*exp = 0;
mag_set_fmpz_2exp_fmpz(z, x, exp);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_set_fmpz_lower(mag_t z, const fmpz_t x)
{
fmpz_t exp;
*exp = 0;
mag_set_fmpz_2exp_fmpz_lower(z, x, exp);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_mul_ui(mag_t z, const mag_t x, ulong y)
{
mag_t t;
mag_init(t);
mag_set_ui(t, y);
mag_mul(z, x, t);
mag_clear(t);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_mul_ui_lower(mag_t z, const mag_t x, ulong y)
{
mag_t t;
mag_init(t);
mag_set_ui_lower(t, y);
mag_mul_lower(z, x, t);
mag_clear(t);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_mul_fmpz(mag_t z, const mag_t x, const fmpz_t y)
{
mag_t t;
mag_init(t);
mag_set_fmpz(t, y);
mag_mul(z, x, t);
mag_clear(t);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_mul_fmpz_lower(mag_t z, const mag_t x, const fmpz_t y)
{
mag_t t;
mag_init(t);
mag_set_fmpz_lower(t, y);
mag_mul_lower(z, x, t);
mag_clear(t);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_div_ui(mag_t z, const mag_t x, ulong y)
{
mag_t t;
mag_init(t);
mag_set_ui_lower(t, y);
mag_div(z, x, t);
mag_clear(t);
}
2014-12-25 15:50:37 +01:00
MAG_INLINE void
mag_div_fmpz(mag_t z, const mag_t x, const fmpz_t y)
{
mag_t t;
mag_init(t);
mag_set_fmpz_lower(t, y);
mag_div(z, x, t);
mag_clear(t);
}
#ifdef __cplusplus
}
#endif
#endif