space. */
static Lisp_Object
-make_pure_bignum (struct Lisp_Bignum *value)
+make_pure_bignum (Lisp_Object value)
{
- size_t i, nlimbs = mpz_size (value->value);
+ mpz_t const *n = xbignum_val (value);
+ size_t i, nlimbs = mpz_size (*n);
size_t nbytes = nlimbs * sizeof (mp_limb_t);
mp_limb_t *pure_limbs;
mp_size_t new_size;
int limb_alignment = alignof (mp_limb_t);
pure_limbs = pure_alloc (nbytes, - limb_alignment);
for (i = 0; i < nlimbs; ++i)
- pure_limbs[i] = mpz_getlimbn (value->value, i);
+ pure_limbs[i] = mpz_getlimbn (*n, i);
new_size = nlimbs;
- if (mpz_sgn (value->value) < 0)
+ if (mpz_sgn (*n) < 0)
new_size = -new_size;
mpz_roinit_n (b->value, pure_limbs, new_size);
return obj;
}
else if (BIGNUMP (obj))
- obj = make_pure_bignum (XBIGNUM (obj));
+ obj = make_pure_bignum (obj);
else
{
AUTO_STRING (fmt, "Don't know how to purify: %S");
double
bignum_to_double (Lisp_Object n)
{
- return mpz_get_d_rounded (XBIGNUM (n)->value);
+ return mpz_get_d_rounded (*xbignum_val (n));
}
/* Return D, converted to a Lisp integer. Discard any fraction.
bignum_to_intmax (Lisp_Object x)
{
intmax_t i;
- return mpz_to_intmax (XBIGNUM (x)->value, &i) ? i : 0;
+ return mpz_to_intmax (*xbignum_val (x), &i) ? i : 0;
}
uintmax_t
bignum_to_uintmax (Lisp_Object x)
{
uintmax_t i;
- return mpz_to_uintmax (XBIGNUM (x)->value, &i) ? i : 0;
+ return mpz_to_uintmax (*xbignum_val (x), &i) ? i : 0;
}
/* Yield an upper bound on the buffer size needed to contain a C
ptrdiff_t
bignum_bufsize (Lisp_Object num, int base)
{
- return mpz_bufsize (XBIGNUM (num)->value, base);
+ return mpz_bufsize (*xbignum_val (num), base);
}
/* Convert NUM to a nearest double, as opposed to mpz_get_d which
bignum_to_c_string (char *buf, ptrdiff_t size, Lisp_Object num, int base)
{
eassert (bignum_bufsize (num, abs (base)) == size);
- mpz_get_str (buf, base, XBIGNUM (num)->value);
+ mpz_get_str (buf, base, *xbignum_val (num));
ptrdiff_t n = size - 2;
return !buf[n - 1] ? n - 1 : n + !!buf[n];
}
mpz_set_uintmax_slow (result, v);
}
+/* Return a pointer to the mpz_t value represented by the bignum I.
+ It is const because the value should not change. */
+INLINE mpz_t const *
+bignum_val (struct Lisp_Bignum const *i)
+{
+ return &i->value;
+}
+INLINE mpz_t const *
+xbignum_val (Lisp_Object i)
+{
+ return bignum_val (XBIGNUM (i));
+}
+
/* Return a pointer to an mpz_t that is equal to the Lisp integer I.
If I is a bignum this returns a pointer to I's representation;
otherwise this sets *TMP to I's value and returns TMP. */
mpz_set_intmax (*tmp, XFIXNUM (i));
return tmp;
}
- return &XBIGNUM (i)->value;
+ return xbignum_val (i);
}
/* Set RESULT to the value stored in the Lisp integer I. If I is a
if (FIXNUMP (i))
mpz_set_intmax (result, XFIXNUM (i));
else
- mpz_set (result, XBIGNUM (i)->value);
+ mpz_set (result, *xbignum_val (i));
}
INLINE_HEADER_END
(Lisp_Object object)
{
return ((FIXNUMP (object) ? 0 <= XFIXNUM (object)
- : BIGNUMP (object) && 0 <= mpz_sgn (XBIGNUM (object)->value))
+ : BIGNUMP (object) && 0 <= mpz_sgn (*xbignum_val (object)))
? Qt : Qnil);
}
else if (isnan (f1))
lt = eq = gt = false;
else
- i2 = mpz_cmp_d (XBIGNUM (num2)->value, f1);
+ i2 = mpz_cmp_d (*xbignum_val (num2), f1);
}
else if (FIXNUMP (num1))
{
i2 = XFIXNUM (num2);
}
else
- i2 = mpz_sgn (XBIGNUM (num2)->value);
+ i2 = mpz_sgn (*xbignum_val (num2));
}
else if (FLOATP (num2))
{
if (isnan (f2))
lt = eq = gt = false;
else
- i1 = mpz_cmp_d (XBIGNUM (num1)->value, f2);
+ i1 = mpz_cmp_d (*xbignum_val (num1), f2);
}
else if (FIXNUMP (num2))
- i1 = mpz_sgn (XBIGNUM (num1)->value);
+ i1 = mpz_sgn (*xbignum_val (num1));
else
- i1 = mpz_cmp (XBIGNUM (num1)->value, XBIGNUM (num2)->value);
+ i1 = mpz_cmp (*xbignum_val (num1), *xbignum_val (num2));
if (eq)
{
return make_int (-XFIXNUM (a));
if (FLOATP (a))
return make_float (-XFLOAT_DATA (a));
- mpz_neg (mpz[0], XBIGNUM (a)->value);
+ mpz_neg (mpz[0], *xbignum_val (a));
return make_integer_mpz ();
}
return arith_driver (Asub, nargs, args, a);
if (BIGNUMP (value))
{
- mpz_t *nonneg = &XBIGNUM (value)->value;
+ mpz_t const *nonneg = xbignum_val (value);
if (mpz_sgn (*nonneg) < 0)
{
mpz_com (mpz[0], *nonneg);
{
if (EQ (value, make_fixnum (0)))
return value;
- if (mpz_sgn (XBIGNUM (count)->value) < 0)
+ if (mpz_sgn (*xbignum_val (count)) < 0)
{
EMACS_INT v = (FIXNUMP (value) ? XFIXNUM (value)
- : mpz_sgn (XBIGNUM (value)->value));
+ : mpz_sgn (*xbignum_val (value)));
return make_fixnum (v < 0 ? -1 : 0);
}
overflow_error ();
if (TYPE_RANGED_FIXNUMP (unsigned long, y))
exp = XFIXNUM (y);
else if (MOST_POSITIVE_FIXNUM < ULONG_MAX && BIGNUMP (y)
- && mpz_fits_ulong_p (XBIGNUM (y)->value))
- exp = mpz_get_ui (XBIGNUM (y)->value);
+ && mpz_fits_ulong_p (*xbignum_val (y)))
+ exp = mpz_get_ui (*xbignum_val (y));
else
overflow_error ();
return make_int (XFIXNUM (number) + 1);
if (FLOATP (number))
return (make_float (1.0 + XFLOAT_DATA (number)));
- mpz_add_ui (mpz[0], XBIGNUM (number)->value, 1);
+ mpz_add_ui (mpz[0], *xbignum_val (number), 1);
return make_integer_mpz ();
}
return make_int (XFIXNUM (number) - 1);
if (FLOATP (number))
return (make_float (-1.0 + XFLOAT_DATA (number)));
- mpz_sub_ui (mpz[0], XBIGNUM (number)->value, 1);
+ mpz_sub_ui (mpz[0], *xbignum_val (number), 1);
return make_integer_mpz ();
}
CHECK_INTEGER (number);
if (FIXNUMP (number))
return make_fixnum (~XFIXNUM (number));
- mpz_com (mpz[0], XBIGNUM (number)->value);
+ mpz_com (mpz[0], *xbignum_val (number));
return make_integer_mpz ();
}
}
else
{
- if (mpz_sgn (XBIGNUM (arg)->value) < 0)
+ if (mpz_sgn (*xbignum_val (arg)) < 0)
{
- mpz_neg (mpz[0], XBIGNUM (arg)->value);
+ mpz_neg (mpz[0], *xbignum_val (arg));
arg = make_integer_mpz ();
}
}
value = ivalue - 1;
}
else if (!FIXNUMP (arg))
- value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1;
+ value = mpz_sizeinbase (*xbignum_val (arg), 2) - 1;
else
{
EMACS_INT i = XFIXNUM (arg);
enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES };
static bool internal_equal (Lisp_Object, Lisp_Object,
enum equal_kind, int, Lisp_Object);
-static EMACS_UINT sxhash_bignum (struct Lisp_Bignum *);
DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
doc: /* Return the argument unchanged. */
}
else
{
- if (mpz_sgn (XBIGNUM (n)->value) < 0)
+ if (mpz_sgn (*xbignum_val (n)) < 0)
return tail;
num = large_num;
}
CYCLE_LENGTH. */
/* Add N mod CYCLE_LENGTH to NUM. */
if (cycle_length <= ULONG_MAX)
- num += mpz_tdiv_ui (XBIGNUM (n)->value, cycle_length);
+ num += mpz_tdiv_ui (*xbignum_val (n), cycle_length);
else
{
mpz_set_intmax (mpz[0], cycle_length);
- mpz_tdiv_r (mpz[0], XBIGNUM (n)->value, mpz[0]);
+ mpz_tdiv_r (mpz[0], *xbignum_val (n), mpz[0]);
intptr_t iz;
mpz_export (&iz, NULL, -1, sizeof iz, 0, 0, mpz[0]);
num += iz;
{
Lisp_Object tem = XCAR (tail);
if (BIGNUMP (tem)
- && mpz_cmp (XBIGNUM (elt)->value, XBIGNUM (tem)->value) == 0)
+ && mpz_cmp (*xbignum_val (elt), *xbignum_val (tem)) == 0)
return tail;
}
}
return FLOATP (obj2) && same_float (obj1, obj2) ? Qt : Qnil;
else if (BIGNUMP (obj1))
return ((BIGNUMP (obj2)
- && mpz_cmp (XBIGNUM (obj1)->value, XBIGNUM (obj2)->value) == 0)
+ && mpz_cmp (*xbignum_val (obj1), *xbignum_val (obj2)) == 0)
? Qt : Qnil);
else
return EQ (obj1, obj2) ? Qt : Qnil;
if (ASIZE (o2) != size)
return false;
if (BIGNUMP (o1))
- return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0;
+ return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0;
if (OVERLAYP (o1))
{
if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
/* Return a hash for a bignum. */
static EMACS_UINT
-sxhash_bignum (struct Lisp_Bignum *bignum)
+sxhash_bignum (Lisp_Object bignum)
{
- size_t i, nlimbs = mpz_size (bignum->value);
+ mpz_t const *n = xbignum_val (bignum);
+ size_t i, nlimbs = mpz_size (*n);
EMACS_UINT hash = 0;
for (i = 0; i < nlimbs; ++i)
- hash = sxhash_combine (hash, mpz_getlimbn (bignum->value, i));
+ hash = sxhash_combine (hash, mpz_getlimbn (*n, i));
return SXHASH_REDUCE (hash);
}
/* This can be everything from a vector to an overlay. */
case Lisp_Vectorlike:
if (BIGNUMP (obj))
- hash = sxhash_bignum (XBIGNUM (obj));
+ hash = sxhash_bignum (obj);
else if (VECTORP (obj) || RECORDP (obj))
/* According to the CL HyperSpec, two arrays are equal only if
they are `eq', except for strings and bit-vectors. In
const struct Lisp_Bignum *bignum = XBIGNUM (object);
START_DUMP_PVEC (ctx, &bignum->header, struct Lisp_Bignum, out);
verify (sizeof (out->value) >= sizeof (struct bignum_reload_info));
- dump_field_fixup_later (ctx, out, bignum, &bignum->value);
+ dump_field_fixup_later (ctx, out, bignum, xbignum_val (object));
dump_off bignum_offset = finish_dump_pvec (ctx, &out->header);
if (ctx->flags.dump_object_contents)
{
static void
dump_cold_bignum (struct dump_context *ctx, Lisp_Object object)
{
- const struct Lisp_Bignum *bignum = XBIGNUM (object);
- size_t sz_nlimbs = mpz_size (bignum->value);
+ mpz_t const *n = xbignum_val (object);
+ size_t sz_nlimbs = mpz_size (*n);
eassert (sz_nlimbs < DUMP_OFF_MAX);
dump_align_output (ctx, alignof (mp_limb_t));
dump_off nlimbs = (dump_off) sz_nlimbs;
Lisp_Object descriptor
= list2 (dump_off_to_lisp (ctx->offset),
- dump_off_to_lisp ((mpz_sgn (bignum->value) < 0
- ? -nlimbs : nlimbs)));
+ dump_off_to_lisp (mpz_sgn (*n) < 0 ? -nlimbs : nlimbs));
Fputhash (object, descriptor, ctx->bignum_data);
for (mp_size_t i = 0; i < nlimbs; ++i)
{
- mp_limb_t limb = mpz_getlimbn (bignum->value, i);
+ mp_limb_t limb = mpz_getlimbn (*n, i);
dump_write (ctx, &limb, sizeof (limb));
}
}
{
struct Lisp_Bignum *bignum = dump_ptr (dump_base, reloc_offset);
struct bignum_reload_info reload_info;
- verify (sizeof (reload_info) <= sizeof (bignum->value));
- memcpy (&reload_info, &bignum->value, sizeof (reload_info));
+ verify (sizeof (reload_info) <= sizeof (*bignum_val (bignum)));
+ memcpy (&reload_info, bignum_val (bignum), sizeof (reload_info));
const mp_limb_t *limbs =
dump_ptr (dump_base, reload_info.data_location);
mpz_roinit_n (bignum->value, limbs, reload_info.nlimbs);
#define TRILLION 1000000000000
#if FIXNUM_OVERFLOW_P (TRILLION)
static Lisp_Object trillion;
-# define ztrillion (XBIGNUM (trillion)->value)
+# define ztrillion (*xbignum_val (trillion))
#else
# define trillion make_fixnum (TRILLION)
# if ULONG_MAX < TRILLION || !FASTER_TIMEFNS
return make_int (ticks / XFIXNUM (t.hz)
- (ticks % XFIXNUM (t.hz) < 0));
}
- else if (! (BIGNUMP (hz) && 0 < mpz_sgn (XBIGNUM (hz)->value)))
+ else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz))))
invalid_hz (hz);
mpz_mul (mpz[0],
struct timespec result = invalid_timespec ();
int ns;
mpz_t *q = &mpz[0];
+ mpz_t const *qt = q;
if (FASTER_TIMEFNS && EQ (t.hz, timespec_hz))
{
return result;
}
else
- ns = mpz_fdiv_q_ui (*q, XBIGNUM (t.ticks)->value, TIMESPEC_HZ);
+ ns = mpz_fdiv_q_ui (*q, *xbignum_val (t.ticks), TIMESPEC_HZ);
}
else if (FASTER_TIMEFNS && EQ (t.hz, make_fixnum (1)))
{
return result;
}
else
- q = &XBIGNUM (t.ticks)->value;
+ qt = xbignum_val (t.ticks);
}
else
{
/* With some versions of MinGW, tv_sec is a 64-bit type, whereas
time_t is a 32-bit type. */
time_t sec;
- if (mpz_time (*q, &sec))
+ if (mpz_time (*qt, &sec))
{
result.tv_sec = sec;
result.tv_nsec = ns;
if (eabs (XFIXNUM (b)) <= ULONG_MAX)
{
((XFIXNUM (b) < 0) == subtract ? mpz_add_ui : mpz_sub_ui)
- (mpz[0], XBIGNUM (a)->value, eabs (XFIXNUM (b)));
+ (mpz[0], *xbignum_val (a), eabs (XFIXNUM (b)));
mpz_done = true;
}
}