unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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


  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).