diff --git a/doc/source/flint.rst b/doc/source/flint.rst index 6237c9f8b1..faafb352d1 100644 --- a/doc/source/flint.rst +++ b/doc/source/flint.rst @@ -59,17 +59,6 @@ The file ``flint.h`` contains various useful macros. Returns the sign of `x` where `x` is interpreted as a :type:`slong`, that is, returns `-1` if `x < 0`, `0` if `x = 0` and `1` if `x > 0`. -.. function:: flint_bitcnt_t FLINT_BIT_COUNT(ulong x) - - Returns the number of binary bits required to represent *x*. If *x* is zero - it returns *0*. This is an inline-function only. - -.. macro:: FLINT_FLOG2(x) - FLINT_CLOG2(x) - - For `x \ge 1`, it returns `\lfloor \log_2 x \rfloor` - and `\lceil \log_2 x \rceil`, respectively. - Integer types ----------------------------------------------- diff --git a/doc/source/longlong.rst b/doc/source/longlong.rst index 3c6acd21cb..e7ee6df79f 100644 --- a/doc/source/longlong.rst +++ b/doc/source/longlong.rst @@ -3,7 +3,7 @@ **longlong.h** -- support functions for multi-word arithmetic =============================================================================== -Leading and trailing zeroes +Bit manipulation ------------------------------------------------------------------------------- .. macro:: flint_clz(x) @@ -18,6 +18,17 @@ Leading and trailing zeroes As for ``flint_clz()``, but counts from the least significant end. If `x` is zero then the return value is undefined. +.. function:: flint_bitcnt_t FLINT_BIT_COUNT(ulong x) + + Returns the number of binary bits required to represent *x*. If *x* is zero + it returns *0*. This is an inline-function only. + +.. macro:: FLINT_FLOG2(x) + FLINT_CLOG2(x) + + For `x \ge 1`, it returns `\lfloor \log_2 x \rfloor` + and `\lceil \log_2 x \rceil`, respectively. + Addition and subtraction ------------------------------------------------------------------------------- diff --git a/src/bernoulli/bound_2exp_si.c b/src/bernoulli/bound_2exp_si.c index af0c25af0f..eb8741da36 100644 --- a/src/bernoulli/bound_2exp_si.c +++ b/src/bernoulli/bound_2exp_si.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "bernoulli.h" const short bernoulli_bound_tab[256] = { diff --git a/src/bool_mat/pow_ui.c b/src/bool_mat/pow_ui.c index da20321c18..8bbb6f9831 100644 --- a/src/bool_mat/pow_ui.c +++ b/src/bool_mat/pow_ui.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "bool_mat.h" void diff --git a/src/crt_helpers.h b/src/crt_helpers.h index de729d0dd9..4d54633f09 100644 --- a/src/crt_helpers.h +++ b/src/crt_helpers.h @@ -18,7 +18,7 @@ # include #endif -#include "flint.h" +#include "longlong.h" #include "templates.h" #ifdef __cplusplus diff --git a/src/d_mat/init.c b/src/d_mat/init.c index 4e4812a573..3463760027 100644 --- a/src/d_mat/init.c +++ b/src/d_mat/init.c @@ -10,6 +10,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "d_mat.h" void @@ -18,13 +19,24 @@ d_mat_init(d_mat_t mat, slong rows, slong cols) slong i; if (rows != 0) - mat->rows = (double **) flint_malloc(rows * sizeof(double *)); + mat->rows = flint_malloc(rows * sizeof(double *)); else mat->rows = NULL; - if (rows != 0 && cols != 0) /* Allocate space for r*c small entries */ + mat->r = rows; + mat->c = cols; + + if (rows != 0 && cols != 0) { - mat->entries = (double *) flint_calloc(flint_mul_sizes(rows, cols), sizeof(double)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_calloc(num, sizeof(double)); for (i = 0; i < rows; i++) mat->rows[i] = mat->entries + i * cols; @@ -35,7 +47,4 @@ d_mat_init(d_mat_t mat, slong rows, slong cols) for (i = 0; i < rows; i++) mat->rows[i] = NULL; } - - mat->r = rows; - mat->c = cols; } diff --git a/src/fft_small.h b/src/fft_small.h index e5314e728d..6552dcbcc6 100644 --- a/src/fft_small.h +++ b/src/fft_small.h @@ -12,6 +12,7 @@ #ifndef FFT_SMALL_H #define FFT_SMALL_H +#include "longlong.h" #include "machine_vectors.h" #define LG_BLK_SZ 8 diff --git a/src/flint.h.in b/src/flint.h.in index 726ccee444..8fa9fb55c6 100644 --- a/src/flint.h.in +++ b/src/flint.h.in @@ -207,8 +207,6 @@ typedef const ulong * nn_srcptr; # endif #endif -#include "longlong.h" - /* memory ********************************************************************/ FLINT_WARN_UNUSED FLINT_MALLOC FLINT_RETURNS_NONNULL void * flint_malloc(size_t size); @@ -366,25 +364,6 @@ FLINT_INLINE ulong n_randint(flint_rand_t state, ulong limit) #define FLINT_SGN(x) ((0 < (slong)(x)) - ((slong)(x) < 0)) #define FLINT_SWAP(T, x, y) do { T _swap_t = (x); (x) = (y); (y) = _swap_t; } while(0) -#define r_shift(in, shift) \ - ((shift == FLINT_BITS) ? WORD(0) : ((in) >> (shift))) - -#define l_shift(in, shift) \ - ((shift == FLINT_BITS) ? WORD(0) : ((in) << (shift))) - -/* Beware when using the unsigned return value in signed arithmetic */ -FLINT_FORCE_INLINE -flint_bitcnt_t FLINT_BIT_COUNT(ulong x) -{ - flint_bitcnt_t zeros = FLINT_BITS; - if (x) zeros = flint_clz(x); - return FLINT_BITS - zeros; -} - -#define FLINT_FLOG2(k) (FLINT_BIT_COUNT(k) - 1) - -#define FLINT_CLOG2(k) FLINT_BIT_COUNT((k) - 1) - /* allocation macros *********************************************************/ #define FLINT_ARRAY_ALLOC(n, T) (T *) flint_malloc((n)*sizeof(T)) @@ -463,20 +442,6 @@ typedef enum FLINT_NORETURN void flint_throw(flint_err_t exc, const char * msg, ...); -/* checked multiplication ****************************************************/ - -FLINT_INLINE slong flint_mul_sizes(slong x, slong y) -{ - ulong hi, lo; - - umul_ppmm(hi, lo, (ulong) x, (ulong) y); - - if (hi != 0 || lo > WORD_MAX) - flint_throw(FLINT_OVERFLOW, "Overflow creating size %wd x %wd object.\n", x, y); - - return lo; -} - /* FLINT generic type definitions ********************************************/ typedef struct diff --git a/src/fmpq_mat/init.c b/src/fmpq_mat/init.c index 2f8ebc33ff..8e93f16439 100644 --- a/src/fmpq_mat/init.c +++ b/src/fmpq_mat/init.c @@ -10,6 +10,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "fmpq_mat.h" void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols) @@ -17,13 +18,24 @@ void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols) slong i; if (rows != 0) - mat->rows = (fmpq **) flint_malloc(rows * sizeof(fmpq *)); + mat->rows = flint_malloc(rows * sizeof(fmpq *)); else mat->rows = NULL; + mat->r = rows; + mat->c = cols; + if (rows != 0 && cols != 0) { - mat->entries = (fmpq *) flint_calloc(flint_mul_sizes(rows, cols), sizeof(fmpq)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_calloc(num, sizeof(fmpq)); /* Set denominators */ for (i = 0; i < rows * cols; i++) @@ -41,7 +53,4 @@ void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols) mat->rows[i] = NULL; } } - - mat->r = rows; - mat->c = cols; } diff --git a/src/fmpz.h b/src/fmpz.h index a79a6f1c9e..12848a7bdb 100644 --- a/src/fmpz.h +++ b/src/fmpz.h @@ -20,6 +20,7 @@ #include #include "fmpz_types.h" +#include "longlong.h" #ifdef __cplusplus extern "C" { diff --git a/src/fmpz_lll/mpf-impl.c b/src/fmpz_lll/mpf-impl.c index 8094adb349..743e8ad6e1 100644 --- a/src/fmpz_lll/mpf-impl.c +++ b/src/fmpz_lll/mpf-impl.c @@ -10,6 +10,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "gmpcompat.h" #include "mpf-impl.h" #include "fmpz.h" @@ -108,10 +109,22 @@ _mpf_vec_dot2(mpf_t res, const mpf * vec1, const mpf * vec2, slong len2, flint_b void mpf_mat_init(mpf_mat_t mat, slong rows, slong cols, flint_bitcnt_t prec) { + mat->r = rows; + mat->c = cols; + mat->prec = prec; + if (rows != 0 && cols != 0) { slong i; - mat->entries = flint_malloc(flint_mul_sizes(rows, cols) * sizeof(mpf)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_malloc(num * sizeof(mpf)); mat->rows = flint_malloc(rows * sizeof(mpf *)); for (i = 0; i < rows * cols; i++) @@ -124,10 +137,6 @@ mpf_mat_init(mpf_mat_t mat, slong rows, slong cols, flint_bitcnt_t prec) mat->entries = NULL; mat->rows = NULL; } - - mat->r = rows; - mat->c = cols; - mat->prec = prec; } void mpf_mat_clear(mpf_mat_t mat) diff --git a/src/fmpz_mat/fflu.c b/src/fmpz_mat/fflu.c index c1dce2f497..8a00ade89d 100644 --- a/src/fmpz_mat/fflu.c +++ b/src/fmpz_mat/fflu.c @@ -15,6 +15,8 @@ #define E(j,k) fmpz_mat_entry(B,j,k) +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + slong fmpz_mat_fflu(fmpz_mat_t B, fmpz_t den, slong * perm, const fmpz_mat_t A, int rank_check) diff --git a/src/fmpz_mat/init.c b/src/fmpz_mat/init.c index cd93d80300..b31989f6ce 100644 --- a/src/fmpz_mat/init.c +++ b/src/fmpz_mat/init.c @@ -10,6 +10,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "fmpz_mat.h" void @@ -18,13 +19,24 @@ fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols) slong i; if (rows != 0) - mat->rows = (fmpz **) flint_malloc(rows * sizeof(fmpz *)); + mat->rows = flint_malloc(rows * sizeof(fmpz *)); else mat->rows = NULL; - if (rows != 0 && cols != 0) /* Allocate space for r*c small entries */ + mat->r = rows; + mat->c = cols; + + if (rows != 0 && cols != 0) { - mat->entries = (fmpz *) flint_calloc(flint_mul_sizes(rows, cols), sizeof(fmpz)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_calloc(num, sizeof(fmpz)); for (i = 0; i < rows; i++) mat->rows[i] = mat->entries + i * cols; @@ -35,9 +47,6 @@ fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols) for (i = 0; i < rows; i++) mat->rows[i] = NULL; } - - mat->r = rows; - mat->c = cols; } void diff --git a/src/fmpz_mat/mul.c b/src/fmpz_mat/mul.c index fb59a2e8b1..72fb4e62e2 100644 --- a/src/fmpz_mat/mul.c +++ b/src/fmpz_mat/mul.c @@ -13,6 +13,10 @@ #include "fmpz.h" #include "fmpz_mat.h" +#if FLINT_USES_BLAS +# include "longlong.h" +#endif + void _fmpz_mat_mul_small_1(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) { slong ar, br, bc; diff --git a/src/fmpz_mat/mul_blas.c b/src/fmpz_mat/mul_blas.c index 853ab28e27..74e295d6a2 100644 --- a/src/fmpz_mat/mul_blas.c +++ b/src/fmpz_mat/mul_blas.c @@ -10,6 +10,7 @@ */ #include "fmpz_mat.h" +#include "longlong.h" /* todo: squaring optimizations */ diff --git a/src/fmpz_mat/solve_fflu_precomp.c b/src/fmpz_mat/solve_fflu_precomp.c index 3f09d242eb..bc7a623369 100644 --- a/src/fmpz_mat/solve_fflu_precomp.c +++ b/src/fmpz_mat/solve_fflu_precomp.c @@ -20,6 +20,8 @@ #define BB(ii,jj) fmpz_mat_entry(B,(ii),(jj)) #define LU(ii,jj) fmpz_mat_entry(FFLU,(ii),(jj)) +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + void fmpz_mat_set_perm(fmpz_mat_t X, const slong * perm, const fmpz_mat_t B) { diff --git a/src/fmpz_mod_poly/frobenius_powers_2exp_precomp.c b/src/fmpz_mod_poly/frobenius_powers_2exp_precomp.c index 00bd7a31bf..403b257844 100644 --- a/src/fmpz_mod_poly/frobenius_powers_2exp_precomp.c +++ b/src/fmpz_mod_poly/frobenius_powers_2exp_precomp.c @@ -11,6 +11,7 @@ #include "fmpz_mod.h" #include "fmpz_mod_poly.h" +#include "longlong.h" void fmpz_mod_poly_frobenius_powers_2exp_precomp( fmpz_mod_poly_frobenius_powers_2exp_t pow, const fmpz_mod_poly_t f, diff --git a/src/fmpz_mpoly.h b/src/fmpz_mpoly.h index 1282ce497d..0714db2949 100644 --- a/src/fmpz_mpoly.h +++ b/src/fmpz_mpoly.h @@ -19,6 +19,7 @@ #define FMPZ_MPOLY_INLINE static inline #endif +#include "longlong.h" #include "mpoly_types.h" #ifdef __cplusplus diff --git a/src/fmpz_poly_mat/init.c b/src/fmpz_poly_mat/init.c index e659a2e65e..af0985100e 100644 --- a/src/fmpz_poly_mat/init.c +++ b/src/fmpz_poly_mat/init.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "fmpz_poly.h" #include "fmpz_poly_mat.h" @@ -18,13 +19,24 @@ fmpz_poly_mat_init(fmpz_poly_mat_t A, slong rows, slong cols) slong i; if (rows != 0) - A->rows = (fmpz_poly_struct **) flint_malloc(rows * sizeof(fmpz_poly_struct *)); + A->rows = flint_malloc(rows * sizeof(fmpz_poly_struct *)); else A->rows = NULL; + A->r = rows; + A->c = cols; + if (rows != 0 && cols != 0) { - A->entries = (fmpz_poly_struct *) flint_malloc(flint_mul_sizes(rows, cols) * sizeof(fmpz_poly_struct)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + A->entries = flint_malloc(num * sizeof(fmpz_poly_struct)); for (i = 0; i < rows * cols; i++) fmpz_poly_init(A->entries + i); @@ -41,9 +53,6 @@ fmpz_poly_mat_init(fmpz_poly_mat_t A, slong rows, slong cols) A->rows[i] = NULL; } } - - A->r = rows; - A->c = cols; } void diff --git a/src/fmpz_poly_mat/mul_KS.c b/src/fmpz_poly_mat/mul_KS.c index 0b078be36a..317ad7c745 100644 --- a/src/fmpz_poly_mat/mul_KS.c +++ b/src/fmpz_poly_mat/mul_KS.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "longlong.h" #include "fmpz_poly.h" #include "fmpz_poly_mat.h" #include "fmpz_mat.h" diff --git a/src/fmpz_poly_mat/pow.c b/src/fmpz_poly_mat/pow.c index 30496641bd..d71ef535d2 100644 --- a/src/fmpz_poly_mat/pow.c +++ b/src/fmpz_poly_mat/pow.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "longlong.h" #include "fmpz_poly.h" #include "fmpz_poly_mat.h" diff --git a/src/fmpz_poly_mat/pow_trunc.c b/src/fmpz_poly_mat/pow_trunc.c index fec2df17eb..09642fdf07 100644 --- a/src/fmpz_poly_mat/pow_trunc.c +++ b/src/fmpz_poly_mat/pow_trunc.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "longlong.h" #include "fmpz_poly.h" #include "fmpz_poly_mat.h" diff --git a/src/fmpz_poly_mat/sqr_KS.c b/src/fmpz_poly_mat/sqr_KS.c index 030073822b..bf875a4975 100644 --- a/src/fmpz_poly_mat/sqr_KS.c +++ b/src/fmpz_poly_mat/sqr_KS.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "longlong.h" #include "fmpz_poly.h" #include "fmpz_poly_mat.h" #include "fmpz_mat.h" diff --git a/src/fq_mat_templates/init.c b/src/fq_mat_templates/init.c index 59d71e8324..78662bceb3 100644 --- a/src/fq_mat_templates/init.c +++ b/src/fq_mat_templates/init.c @@ -11,50 +11,51 @@ */ #ifdef T - +#include "long_extras.h" #include "templates.h" void -TEMPLATE(T, mat_init) (TEMPLATE(T, mat_t) mat, slong rows, slong cols, +TEMPLATE(T, mat_init)(TEMPLATE(T, mat_t) mat, slong rows, slong cols, const TEMPLATE(T, ctx_t) ctx) { slong i; + mat->r = rows; + mat->c = cols; + if (rows != 0) - mat->rows = (TEMPLATE(T, struct) **) flint_malloc(rows - * sizeof(TEMPLATE(T, struct) *)); + mat->rows = flint_malloc(rows * sizeof(TEMPLATE(T, struct) *)); else mat->rows = NULL; - if (rows != 0 && cols != 0) /* Allocate space for r*c small entries */ + if (rows != 0 && cols != 0) { slong j; + slong num; + int of; - mat->entries = (TEMPLATE(T, struct) *) flint_malloc(flint_mul_sizes(rows, cols) - * sizeof(TEMPLATE(T, struct))); + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_malloc(num * sizeof(TEMPLATE(T, struct))); for (i = 0; i < rows; i++) { mat->rows[i] = mat->entries + i * cols; for (j = 0; j < cols; j++) - { TEMPLATE(T, init) (mat->rows[i] + j, ctx); - } } } else { mat->entries = NULL; - if (rows != 0) - { + if (rows != 0) + { for (i = 0; i < rows; i++) mat->rows[i] = NULL; - } + } } - - mat->r = rows; - mat->c = cols; } - - #endif diff --git a/src/fq_nmod_mpoly_factor/n_bpoly_fq_factor_smprime.c b/src/fq_nmod_mpoly_factor/n_bpoly_fq_factor_smprime.c index a4cc35e13b..55da43afd4 100644 --- a/src/fq_nmod_mpoly_factor/n_bpoly_fq_factor_smprime.c +++ b/src/fq_nmod_mpoly_factor/n_bpoly_fq_factor_smprime.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "fq_nmod.h" #include "nmod_mat.h" #include "fmpz_poly_factor.h" diff --git a/src/gmpcompat-longlong.h.in b/src/gmpcompat-longlong.h.in index 2c905a8d5c..7eb489a172 100644 --- a/src/gmpcompat-longlong.h.in +++ b/src/gmpcompat-longlong.h.in @@ -13,7 +13,7 @@ #define GMP_COMPAT_H #include -#include "flint.h" +#include "longlong.h" #define FLINT_MPZ_REALLOC(z, len) \ ((len) > ((z)->_mp_alloc) \ diff --git a/src/gmpcompat.h.in b/src/gmpcompat.h.in index 3ed3980e3a..2973ee9f3d 100644 --- a/src/gmpcompat.h.in +++ b/src/gmpcompat.h.in @@ -13,7 +13,7 @@ #define GMP_COMPAT_H #include -#include "flint.h" +#include "longlong.h" #define FLINT_MPZ_REALLOC(z, len) \ ((len) > ((z)->_mp_alloc) \ diff --git a/src/gr_mat/init.c b/src/gr_mat/init.c index 79bfd71f80..ebc9a14528 100644 --- a/src/gr_mat/init.c +++ b/src/gr_mat/init.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "gr_mat.h" void @@ -18,6 +19,9 @@ gr_mat_init(gr_mat_t mat, slong rows, slong cols, gr_ctx_t ctx) sz = ctx->sizeof_elem; + mat->r = rows; + mat->c = cols; + if (rows != 0) mat->rows = flint_malloc(rows * sizeof(gr_ptr)); else @@ -25,7 +29,15 @@ gr_mat_init(gr_mat_t mat, slong rows, slong cols, gr_ctx_t ctx) if (rows != 0 && cols != 0) { - mat->entries = (gr_ptr) flint_malloc(flint_mul_sizes(rows, cols) * sz); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_malloc(num * sz); _gr_vec_init(mat->entries, rows * cols, ctx); @@ -38,7 +50,4 @@ gr_mat_init(gr_mat_t mat, slong rows, slong cols, gr_ctx_t ctx) for (i = 0; i < rows; i++) mat->rows[i] = NULL; } - - mat->r = rows; - mat->c = cols; } diff --git a/src/gr_poly/evaluate_vec_fast.c b/src/gr_poly/evaluate_vec_fast.c index 1d6c4224d2..6ddef31af3 100644 --- a/src/gr_poly/evaluate_vec_fast.c +++ b/src/gr_poly/evaluate_vec_fast.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "gr_vec.h" #include "gr_poly.h" diff --git a/src/gr_poly/hgcd.c b/src/gr_poly/hgcd.c index 1eafaa7779..98c2abb5e9 100644 --- a/src/gr_poly/hgcd.c +++ b/src/gr_poly/hgcd.c @@ -11,6 +11,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "gr_poly.h" #include "gr_vec.h" diff --git a/src/gr_poly/pow_ui_binexp.c b/src/gr_poly/pow_ui_binexp.c index 0f530e19cd..7ae26c001e 100644 --- a/src/gr_poly/pow_ui_binexp.c +++ b/src/gr_poly/pow_ui_binexp.c @@ -9,6 +9,7 @@ (at your option) any later version. See . */ +#include "longlong.h" #include "gr_vec.h" #include "gr_poly.h" diff --git a/src/long_extras.h b/src/long_extras.h index c916714399..31fa391829 100644 --- a/src/long_extras.h +++ b/src/long_extras.h @@ -18,7 +18,7 @@ #define LONG_EXTRAS_INLINE static inline #endif -#include "flint.h" +#include "longlong.h" #ifdef __cplusplus extern "C" { @@ -32,19 +32,25 @@ size_t z_sizeinbase(slong n, int b); LONG_EXTRAS_INLINE int z_mul_checked(slong * a, slong b, slong c) { - /* TODO __builtin_mul_overflow */ +#if defined(__GNUC__) + return __builtin_mul_overflow(b, c, a); +#else ulong ahi, alo; smul_ppmm(ahi, alo, b, c); *a = alo; return FLINT_SIGN_EXT(alo) != ahi; +#endif } LONG_EXTRAS_INLINE int z_add_checked(slong * a, slong b, slong c) { - /* TODO __builtin_add_overflow */ +#if defined(__GNUC__) + return __builtin_add_overflow(b, c, a); +#else int of = (b > 0 && c > WORD_MAX - b) || (b < 0 && c < WORD_MIN - b); *a = b + c; return of; +#endif } LONG_EXTRAS_INLINE diff --git a/src/longlong.h b/src/longlong.h index 3fc7808923..5704a570b4 100644 --- a/src/longlong.h +++ b/src/longlong.h @@ -19,6 +19,8 @@ #ifndef FLINT_LONGLONG_H #define FLINT_LONGLONG_H +#include "flint.h" + #ifdef __cplusplus extern "C" { #endif @@ -92,6 +94,18 @@ static inline int flint_ctz(ulong x) } #endif +/* Beware when using the unsigned return value in signed arithmetic */ +FLINT_FORCE_INLINE +flint_bitcnt_t FLINT_BIT_COUNT(ulong x) +{ + flint_bitcnt_t zeros = FLINT_BITS; + if (x) zeros = flint_clz(x); + return FLINT_BITS - zeros; +} + +#define FLINT_FLOG2(k) (FLINT_BIT_COUNT(k) - 1) +#define FLINT_CLOG2(k) FLINT_BIT_COUNT((k) - 1) + /* Addition and subtraction */ #if !defined(add_ssaaaa) # define add_ssaaaa(s1, s0, a1, a0, b1, b0) \ diff --git a/src/mpfr_mat/init.c b/src/mpfr_mat/init.c index 13237ff493..4904cf3622 100644 --- a/src/mpfr_mat/init.c +++ b/src/mpfr_mat/init.c @@ -10,19 +10,29 @@ */ #include -#include "flint.h" +#include "long_extras.h" #include "mpfr_mat.h" void mpfr_mat_init(mpfr_mat_t mat, slong rows, slong cols, mpfr_prec_t prec) { + mat->r = rows; + mat->c = cols; + mat->prec = prec; - if (rows != 0 && cols != 0) /* Allocate space for r*c small entries */ + if (rows != 0 && cols != 0) { slong i; - mat->entries = - (__mpfr_struct *) flint_malloc(flint_mul_sizes(rows, cols) * sizeof(__mpfr_struct)); - mat->rows = (__mpfr_struct **) flint_malloc(rows * sizeof(__mpfr_struct *)); /* Initialise rows */ + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_malloc(num * sizeof(__mpfr_struct)); + mat->rows = flint_malloc(rows * sizeof(__mpfr_struct *)); for (i = 0; i < rows * cols; i++) mpfr_init2(mat->entries + i, prec); @@ -31,8 +41,4 @@ mpfr_mat_init(mpfr_mat_t mat, slong rows, slong cols, mpfr_prec_t prec) } else mat->entries = NULL; - - mat->r = rows; - mat->c = cols; - mat->prec = prec; } diff --git a/src/mpn_extras.h b/src/mpn_extras.h index 0393e85043..64ffc2bb7f 100644 --- a/src/mpn_extras.h +++ b/src/mpn_extras.h @@ -22,7 +22,7 @@ #endif #include -#include "flint.h" +#include "longlong.h" #ifdef __cplusplus extern "C" { diff --git a/src/mpoly.h b/src/mpoly.h index 45ac5175ef..14dfbeb92f 100644 --- a/src/mpoly.h +++ b/src/mpoly.h @@ -21,6 +21,7 @@ #include #include +#include "longlong.h" #include "mpoly_types.h" #ifdef __cplusplus diff --git a/src/mpoly/test/t-pack_unpack.c b/src/mpoly/test/t-pack_unpack.c index a9af811b0a..ac98bd0e10 100644 --- a/src/mpoly/test/t-pack_unpack.c +++ b/src/mpoly/test/t-pack_unpack.c @@ -13,6 +13,9 @@ #include "ulong_extras.h" #include "mpoly.h" +#define l_shift(in, shift) \ + ((shift == FLINT_BITS) ? WORD(0) : ((in) << (shift))) + TEST_FUNCTION_START(mpoly_pack_unpack, state) { slong k, i, length, nfields, bits1, bits2; diff --git a/src/nmod.h b/src/nmod.h index 13f61f7bc0..ecaafcf6b2 100644 --- a/src/nmod.h +++ b/src/nmod.h @@ -27,74 +27,75 @@ extern "C" { #endif #define NMOD_RED2(r, a_hi, a_lo, mod) \ - do { \ - ulong q0xx, q1xx, r1xx; \ - const ulong u1xx = ((a_hi)<<(mod).norm) + r_shift((a_lo), FLINT_BITS - (mod).norm); \ - const ulong u0xx = ((a_lo)<<(mod).norm); \ - const ulong nxx = ((mod).n<<(mod).norm); \ - umul_ppmm(q1xx, q0xx, (mod).ninv, u1xx); \ - add_ssaaaa(q1xx, q0xx, q1xx, q0xx, u1xx, u0xx); \ - r1xx = (u0xx - (q1xx + 1)*nxx); \ - if (r1xx > q0xx) r1xx += nxx; \ - if (r1xx < nxx) r = (r1xx>>(mod).norm); \ - else r = ((r1xx - nxx)>>(mod).norm); \ - } while (0) + do { \ + ulong q0xx, q1xx, r1xx; \ + const ulong u1xx = ((a_hi)<<(mod).norm) \ + + (((mod).norm == 0) ? WORD(0) : (a_lo)>>(FLINT_BITS - (mod).norm)); \ + const ulong u0xx = (a_lo)<<(mod).norm; \ + const ulong nxx = (mod).n<<(mod).norm; \ + umul_ppmm(q1xx, q0xx, (mod).ninv, u1xx); \ + add_ssaaaa(q1xx, q0xx, q1xx, q0xx, u1xx, u0xx); \ + r1xx = (u0xx - (q1xx + 1)*nxx); \ + if (r1xx > q0xx) r1xx += nxx; \ + if (r1xx < nxx) r = (r1xx>>(mod).norm); \ + else r = ((r1xx - nxx)>>(mod).norm); \ + } while (0) #define NMOD_RED(r, a, mod) \ - do { \ - NMOD_RED2(r, 0, a, mod); \ - } while (0) + do { \ + NMOD_RED2(r, 0, a, mod); \ + } while (0) #define NMOD2_RED2(r, a_hi, a_lo, mod) \ - do { \ - ulong v_hi; \ - NMOD_RED(v_hi, a_hi, mod); \ - NMOD_RED2(r, v_hi, a_lo, mod); \ - } while (0) + do { \ + ulong v_hi; \ + NMOD_RED(v_hi, a_hi, mod); \ + NMOD_RED2(r, v_hi, a_lo, mod); \ + } while (0) #define NMOD_RED3(r, a_hi, a_me, a_lo, mod) \ - do { \ - ulong v_hi; \ - NMOD_RED2(v_hi, a_hi, a_me, mod); \ - NMOD_RED2(r, v_hi, a_lo, mod); \ - } while (0) + do { \ + ulong v_hi; \ + NMOD_RED2(v_hi, a_hi, a_me, mod); \ + NMOD_RED2(r, v_hi, a_lo, mod); \ + } while (0) #define NMOD_BITS(mod) (FLINT_BITS - ((mod).norm)) #define NMOD_CAN_USE_SHOUP(mod) ((mod).norm > 0) #define NMOD_MUL_PRENORM(res, a, b, mod) \ - do { \ - ulong q0xx, q1xx, rxx, p_hixx, p_loxx; \ - ulong nxx, ninvxx; \ - unsigned int normxx; \ - ninvxx = (mod).ninv; \ - normxx = (mod).norm; \ - nxx = (mod).n << normxx; \ - umul_ppmm(p_hixx, p_loxx, (a), (b)); \ - umul_ppmm(q1xx, q0xx, ninvxx, p_hixx); \ - add_ssaaaa(q1xx, q0xx, q1xx, q0xx, p_hixx, p_loxx); \ - rxx = (p_loxx - (q1xx + 1) * nxx); \ - if (rxx > q0xx) \ - rxx += nxx; \ - rxx = (rxx < nxx ? rxx : rxx - nxx) >> normxx; \ - (res) = rxx; \ - } while (0) + do { \ + ulong q0xx, q1xx, rxx, p_hixx, p_loxx; \ + ulong nxx, ninvxx; \ + unsigned int normxx; \ + ninvxx = (mod).ninv; \ + normxx = (mod).norm; \ + nxx = (mod).n << normxx; \ + umul_ppmm(p_hixx, p_loxx, (a), (b)); \ + umul_ppmm(q1xx, q0xx, ninvxx, p_hixx); \ + add_ssaaaa(q1xx, q0xx, q1xx, q0xx, p_hixx, p_loxx); \ + rxx = (p_loxx - (q1xx + 1) * nxx); \ + if (rxx > q0xx) \ + rxx += nxx; \ + rxx = (rxx < nxx ? rxx : rxx - nxx) >> normxx; \ + (res) = rxx; \ + } while (0) #define NMOD_MUL_FULLWORD(res, a, b, mod) \ - do { \ - ulong q0xx, q1xx, rxx, p_hixx, p_loxx; \ - ulong nxx, ninvxx; \ - ninvxx = (mod).ninv; \ - nxx = (mod).n; \ - umul_ppmm(p_hixx, p_loxx, (a), (b)); \ - umul_ppmm(q1xx, q0xx, ninvxx, p_hixx); \ - add_ssaaaa(q1xx, q0xx, q1xx, q0xx, p_hixx, p_loxx); \ - rxx = (p_loxx - (q1xx + 1) * nxx); \ - if (rxx > q0xx) \ - rxx += nxx; \ - rxx = (rxx < nxx ? rxx : rxx - nxx); \ - (res) = rxx; \ - } while (0) + do { \ + ulong q0xx, q1xx, rxx, p_hixx, p_loxx; \ + ulong nxx, ninvxx; \ + ninvxx = (mod).ninv; \ + nxx = (mod).n; \ + umul_ppmm(p_hixx, p_loxx, (a), (b)); \ + umul_ppmm(q1xx, q0xx, ninvxx, p_hixx); \ + add_ssaaaa(q1xx, q0xx, q1xx, q0xx, p_hixx, p_loxx); \ + rxx = (p_loxx - (q1xx + 1) * nxx); \ + if (rxx > q0xx) \ + rxx += nxx; \ + rxx = (rxx < nxx ? rxx : rxx - nxx); \ + (res) = rxx; \ + } while (0) NMOD_INLINE ulong nmod_set_ui(ulong x, nmod_t mod) { diff --git a/src/nmod_mat/init.c b/src/nmod_mat/init.c index 8f327857e8..822639c83d 100644 --- a/src/nmod_mat/init.c +++ b/src/nmod_mat/init.c @@ -10,6 +10,7 @@ (at your option) any later version. See . */ +#include "long_extras.h" #include "mpn_extras.h" #include "nmod_mat.h" @@ -19,13 +20,24 @@ nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, ulong n) slong i; if (rows != 0) - mat->rows = (ulong **) flint_malloc(rows * sizeof(ulong *)); + mat->rows = flint_malloc(rows * sizeof(ulong *)); else mat->rows = NULL; + mat->r = rows; + mat->c = cols; + if (rows != 0 && cols != 0) { - mat->entries = (ulong *) flint_calloc(flint_mul_sizes(rows, cols), sizeof(ulong)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_calloc(num, sizeof(ulong)); for (i = 0; i < rows; i++) mat->rows[i] = mat->entries + i * cols; @@ -33,16 +45,13 @@ nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, ulong n) else { mat->entries = NULL; - if (rows != 0) + if (rows != 0) { for (i = 0; i < rows; i++) mat->rows[i] = NULL; } } - mat->r = rows; - mat->c = cols; - nmod_mat_set_mod(mat, n); } @@ -58,9 +67,22 @@ nmod_mat_init_set(nmod_mat_t mat, const nmod_mat_t src) else mat->rows = NULL; - if ((rows) && (cols)) + mat->r = rows; + mat->c = cols; + + mat->mod = src->mod; + + if (rows != 0 && cols != 0) { - mat->entries = flint_malloc(flint_mul_sizes(rows, cols) * sizeof(ulong)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + mat->entries = flint_malloc(num * sizeof(ulong)); for (i = 0; i < rows; i++) { @@ -71,15 +93,10 @@ nmod_mat_init_set(nmod_mat_t mat, const nmod_mat_t src) else { mat->entries = NULL; - if (rows != 0) + if (rows != 0) { for (i = 0; i < rows; i++) mat->rows[i] = NULL; - } + } } - - mat->r = rows; - mat->c = cols; - - mat->mod = src->mod; } diff --git a/src/nmod_mat/mul.c b/src/nmod_mat/mul.c index e5810a2f67..245a536ad5 100644 --- a/src/nmod_mat/mul.c +++ b/src/nmod_mat/mul.c @@ -15,6 +15,7 @@ #include "thread_support.h" #if FLINT_USES_BLAS +# include "longlong.h" # include "cblas.h" #endif diff --git a/src/nmod_poly/bit_pack.c b/src/nmod_poly/bit_pack.c index c29bc9bc1a..c20cf56bb0 100644 --- a/src/nmod_poly/bit_pack.c +++ b/src/nmod_poly/bit_pack.c @@ -14,6 +14,8 @@ #include "nmod_poly.h" #include "fmpz.h" +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + /* Assumes length > 0, bits > 0. */ void _nmod_poly_bit_pack(nn_ptr res, nn_srcptr poly, slong len, flint_bitcnt_t bits) diff --git a/src/nmod_poly/get_str.c b/src/nmod_poly/get_str.c index 0e166f2e29..1e390bd935 100644 --- a/src/nmod_poly/get_str.c +++ b/src/nmod_poly/get_str.c @@ -13,6 +13,7 @@ #include #include #include "nmod_poly.h" +#include "longlong.h" char * nmod_poly_get_str(const nmod_poly_t poly) { diff --git a/src/nmod_poly/mulhigh.c b/src/nmod_poly/mulhigh.c index a25a1d3ae0..bd42557af1 100644 --- a/src/nmod_poly/mulhigh.c +++ b/src/nmod_poly/mulhigh.c @@ -10,6 +10,7 @@ */ #include "nmod_poly.h" +#include "longlong.h" void _nmod_poly_mulhigh(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong n, nmod_t mod) diff --git a/src/nmod_poly_factor/factor.c b/src/nmod_poly_factor/factor.c index 9346fc859a..927829bae8 100644 --- a/src/nmod_poly_factor/factor.c +++ b/src/nmod_poly_factor/factor.c @@ -13,6 +13,7 @@ */ #include +#include "longlong.h" #include "nmod_poly.h" #include "nmod_poly_factor.h" diff --git a/src/nmod_poly_mat/init.c b/src/nmod_poly_mat/init.c index 518b9fda3f..334c11611f 100644 --- a/src/nmod_poly_mat/init.c +++ b/src/nmod_poly_mat/init.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "long_extras.h" #include "nmod_poly.h" #include "nmod_poly_mat.h" @@ -19,13 +19,25 @@ nmod_poly_mat_init(nmod_poly_mat_t A, slong rows, slong cols, ulong n) slong i; if (rows > 0) - A->rows = (nmod_poly_struct **) flint_malloc(rows * sizeof(nmod_poly_struct *)); + A->rows = flint_malloc(rows * sizeof(nmod_poly_struct *)); else A->rows = NULL; + A->modulus = n; + A->r = rows; + A->c = cols; + if (rows > 0 && cols > 0) { - A->entries = (nmod_poly_struct *) flint_malloc(flint_mul_sizes(rows, cols) * sizeof(nmod_poly_struct)); + slong num; + int of; + + of = z_mul_checked(&num, rows, cols); + + if (of) + flint_throw(FLINT_ERROR, "Overflow creating a %wd x %wd object\n", rows, cols); + + A->entries = flint_malloc(num * sizeof(nmod_poly_struct)); for (i = 0; i < rows * cols; i++) nmod_poly_init(A->entries + i, n); @@ -36,14 +48,10 @@ nmod_poly_mat_init(nmod_poly_mat_t A, slong rows, slong cols, ulong n) else { A->entries = NULL; - if (rows > 0) + if (rows > 0) { for (i = 0; i < rows; i++) A->rows[i] = NULL; } } - - A->modulus = n; - A->r = rows; - A->c = cols; } diff --git a/src/nmod_poly_mat/pow.c b/src/nmod_poly_mat/pow.c index 5a899488c7..546b2f9f55 100644 --- a/src/nmod_poly_mat/pow.c +++ b/src/nmod_poly_mat/pow.c @@ -9,7 +9,7 @@ (at your option) any later version. See . */ -#include "flint.h" +#include "longlong.h" #include "nmod_poly.h" #include "nmod_poly_mat.h" diff --git a/src/nmod_vec/max_bits.c b/src/nmod_vec/max_bits.c index b9fed615c0..8d60ccc312 100644 --- a/src/nmod_vec/max_bits.c +++ b/src/nmod_vec/max_bits.c @@ -11,6 +11,7 @@ */ #include "nmod_vec.h" +#include "longlong.h" flint_bitcnt_t _nmod_vec_max_bits(nn_srcptr vec, slong len) { diff --git a/src/test/t-flint_clz.c b/src/test/t-flint_clz.c index 23af381085..9027caca8a 100644 --- a/src/test/t-flint_clz.c +++ b/src/test/t-flint_clz.c @@ -12,6 +12,8 @@ #include "ulong_extras.h" #include "test_helpers.h" +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + TEST_FUNCTION_START(flint_clz, state) { int i, result; @@ -19,14 +21,16 @@ TEST_FUNCTION_START(flint_clz, state) for (i = 0; i < 100000 * flint_test_multiplier(); i++) { ulong n; - unsigned int count = 0; + unsigned int count; n = n_randtest(state); - if (n != 0) - count = flint_clz(n); + if (n == 0) + continue; + + count = flint_clz(n); - result = ((n == UWORD(0)) || (((slong)(n << count) < WORD(0)) && (r_shift(n, FLINT_BITS-count) == UWORD(0)))); + result = ((slong)(n << count) < WORD(0)) && (r_shift(n, FLINT_BITS-count) == UWORD(0)); if (!result) TEST_FUNCTION_FAIL("n = %wu, count = %u\n", n, count); } diff --git a/src/test/t-flint_ctz.c b/src/test/t-flint_ctz.c index 472165ee34..24029e001d 100644 --- a/src/test/t-flint_ctz.c +++ b/src/test/t-flint_ctz.c @@ -12,6 +12,9 @@ #include "ulong_extras.h" #include "test_helpers.h" +#define l_shift(in, shift) \ + ((shift == FLINT_BITS) ? WORD(0) : ((in) << (shift))) + TEST_FUNCTION_START(flint_ctz, state) { int i, result; @@ -19,14 +22,16 @@ TEST_FUNCTION_START(flint_ctz, state) for (i = 0; i < 100000 * flint_test_multiplier(); i++) { ulong n; - unsigned int count = 0; + unsigned int count; n = n_randtest(state); - if (n != 0) - count = flint_ctz(n); + if (n == 0) + continue; + + count = flint_ctz(n); - result = ((n == UWORD(0)) || (((n >> count) & UWORD(1)) && (l_shift(n, FLINT_BITS-count) == UWORD(0)))); + result = ((n >> count) & UWORD(1)) && (l_shift(n, FLINT_BITS-count) == UWORD(0)); if (!result) TEST_FUNCTION_FAIL("n = %wu, count = %u\n", n, count); } diff --git a/src/ulong_extras.h b/src/ulong_extras.h index b3d392e443..729e83dbec 100644 --- a/src/ulong_extras.h +++ b/src/ulong_extras.h @@ -23,6 +23,7 @@ #endif #include "limb_types.h" +#include "longlong.h" #ifdef __cplusplus extern "C" { @@ -116,24 +117,36 @@ ulong n_CRT(ulong r1, ulong m1, ulong r2, ulong m2); ULONG_EXTRAS_INLINE int n_mul_checked(ulong * a, ulong b, ulong c) { +#if defined(__GNUC__) + return __builtin_mul_overflow(b, c, a); +#else ulong ahi, alo; umul_ppmm(ahi, alo, b, c); *a = alo; return 0 != ahi; +#endif } ULONG_EXTRAS_INLINE int n_add_checked(ulong * a, ulong b, ulong c) { +#if defined(__GNUC__) + return __builtin_add_overflow(b, c, a); +#else int of = b + c < b; *a = b + c; return of; +#endif } ULONG_EXTRAS_INLINE int n_sub_checked(ulong * a, ulong b, ulong c) { +#if defined(__GNUC__) + return __builtin_sub_overflow(b, c, a); +#else int of = b < c; *a = b - c; return of; +#endif } /* Modular arithmetic ********************************************************/ diff --git a/src/ulong_extras/div2_preinv.c b/src/ulong_extras/div2_preinv.c index e0206b35a2..aa749d834f 100644 --- a/src/ulong_extras/div2_preinv.c +++ b/src/ulong_extras/div2_preinv.c @@ -18,6 +18,8 @@ https://gmplib.org/~tege/division-paper.pdf */ +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong n_div2_preinv(ulong a, ulong n, ulong ninv) { diff --git a/src/ulong_extras/divrem2_preinv.c b/src/ulong_extras/divrem2_preinv.c index 23e4a0ca24..248c7c0ec6 100644 --- a/src/ulong_extras/divrem2_preinv.c +++ b/src/ulong_extras/divrem2_preinv.c @@ -18,6 +18,8 @@ https://gmplib.org/~tege/division-paper.pdf */ +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong n_divrem2_preinv(ulong * q, ulong a, ulong n, ulong ninv) { diff --git a/src/ulong_extras/factor_SQUFOF.c b/src/ulong_extras/factor_SQUFOF.c index 69cf67718a..c847f5ab0b 100644 --- a/src/ulong_extras/factor_SQUFOF.c +++ b/src/ulong_extras/factor_SQUFOF.c @@ -12,6 +12,8 @@ #include #include "ulong_extras.h" +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong _ll_factor_SQUFOF(ulong n_hi, ulong n_lo, ulong max_iters) { ulong n[2]; diff --git a/src/ulong_extras/ll_mod_preinv.c b/src/ulong_extras/ll_mod_preinv.c index b1616b5d62..b903552af7 100644 --- a/src/ulong_extras/ll_mod_preinv.c +++ b/src/ulong_extras/ll_mod_preinv.c @@ -18,6 +18,8 @@ https://gmplib.org/~tege/division-paper.pdf */ +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong n_ll_mod_preinv(ulong a_hi, ulong a_lo, ulong n, ulong ninv) { diff --git a/src/ulong_extras/lll_mod_preinv.c b/src/ulong_extras/lll_mod_preinv.c index e8859ea479..bd69204990 100644 --- a/src/ulong_extras/lll_mod_preinv.c +++ b/src/ulong_extras/lll_mod_preinv.c @@ -18,6 +18,8 @@ https://gmplib.org/~tege/division-paper.pdf */ +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong n_lll_mod_preinv(ulong a_hi, ulong a_mi, ulong a_lo, ulong n, ulong ninv) { diff --git a/src/ulong_extras/mod2_preinv.c b/src/ulong_extras/mod2_preinv.c index ae96fec452..21f24f3bbd 100644 --- a/src/ulong_extras/mod2_preinv.c +++ b/src/ulong_extras/mod2_preinv.c @@ -18,6 +18,8 @@ https://gmplib.org/~tege/division-paper.pdf */ +#define r_shift(in, c) (((c) == FLINT_BITS) ? WORD(0) : ((in) >> (c))) + ulong n_mod2_preinv(ulong a, ulong n, ulong ninv) { diff --git a/src/ulong_extras/randomisation.c b/src/ulong_extras/randomisation.c index f9a5bc1ea5..c016afe4ee 100644 --- a/src/ulong_extras/randomisation.c +++ b/src/ulong_extras/randomisation.c @@ -16,10 +16,15 @@ #include "ulong_extras.h" #include "fmpz.h" +#define l_shift(in, shift) \ + ((shift == FLINT_BITS) ? WORD(0) : ((in) << (shift))) + ulong n_randbits(flint_rand_t state, unsigned int bits) { - if (bits == 0) return UWORD(0); - else return (UWORD(1) << (bits - 1)) | n_randint(state, l_shift(UWORD(1), bits)); + if (bits == 0) + return UWORD(0); + else + return (UWORD(1) << (bits - 1)) | n_randint(state, l_shift(UWORD(1), bits)); } ulong n_urandint(flint_rand_t state, ulong limit)