From 53f3dd66f12660a47018fc03d50d460787ab6f64 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 5 Mar 2017 13:29:28 -0800 Subject: [PATCH] ffloor etc. now accept only floats * etc/NEWS: Say why. * src/floatfns.c (Ffceiling, Fffloor, Ffround, Fftruncate): Require arg to be float. * test/src/floatfns-tests.el (fround-fixnum): Check this. --- etc/NEWS | 6 ++++++ src/floatfns.c | 16 ++++++++++------ test/src/floatfns-tests.el | 6 ++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index fe02236ecc2..8f7356f3e03 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -907,6 +907,12 @@ compares their numerical values. According to this predicate, due to internal rounding errors. For example, (< most-positive-fixnum (+ 1.0 most-positive-fixnum)) now correctly returns t on 64-bit hosts. +--- +** The functions 'ffloor', 'fceiling', 'ftruncate' and 'fround' now +accept only floating-point arguments, as per their documentation. +Formerly, they quietly accepted integer arguments and sometimes +returned nonsensical answers, e.g., (< N (ffloor N)) could return t. + --- ** On hosts like GNU/Linux x86-64 where a 'long double' fraction contains at least EMACS_INT_WIDTH - 3 bits, 'format' no longer returns diff --git a/src/floatfns.c b/src/floatfns.c index 9ae810669ef..4c09036ac79 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -504,17 +504,19 @@ DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0, \(Round toward +inf.) */) (Lisp_Object arg) { - double d = extract_float (arg); + CHECK_FLOAT (arg); + double d = XFLOAT_DATA (arg); d = ceil (d); return make_float (d); } DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0, doc: /* Return the largest integer no greater than ARG, as a float. -\(Round towards -inf.) */) +\(Round toward -inf.) */) (Lisp_Object arg) { - double d = extract_float (arg); + CHECK_FLOAT (arg); + double d = XFLOAT_DATA (arg); d = floor (d); return make_float (d); } @@ -523,17 +525,19 @@ DEFUN ("fround", Ffround, Sfround, 1, 1, 0, doc: /* Return the nearest integer to ARG, as a float. */) (Lisp_Object arg) { - double d = extract_float (arg); + CHECK_FLOAT (arg); + double d = XFLOAT_DATA (arg); d = emacs_rint (d); return make_float (d); } DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0, doc: /* Truncate a floating point number to an integral float value. -Rounds the value toward zero. */) +\(Round toward zero.) */) (Lisp_Object arg) { - double d = extract_float (arg); + CHECK_FLOAT (arg); + double d = XFLOAT_DATA (arg); d = emacs_trunc (d); return make_float (d); } diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el index cdfb8244f52..de3e44314f9 100644 --- a/test/src/floatfns-tests.el +++ b/test/src/floatfns-tests.el @@ -28,4 +28,10 @@ (ert-deftest logb-extreme-fixnum () (should (= (logb most-negative-fixnum) (1+ (logb most-positive-fixnum))))) +(ert-deftest fround-fixnum () + (should-error (ffloor 0) :type 'wrong-type-argument) + (should-error (fceiling 0) :type 'wrong-type-argument) + (should-error (ftruncate 0) :type 'wrong-type-argument) + (should-error (fround 0) :type 'wrong-type-argument)) + (provide 'floatfns-tests) -- 2.39.5