emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master c44bc4d: Fix (floor 54043195528445955 3.0) bug


From: Paul Eggert
Subject: [Emacs-diffs] master c44bc4d: Fix (floor 54043195528445955 3.0) bug
Date: Thu, 13 Sep 2018 17:30:05 -0400 (EDT)

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

    Fix (floor 54043195528445955 3.0) bug
    
    * src/floatfns.c (rounding_driver): Fix rounding error
    that can occur when both args have values exactly
    representable as integers but at least one arg is a float.
    * test/src/floatfns-tests.el (big-round): New test.
---
 src/floatfns.c             | 20 +++++++++++++++++++-
 test/src/floatfns-tests.el |  4 ++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/floatfns.c b/src/floatfns.c
index 6f5aee2..9003925 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -332,6 +332,18 @@ This is the same as the exponent of a float.  */)
   return make_fixnum (value);
 }
 
+/* True if A is exactly representable as an integer.  */
+
+static bool
+integer_value (Lisp_Object a)
+{
+  if (FLOATP (a))
+    {
+      double d = XFLOAT_DATA (a);
+      return d == floor (d) && isfinite (d);
+    }
+  return true;
+}
 
 /* the rounding functions  */
 
@@ -353,10 +365,16 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor,
   else
     {
       CHECK_NUMBER (divisor);
-      if (!FLOATP (arg) && !FLOATP (divisor))
+      if (integer_value (arg) && integer_value (divisor))
        {
          /* Divide as integers.  Converting to double might lose
             info, even for fixnums; also see the FIXME below.  */
+
+         if (FLOATP (arg))
+           arg = double_to_integer (XFLOAT_DATA (arg));
+         if (FLOATP (divisor))
+           divisor = double_to_integer (XFLOAT_DATA (divisor));
+
          if (FIXNUMP (divisor))
            {
              if (XFIXNUM (divisor) == 0)
diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el
index 3dcddc7..14576b6 100644
--- a/test/src/floatfns-tests.el
+++ b/test/src/floatfns-tests.el
@@ -109,4 +109,8 @@
           (should-error (round n d))
           (should-error (truncate n d)))))))
 
+(ert-deftest big-round ()
+  (should (= (floor 54043195528445955 3)
+             (floor 54043195528445955 3.0))))
+
 (provide 'floatfns-tests)



reply via email to

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