diff --git a/Makefile.in b/Makefile.in
index 89d52a08e..07cc1505e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -25,7 +25,7 @@ export
SOURCES =
LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS))
-HEADERS = $(patsubst %, %.h, $(BUILD_DIRS))
+HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) arb-defs.h
OBJS = $(patsubst %.c, build/%.o, $(SOURCES))
LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS))
diff --git a/arb-defs.h b/arb-defs.h
new file mode 100644
index 000000000..8748d8c4b
--- /dev/null
+++ b/arb-defs.h
@@ -0,0 +1,138 @@
+/*
+ Copyright (C) 2022 Albin Ahlbäck
+ Copyright (C) 2022 Fredrik Johansson
+
+ This file is part of Arb.
+
+ Arb is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "flint/flint.h"
+
+#ifndef ARB_DEFS_H
+#define ARB_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __ARB_VERSION 2
+#define __ARB_VERSION_MINOR 22
+#define __ARB_VERSION_PATCHLEVEL 1
+
+#define ARB_VERSION "2.22.1"
+
+#define __ARB_RELEASE (__ARB_VERSION * 10000 + \
+ __ARB_VERSION_MINOR * 100 + \
+ __ARB_VERSION_PATCHLEVEL)
+
+
+#define TLS_PREFIX FLINT_TLS_PREFIX
+
+#if defined(_MSC_VER) && defined(ARB_BUILD_DLL)
+#define ARB_DLL __declspec(dllexport)
+#else
+#define ARB_DLL FLINT_DLL
+#endif
+
+
+#ifndef flint_abort
+#if __FLINT_RELEASE <= 20502
+#define flint_abort abort
+#endif
+#endif
+
+#if __FLINT_RELEASE < 20600
+#define flint_bitcnt_t ulong
+#endif
+
+
+#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)))
+
+
+/* FLINT_ABS is unsafe for x = WORD_MIN */
+#define UI_ABS_SI(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x)))
+
+
+#define nn_mul_2x1(r2, r1, r0, a1, a0, b0) \
+ do { \
+ mp_limb_t t1; \
+ umul_ppmm(r1, r0, a0, b0); \
+ umul_ppmm(r2, t1, a1, b0); \
+ add_ssaaaa(r2, r1, r2, r1, 0, t1); \
+ } while (0)
+
+#define nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) \
+ do { \
+ mp_limb_t t1, t2, t3; \
+ umul_ppmm(r1, r0, a0, b0); \
+ umul_ppmm(r2, t1, a1, b0); \
+ add_ssaaaa(r2, r1, r2, r1, 0, t1); \
+ umul_ppmm(t1, t2, a0, b1); \
+ umul_ppmm(r3, t3, a1, b1); \
+ add_ssaaaa(r3, t1, r3, t1, 0, t3); \
+ add_ssaaaa(r2, r1, r2, r1, t1, t2); \
+ r3 += r2 < t1; \
+ } while (0)
+
+
+#ifndef NEWTON_INIT
+
+#define NEWTON_INIT(from, to) \
+ { \
+ slong __steps[FLINT_BITS], __i, __from, __to; \
+ __steps[__i = 0] = __to = (to); \
+ __from = (from); \
+ while (__to > __from) \
+ __steps[++__i] = (__to = (__to + 1) / 2); \
+
+#define NEWTON_BASECASE(bc_to) { slong bc_to = __to;
+
+#define NEWTON_END_BASECASE }
+
+#define NEWTON_LOOP(step_from, step_to) \
+ { \
+ for (__i--; __i >= 0; __i--) \
+ { \
+ slong step_from = __steps[__i+1]; \
+ slong step_to = __steps[__i]; \
+
+#define NEWTON_END_LOOP }}
+
+#define NEWTON_END }
+
+#endif
+
+
+ARB_DLL extern const char * arb_version;
+
+double arb_test_multiplier(void);
+
+/* counts zero bits in the binary representation of e */
+static __inline__
+int
+n_zerobits(mp_limb_t e)
+{
+#ifdef __GMP_SHORT_LIMB
+ return FLINT_BITS - __builtin_popcount(e) - __builtin_clz(e);
+#else
+# ifdef _LONG_LONG_LIMB
+ return FLINT_BITS - __builtin_popcountll(e) - __builtin_clzll(e);
+# else
+ return FLINT_BITS - __builtin_popcountl(e) - __builtin_clzl(e);
+# endif
+#endif
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/arb.h b/arb.h
index be5bf85ff..903c239bd 100644
--- a/arb.h
+++ b/arb.h
@@ -26,17 +26,6 @@
extern "C" {
#endif
-#define __ARB_VERSION 2
-#define __ARB_VERSION_MINOR 22
-#define __ARB_VERSION_PATCHLEVEL 1
-#define ARB_VERSION "2.22.1"
-#define __ARB_RELEASE (__ARB_VERSION * 10000 + \
- __ARB_VERSION_MINOR * 100 + \
- __ARB_VERSION_PATCHLEVEL)
-
-ARB_DLL extern const char * arb_version;
-double arb_test_multiplier(void);
-
typedef struct
{
arf_struct mid;
diff --git a/arb_poly.h b/arb_poly.h
index 1fa2940b2..3d00dae92 100644
--- a/arb_poly.h
+++ b/arb_poly.h
@@ -730,22 +730,6 @@ arb_poly_allocated_bytes(const arb_poly_t x)
/* Macros */
-
-/* counts zero bits in the binary representation of e */
-ARB_POLY_INLINE int
-n_zerobits(mp_limb_t e)
-{
- int zeros = 0;
-
- while (e > 1)
- {
- zeros += !(e & 1);
- e >>= 1;
- }
-
- return zeros;
-}
-
/* Computes the length of the result when raising a polynomial of
length *len* to the power *exp* and truncating to length *trunc*,
without overflow. Assumes poly_len >= 1. */
@@ -760,33 +744,6 @@ poly_pow_length(slong poly_len, ulong exp, slong trunc)
return FLINT_MIN((slong) lo, trunc);
}
-#ifndef NEWTON_INIT
-
-#define NEWTON_INIT(from, to) \
- { \
- slong __steps[FLINT_BITS], __i, __from, __to; \
- __steps[__i = 0] = __to = (to); \
- __from = (from); \
- while (__to > __from) \
- __steps[++__i] = (__to = (__to + 1) / 2); \
-
-#define NEWTON_BASECASE(bc_to) { slong bc_to = __to;
-
-#define NEWTON_END_BASECASE }
-
-#define NEWTON_LOOP(step_from, step_to) \
- { \
- for (__i--; __i >= 0; __i--) \
- { \
- slong step_from = __steps[__i+1]; \
- slong step_to = __steps[__i]; \
-
-#define NEWTON_END_LOOP }}
-
-#define NEWTON_END }
-
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/arf.h b/arf.h
index 2c193f520..3ab1f74b4 100644
--- a/arf.h
+++ b/arf.h
@@ -27,12 +27,6 @@
#include "fmpr.h"
#include "mag.h"
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -439,9 +433,6 @@ arf_init_set_ui(arf_t x, ulong v)
}
}
-/* FLINT_ABS is unsafe for x = WORD_MIN */
-#define UI_ABS_SI(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x)))
-
ARF_INLINE void
arf_init_set_si(arf_t x, slong v)
{
@@ -805,27 +796,6 @@ void arf_urandom(arf_t x, flint_rand_t state, slong bits, arf_rnd_t rnd);
#define MUL_MPFR_MIN_LIMBS 25
#define MUL_MPFR_MAX_LIMBS 10000
-#define nn_mul_2x1(r2, r1, r0, a1, a0, b0) \
- do { \
- mp_limb_t t1; \
- umul_ppmm(r1, r0, a0, b0); \
- umul_ppmm(r2, t1, a1, b0); \
- add_ssaaaa(r2, r1, r2, r1, 0, t1); \
- } while (0)
-
-#define nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) \
- do { \
- mp_limb_t t1, t2, t3; \
- umul_ppmm(r1, r0, a0, b0); \
- umul_ppmm(r2, t1, a1, b0); \
- add_ssaaaa(r2, r1, r2, r1, 0, t1); \
- umul_ppmm(t1, t2, a0, b1); \
- umul_ppmm(r3, t3, a1, b1); \
- add_ssaaaa(r3, t1, r3, t1, 0, t3); \
- add_ssaaaa(r2, r1, r2, r1, t1, t2); \
- r3 += r2 < t1; \
- } while (0)
-
#define ARF_MPN_MUL(_z, _x, _xn, _y, _yn) \
if ((_xn) == (_yn)) \
{ \
diff --git a/bool_mat.h b/bool_mat.h
index e35940b6c..3b45fa1e4 100644
--- a/bool_mat.h
+++ b/bool_mat.h
@@ -21,20 +21,12 @@
#include
#include "flint/flint.h"
#include "flint/fmpz_mat.h"
-
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
+#include "arb-defs.h"
#ifdef __cplusplus
extern "C" {
#endif
-/* currently defined in the arb module, but global to the library */
-double arb_test_multiplier(void);
-
typedef struct
{
int *entries;
diff --git a/dlog.h b/dlog.h
index a00f017e0..0d580d1a7 100644
--- a/dlog.h
+++ b/dlog.h
@@ -19,15 +19,9 @@
#endif
#include "flint/flint.h"
-
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
-
#include "flint/ulong_extras.h"
#include "flint/nmod_vec.h"
+#include "arb-defs.h"
#ifdef __cplusplus
extern "C" {
diff --git a/doc/source/arb-defs.rst b/doc/source/arb-defs.rst
new file mode 100644
index 000000000..36d1272d4
--- /dev/null
+++ b/doc/source/arb-defs.rst
@@ -0,0 +1,91 @@
+.. _arb-defs:
+
+**arb-defs.h** -- global definitions for the Arb library
+================================================================================
+
+The header ``arb-defs.h`` provides macros and functions used throughout the
+Arb-library that are not specific for any Arb-types.
+
+
+Types, macros and constants
+--------------------------------------------------------------------------------
+
+.. macro:: __ARB_VERSION
+
+.. macro:: __ARB_VERSION_MINOR
+
+.. macro:: __ARB_VERSION_PATCHLEVEL
+
+ A macro for the major, minor and patch version of Arb, respectively,
+ represented as an integer. In other words, it gives you the first, second or
+ third number in the version number.
+
+.. macro:: ARB_VERSION
+
+ A macro for the version of Arb, represented as a string.
+
+.. var:: const char * arb_version
+
+ A constant variable equivalence to :macro:`ARB_VERSION`.
+
+.. macro:: __ARB_RELEASE
+
+ A macro aimed for easily parsing the version number of Arb. It is represented
+ as an integer defined by
+
+ .. math ::
+ \mathtt{\_\_ARB\_RELEASE}
+ =
+ 10000 \cdot \mathtt{\_\_ARB\_VERSION}
+ +
+ 100 \cdot \mathtt{\_\_ARB\_VERSION\_MINOR}
+ +
+ \mathtt{\_\_ARB\_VERSION\_PATCHLEVEL}
+
+.. macro:: LIMB_ONE
+
+ The limb with binary representation `(0 0 \cdots 0 1)_{2}`.
+
+.. macro:: LIMB_ONES
+
+ The limb with binary representation `(1 1 \cdots 1 1)_{2}`.
+
+.. macro:: LIMB_TOP
+
+ The limb with binary representation `(1 0 \cdots 0 0)_{2}`.
+
+.. macro:: MASK_LIMB(n, c)
+
+ A macro for removing the `c` lower ones in the bit representation of `n`.
+
+.. macro:: UI_ABS_SI(x)
+
+ Returns the absolute value of `x`.
+
+.. macro:: nn_mul_2x1(r2, r1, r0, a1, a0, b0)
+
+ Given `a = \{a_0, a_1\}` and `b = \{b_0\}`, it sets `r = \{r_0, r_1, r_2\}`
+ to the product `a \cdot b`.
+
+.. macro:: nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0)
+
+ Given `a = \{a_0, a_1\}` and `b = \{b_0, b_1\}`, it sets
+ `r = \{r_0, r_1, r_2, r_3\}` to the product `a \cdot b`.
+
+
+Functions
+--------------------------------------------------------------------------------
+
+.. function:: double arb_test_multiplier(void)
+
+ Returns the test multiplier. This function is used to determine how many
+ tests are going to be performed during ``make check``.
+
+.. function:: int n_zerobits(mp_limb_t e)
+
+ Returns the number of zero bits in the binary representation of `e` *up to
+ its most significant bit*.
+
+
+..
+ vim:spell spelllang=en_us:ts=3:sw=3:tw=80:expandtab:
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 3b94791ac..a37d6743f 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -100,6 +100,14 @@ Example programs
examples.rst
+General utilities
+::::::::::::::::::::::::::::::::::::
+
+.. toctree::
+ :maxdepth: 2
+
+ arb-defs.rst
+
Floating-point numbers
::::::::::::::::::::::::::::::::::::
@@ -248,3 +256,5 @@ Version history
history.rst
+..
+ vim:spell spelllang=en_us:ts=3:sw=3:tw=80:expandtab:
diff --git a/fmpr.h b/fmpr.h
index c6a8c3425..c03edf50a 100644
--- a/fmpr.h
+++ b/fmpr.h
@@ -22,26 +22,8 @@
#include "flint/flint.h"
#include "flint/fmpz.h"
#include "flint/fmpq.h"
-#if __FLINT_RELEASE < 20600
-#include "flint/config.h"
-#else
-#include "flint/flint-config.h"
-#endif
#include "fmpz_extras.h"
-
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
-
-#define TLS_PREFIX FLINT_TLS_PREFIX
-
-#if defined(_MSC_VER) && defined(ARB_BUILD_DLL)
-#define ARB_DLL __declspec(dllexport)
-#else
-#define ARB_DLL FLINT_DLL
-#endif
+#include "arb-defs.h"
#define fmpr_rnd_t int
#define FMPR_RND_DOWN 0
@@ -54,9 +36,6 @@
extern "C" {
#endif
-/* currently defined in the arb module, but global to the library */
-double arb_test_multiplier(void);
-
static __inline__ int
rounds_up(fmpr_rnd_t rnd, int negative)
{
diff --git a/fmpz_extras.h b/fmpz_extras.h
index 0c55f7f6a..168752840 100644
--- a/fmpz_extras.h
+++ b/fmpz_extras.h
@@ -15,24 +15,12 @@
#include
#include "flint/flint.h"
#include "flint/fmpz.h"
+#include "arb-defs.h"
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
-
-#if __FLINT_RELEASE < 20600
-#define flint_bitcnt_t ulong
-#endif
-
-/* currently defined in the arb module, but global to the library */
-double arb_test_multiplier(void);
-
static __inline__ void
fmpz_add_inline(fmpz_t z, const fmpz_t x, const fmpz_t y)
{
diff --git a/mag.h b/mag.h
index 00eb44fa9..3e2991125 100644
--- a/mag.h
+++ b/mag.h
@@ -24,21 +24,10 @@
#include "flint/fmpz.h"
#include "fmpz_extras.h"
-#ifndef flint_abort
-#if __FLINT_RELEASE <= 20502
-#define flint_abort abort
-#endif
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-#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)))
-
#define MAG_MAX_LAGOM_EXP (COEFF_MAX / 4)
#define MAG_MIN_LAGOM_EXP (-MAG_MAX_LAGOM_EXP)