emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 6e37d2f: Read and print NaN significand if <ieee754


From: Paul Eggert
Subject: [Emacs-diffs] master 6e37d2f: Read and print NaN significand if <ieee754.h>
Date: Wed, 1 Aug 2018 03:52:01 -0400 (EDT)

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

    Read and print NaN significand if <ieee754.h>
    
    * configure.ac: Check for ieee754.h.
    * doc/lispref/numbers.texi (Float Basics): Document
    that NaN string representation digits are machine-dependent.
    * etc/NEWS: Mention the change.
    * src/lread.c, src/print.c [HAVE_IEEE754_H]: Include ieee754.h.
    * src/lread.c (string_to_number) [HAVE_IEEE754_H]:
    * src/print.c (float_to_string) [HAVE_IEEE754_H]:
    Read and print NaN significand.
---
 configure.ac             |  1 +
 doc/lispref/numbers.texi |  2 +-
 etc/NEWS                 |  3 +++
 src/lread.c              | 11 +++++++++++
 src/print.c              | 11 +++++++++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index b691867..dbdcce7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1668,6 +1668,7 @@ fi
 
 dnl checks for header files
 AC_CHECK_HEADERS_ONCE(
+  ieee754.h
   linux/fs.h
   malloc.h
   sys/systeminfo.h
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 14d5059..a3317c9 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -241,7 +241,7 @@ A NaN is never numerically equal to any value, not even to 
itself.
 NaNs carry a sign and a significand, and non-numeric functions treat
 two NaNs as equal when their
 signs and significands agree.  Significands of NaNs are
-machine-dependent and are not directly visible to Emacs Lisp.
+machine-dependent, as are the digits in their string representation.
 
   When NaNs and signed zeros are involved, non-numeric functions like
 @code{eql}, @code{equal}, @code{sxhash-eql}, @code{sxhash-equal} and
diff --git a/etc/NEWS b/etc/NEWS
index f1ea835..9e7a765 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -880,6 +880,9 @@ Formerly, some of these functions ignored signs and 
significands of
 NaNs.  Now, all these functions treat NaN signs and significands as
 significant.  For example, (eql 0.0e+NaN -0.0e+NaN) now returns nil
 because the two NaNs have different signs; formerly it returned t.
+Also, on platforms that have <ieee754.h> Emacs now reads and prints
+NaN significands; e.g., if X is a NaN, (format "%s" X) now returns
+"0.0e+NaN", "1.0e+NaN", etc., depending on X's significand.
 
 +++
 ** The function 'make-string' accepts an additional optional argument.
diff --git a/src/lread.c b/src/lread.c
index 50fc6ef..290b0f6 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -72,6 +72,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #define file_tell ftell
 #endif
 
+#if HAVE_IEEE754_H
+# include <ieee754.h>
+#endif
+
 /* The objects or placeholders read with the #n=object form.
 
    A hash table maps a number to either a placeholder (while the
@@ -3757,8 +3761,15 @@ string_to_number (char const *string, int base, int 
flags)
            {
              state |= E_EXP;
              cp += 3;
+#if HAVE_IEEE754_H
+             union ieee754_double u
+               = { .ieee_nan = { .exponent = -1, .quiet_nan = 1,
+                                 .mantissa0 = n >> 31 >> 1, .mantissa1 = n }};
+             value = u.d;
+#else
              /* NAN is a "positive" NaN on all known Emacs hosts.  */
              value = NAN;
+#endif
            }
          else
            cp = ecp;
diff --git a/src/print.c b/src/print.c
index da6ec1a..add2160 100644
--- a/src/print.c
+++ b/src/print.c
@@ -40,6 +40,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <ftoastr.h>
 #include <math.h>
 
+#if HAVE_IEEE754_H
+# include <ieee754.h>
+#endif
+
 #ifdef WINDOWSNT
 # include <sys/socket.h> /* for F_DUPFD_CLOEXEC */
 #endif
@@ -1011,6 +1015,12 @@ float_to_string (char *buf, double data)
     }
   if (isnan (data))
     {
+#if HAVE_IEEE754_H
+      union ieee754_double u = { .d = data };
+      uprintmax_t hi = u.ieee_nan.mantissa0;
+      return sprintf (buf, &"-%"pMu".0e+NaN"[!u.ieee_nan.negative],
+                     (hi << 31 << 1) + u.ieee_nan.mantissa1);
+#else
       /* Prepend "-" if the NaN's sign bit is negative.
         The sign bit of a double is the bit that is 1 in -0.0.  */
       static char const NaN_string[] = "0.0e+NaN";
@@ -1029,6 +1039,7 @@ float_to_string (char *buf, double data)
 
       strcpy (buf + negative, NaN_string);
       return negative + sizeof NaN_string - 1;
+#endif
     }
 
   if (NILP (Vfloat_output_format)



reply via email to

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