emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 21637d5: Fix (round FLOAT BIGNUM) bug


From: Paul Eggert
Subject: [Emacs-diffs] master 21637d5: Fix (round FLOAT BIGNUM) bug
Date: Tue, 4 Sep 2018 14:51:13 -0400 (EDT)

branch: master
commit 21637d5e5b29d5ec8fb966c0ddfbfba3eb33da38
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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 2f33b86..13ab7b0 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 d41b08f..9a38205 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))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]