From: Paul Eggert <eggert@cs.ucla.edu>
To: Eli Zaretskii <eliz@gnu.org>
Cc: andrewjmoreton@gmail.com, emacs-devel@gnu.org
Subject: Re: Bignum speedup patch causes crash at startup
Date: Tue, 4 Sep 2018 11:59:53 -0700 [thread overview]
Message-ID: <54c97913-984d-6129-e126-3c7fb66ed6c6@cs.ucla.edu> (raw)
In-Reply-To: <831sa9z0wa.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 758 bytes --]
Eli Zaretskii wrote:
> I don't understand why it prefers GMP calls to a simple double
> division, when both arguments are fixnums. What am I missing?
First, converting a fixnum to a double can lose info. Second, the double
division could round, which would mean the result would be double-rounded. We're
already suffering from double-rounding when either argument is floating-point,
and we don't want that bug to also infect integer division. So even the Emacs 26
code (which doesn't have bignums) must use integer division here, not double
division.
This is worth commenting so I installed the attached. While writing the comment
I noticed there's a bug when one argument is a bignum and the other is a float,
so I fixed that in the attached too.
[-- Attachment #2: 0001-Fix-round-FLOAT-BIGNUM-bug.patch --]
[-- Type: text/x-patch, Size: 2091 bytes --]
From 21637d5e5b29d5ec8fb966c0ddfbfba3eb33da38 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 4 Sep 2018 11:49:41 -0700
Subject: [PATCH] Fix (round FLOAT BIGNUM) bug
* src/floatfns.c (rounding_driver): Fix bug when one
argument is a float and the other is a bignum.
* test/src/floatfns-tests.el (bignum-round): Test for the bug.
---
src/floatfns.c | 7 +++++--
test/src/floatfns-tests.el | 5 +++++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/floatfns.c b/src/floatfns.c
index 2f33b8652b..13ab7b0359 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -355,6 +355,8 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor,
CHECK_NUMBER (divisor);
if (!FLOATP (arg) && !FLOATP (divisor))
{
+ /* Divide as integers. Converting to double might lose
+ info, even for fixnums; also see the FIXME below. */
if (EQ (divisor, make_fixnum (0)))
xsignal0 (Qarith_error);
int_divide (mpz[0],
@@ -363,10 +365,11 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor,
return make_integer_mpz ();
}
- double f1 = FLOATP (arg) ? XFLOAT_DATA (arg) : XFIXNUM (arg);
- double f2 = FLOATP (divisor) ? XFLOAT_DATA (divisor) : XFIXNUM (divisor);
+ double f1 = XFLOATINT (arg);
+ double f2 = XFLOATINT (divisor);
if (! IEEE_FLOATING_POINT && f2 == 0)
xsignal0 (Qarith_error);
+ /* FIXME: This division rounds, so the result is double-rounded. */
d = f1 / f2;
}
diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el
index d41b08f796..9a382058b4 100644
--- a/test/src/floatfns-tests.el
+++ b/test/src/floatfns-tests.el
@@ -70,6 +70,11 @@
(should (= n (floor n)))
(should (= n (round n)))
(should (= n (truncate n)))
+ (let ((-n (- n))
+ (f (float n))
+ (-f (- (float n))))
+ (should (= 1 (round n f) (round -n -f) (round f n) (round -f -n)))
+ (should (= -1 (round -n f) (round n -f) (round f -n) (round -f n))))
(dolist (d ns)
(let ((q (/ n d))
(r (% n d))
--
2.17.1
next prev parent reply other threads:[~2018-09-04 18:59 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-04 14:21 Bignum speedup patch causes crash at startup Andy Moreton
2018-09-04 15:10 ` Eli Zaretskii
2018-09-04 16:24 ` Eli Zaretskii
2018-09-04 18:59 ` Paul Eggert [this message]
2018-09-05 2:35 ` Eli Zaretskii
2018-09-05 7:31 ` Paul Eggert
2018-09-04 16:40 ` Paul Eggert
2018-09-04 17:30 ` Eli Zaretskii
2018-09-04 17:37 ` Andy Moreton
2018-09-04 17:50 ` Eli Zaretskii
2018-09-04 19:50 ` Andy Moreton
2018-09-04 21:11 ` Paul Eggert
2018-09-04 22:34 ` Tom Tromey
2018-09-05 0:09 ` Andy Moreton
2018-09-05 0:56 ` Paul Eggert
2018-09-05 15:21 ` Eli Zaretskii
2018-09-05 15:17 ` Eli Zaretskii
2018-09-04 19:56 ` Andy Moreton
2018-09-04 20:48 ` Paul Eggert
2018-09-05 15:15 ` Eli Zaretskii
2018-09-05 15:40 ` Paul Eggert
2018-09-05 15:50 ` Pip Cet
2018-09-05 16:06 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54c97913-984d-6129-e126-3c7fb66ed6c6@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=andrewjmoreton@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).