emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 202bd7b: Fix logb on zero, infinite, NaN args


From: Paul Eggert
Subject: [Emacs-diffs] master 202bd7b: Fix logb on zero, infinite, NaN args
Date: Sun, 6 Jan 2019 19:25:45 -0500 (EST)

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

    Fix logb on zero, infinite, NaN args
    
    Change logb to return -infinity, +infinity, and NaN respectively.
    Formerly logb returned an extreme fixnum to represent
    infinity, but this is no longer the right thing to do now that
    we have bignums and there is no extreme integer.
    * doc/lispref/numbers.texi (Float Basics), etc/NEWS: Document.
    * src/floatfns.c (Flogb): Implement this.
---
 doc/lispref/numbers.texi |  8 ++++++--
 etc/NEWS                 |  4 ++++
 src/floatfns.c           | 27 +++++++++++----------------
 3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index cffc634..fbdd83f 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -313,14 +313,18 @@ and returns the result.  @var{x1} and @var{x2} must be 
floating point.
 
 @defun logb x
 This function returns the binary exponent of @var{x}.  More
-precisely, the value is the logarithm base 2 of @math{|x|}, rounded
-down to an integer.
+precisely, if @var{x} is finite and nonzero, the value is the
+logarithm base 2 of @math{|x|}, rounded down to an integer.
+If @var{x} is zero, infinite, or a NaN, the value is minus infinity,
+plus infinity, or a NaN respectively.
 
 @example
 (logb 10)
      @result{} 3
 (logb 10.0e20)
      @result{} 69
+(logb 0)
+     @result{} -1.0e+INF
 @end example
 @end defun
 
diff --git a/etc/NEWS b/etc/NEWS
index b316aec..3670ab5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1112,6 +1112,10 @@ old-style backquotes as new-style, bind the new variable
 integer, Emacs now signals an error if the number is too large for the
 implementation to format.
 
+** logb now returns infinity when given an infinite or zero argument,
+and returns a NaN when given a NaN.  Formerly, it returned an extreme
+fixnum for such arguments.
+
 ---
 ** Some functions and variables obsolete since Emacs 22 have been removed:
 archive-mouse-extract, assoc-ignore-case, assoc-ignore-representation,
diff --git a/src/floatfns.c b/src/floatfns.c
index 2d76b97..a913aad 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -306,27 +306,22 @@ This is the same as the exponent of a float.  */)
   if (FLOATP (arg))
     {
       double f = XFLOAT_DATA (arg);
-
       if (f == 0)
-       value = MOST_NEGATIVE_FIXNUM;
-      else if (isfinite (f))
-       {
-         int ivalue;
-         frexp (f, &ivalue);
-         value = ivalue - 1;
-       }
-      else
-       value = MOST_POSITIVE_FIXNUM;
+       return make_float (-HUGE_VAL);
+      if (!isfinite (f))
+       return f < 0 ? make_float (-f) : arg;
+      int ivalue;
+      frexp (f, &ivalue);
+      value = ivalue - 1;
     }
-  else if (BIGNUMP (arg))
+  else if (!FIXNUMP (arg))
     value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1;
   else
     {
-      eassert (FIXNUMP (arg));
-      EMACS_INT i = eabs (XFIXNUM (arg));
-      value = (i == 0
-              ? MOST_NEGATIVE_FIXNUM
-              : EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (i));
+      EMACS_INT i = XFIXNUM (arg);
+      if (i == 0)
+       return make_float (-HUGE_VAL);
+      value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i));
     }
 
   return make_fixnum (value);



reply via email to

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