diff options
author | Tom Tromey <tom@tromey.com> | 2018-07-19 15:58:10 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-07-19 16:08:41 -0600 |
commit | 76715f8921dca740880cd22c644a6328cd810846 (patch) | |
tree | d85940e4c452575c453ab3ea6a7d0ec25b20f2ab /src/alloc.c | |
parent | 678881e428073b39a906c1ffd01e1b76e271cb5d (diff) | |
download | emacs-feature/bignum.tar.gz |
Fix bignum creation when EMACS_INT is wider than longfeature/bignum
* src/alloc.c (mpz_set_intmax_slow, mpz_set_uintmax_slow): New
functions.
* src/data.c (arith_driver, Frem, Fmod, ash_lsh_impl, Fadd1)
(Fsub1): Use mpz_set_intmax, mpz_set_uintmax.
* src/emacs-module.c (module_make_integer): Use mpz_set_intmax.
* src/floatfns.c (Fabs): Use mpz_set_intmax.
* src/lisp.h (mpz_set_intmax, mpz_set_uintmax): New inline
functions.
(mpz_set_uintmax_slow, mpz_set_intmax_slow): Declare.
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/alloc.c b/src/alloc.c index b775948fd96..1dc1bbb031a 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3824,6 +3824,36 @@ make_number (mpz_t value) return obj; } +void +mpz_set_intmax_slow (mpz_t result, intmax_t v) +{ + /* If long is larger then a faster path is taken. */ + eassert (sizeof (intmax_t) > sizeof (long)); + + bool negate = false; + if (v < 0) + { + v = -v; + negate = true; + } + mpz_set_uintmax_slow (result, (uintmax_t) v); + if (negate) + mpz_neg (result, result); +} + +void +mpz_set_uintmax_slow (mpz_t result, uintmax_t v) +{ + /* If long is larger then a faster path is taken. */ + eassert (sizeof (uintmax_t) > sizeof (unsigned long)); + /* This restriction could be lifted if needed. */ + eassert (sizeof (uintmax_t) <= 2 * sizeof (unsigned long)); + + mpz_set_ui (result, v >> (CHAR_BIT * sizeof (unsigned long))); + mpz_mul_2exp (result, result, CHAR_BIT * sizeof (unsigned long)); + mpz_add_ui (result, result, v & -1ul); +} + /* Return a newly created vector or string with specified arguments as elements. If all the arguments are characters that can fit |