diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-22 19:30:24 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-22 19:30:57 -0700 |
commit | ee641b87cf220250ba89f219fb47a4406a05deb7 (patch) | |
tree | 08ff44c5197ae39b2ec0906de4bb4dcafda4677f /src/floatfns.c | |
parent | be5fe6183e95f3afe3a62ec43504b99df90bc794 (diff) | |
download | emacs-ee641b87cf220250ba89f219fb47a4406a05deb7.tar.gz |
Fix bugs when rounding to bignums
Also, since Emacs historically reported a range error when
rounding operations overflowed, do that consistently for all
bignum overflows.
* doc/lispref/errors.texi (Standard Errors):
* doc/lispref/numbers.texi (Integer Basics): Document range errors.
* src/alloc.c (range_error): Rename from integer_overflow.
All uses changed.
* src/floatfns.c (rounding_driver): When the result of a floating
point rounding operation does not fit into a fixnum, put it
into a bignum instead of always signaling an range error.
* test/src/floatfns-tests.el (divide-extreme-sign):
These tests now return the mathematically-correct answer
instead of signaling an error.
(bignum-round): Check that integers round to themselves.
Diffstat (limited to 'src/floatfns.c')
-rw-r--r-- | src/floatfns.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index c09fe9d6a5b..e7884864eef 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -410,7 +410,12 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor, if (! FIXNUM_OVERFLOW_P (ir)) return make_fixnum (ir); } - xsignal2 (Qrange_error, build_string (name), arg); + mpz_t drz; + mpz_init (drz); + mpz_set_d (drz, dr); + Lisp_Object rounded = make_number (drz); + mpz_clear (drz); + return rounded; } static void @@ -501,13 +506,20 @@ systems, but 2 on others. */) return rounding_driver (arg, divisor, emacs_rint, rounddiv_q, "round"); } +/* Since rounding_driver truncates anyway, no need to call 'trunc'. */ +static double +identity (double x) +{ + return x; +} + DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0, doc: /* Truncate a floating point number to an int. Rounds ARG toward zero. With optional DIVISOR, truncate ARG/DIVISOR. */) (Lisp_Object arg, Lisp_Object divisor) { - return rounding_driver (arg, divisor, trunc, mpz_tdiv_q, "truncate"); + return rounding_driver (arg, divisor, identity, mpz_tdiv_q, "truncate"); } |