aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2018-08-01 00:49:39 -0700
committerPaul Eggert2018-08-01 00:51:55 -0700
commit6e37d2fd05bea373c472af1c6e80238ace5e1c94 (patch)
tree9c3090ba9e3bdb682b7702d64db98581befe1009
parente28a37438d4ba71cd8a053e956686ab29ff97b6a (diff)
downloademacs-6e37d2fd05bea373c472af1c6e80238ace5e1c94.tar.gz
emacs-6e37d2fd05bea373c472af1c6e80238ace5e1c94.zip
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.
-rw-r--r--configure.ac1
-rw-r--r--doc/lispref/numbers.texi2
-rw-r--r--etc/NEWS3
-rw-r--r--src/lread.c11
-rw-r--r--src/print.c11
5 files changed, 27 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index b6918671e40..dbdcce7c8d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1668,6 +1668,7 @@ fi
1668 1668
1669dnl checks for header files 1669dnl checks for header files
1670AC_CHECK_HEADERS_ONCE( 1670AC_CHECK_HEADERS_ONCE(
1671 ieee754.h
1671 linux/fs.h 1672 linux/fs.h
1672 malloc.h 1673 malloc.h
1673 sys/systeminfo.h 1674 sys/systeminfo.h
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 14d5059ffb3..a3317c9a260 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.
241NaNs carry a sign and a significand, and non-numeric functions treat 241NaNs carry a sign and a significand, and non-numeric functions treat
242two NaNs as equal when their 242two NaNs as equal when their
243signs and significands agree. Significands of NaNs are 243signs and significands agree. Significands of NaNs are
244machine-dependent and are not directly visible to Emacs Lisp. 244machine-dependent, as are the digits in their string representation.
245 245
246 When NaNs and signed zeros are involved, non-numeric functions like 246 When NaNs and signed zeros are involved, non-numeric functions like
247@code{eql}, @code{equal}, @code{sxhash-eql}, @code{sxhash-equal} and 247@code{eql}, @code{equal}, @code{sxhash-eql}, @code{sxhash-equal} and
diff --git a/etc/NEWS b/etc/NEWS
index f1ea8356790..9e7a765dc61 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -880,6 +880,9 @@ Formerly, some of these functions ignored signs and significands of
880NaNs. Now, all these functions treat NaN signs and significands as 880NaNs. Now, all these functions treat NaN signs and significands as
881significant. For example, (eql 0.0e+NaN -0.0e+NaN) now returns nil 881significant. For example, (eql 0.0e+NaN -0.0e+NaN) now returns nil
882because the two NaNs have different signs; formerly it returned t. 882because the two NaNs have different signs; formerly it returned t.
883Also, on platforms that have <ieee754.h> Emacs now reads and prints
884NaN significands; e.g., if X is a NaN, (format "%s" X) now returns
885"0.0e+NaN", "1.0e+NaN", etc., depending on X's significand.
883 886
884+++ 887+++
885** The function 'make-string' accepts an additional optional argument. 888** The function 'make-string' accepts an additional optional argument.
diff --git a/src/lread.c b/src/lread.c
index 50fc6ef8f3a..290b0f6bbe9 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/>. */
72#define file_tell ftell 72#define file_tell ftell
73#endif 73#endif
74 74
75#if HAVE_IEEE754_H
76# include <ieee754.h>
77#endif
78
75/* The objects or placeholders read with the #n=object form. 79/* The objects or placeholders read with the #n=object form.
76 80
77 A hash table maps a number to either a placeholder (while the 81 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)
3757 { 3761 {
3758 state |= E_EXP; 3762 state |= E_EXP;
3759 cp += 3; 3763 cp += 3;
3764#if HAVE_IEEE754_H
3765 union ieee754_double u
3766 = { .ieee_nan = { .exponent = -1, .quiet_nan = 1,
3767 .mantissa0 = n >> 31 >> 1, .mantissa1 = n }};
3768 value = u.d;
3769#else
3760 /* NAN is a "positive" NaN on all known Emacs hosts. */ 3770 /* NAN is a "positive" NaN on all known Emacs hosts. */
3761 value = NAN; 3771 value = NAN;
3772#endif
3762 } 3773 }
3763 else 3774 else
3764 cp = ecp; 3775 cp = ecp;
diff --git a/src/print.c b/src/print.c
index da6ec1aaedf..add21609cc5 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/>. */
40#include <ftoastr.h> 40#include <ftoastr.h>
41#include <math.h> 41#include <math.h>
42 42
43#if HAVE_IEEE754_H
44# include <ieee754.h>
45#endif
46
43#ifdef WINDOWSNT 47#ifdef WINDOWSNT
44# include <sys/socket.h> /* for F_DUPFD_CLOEXEC */ 48# include <sys/socket.h> /* for F_DUPFD_CLOEXEC */
45#endif 49#endif
@@ -1011,6 +1015,12 @@ float_to_string (char *buf, double data)
1011 } 1015 }
1012 if (isnan (data)) 1016 if (isnan (data))
1013 { 1017 {
1018#if HAVE_IEEE754_H
1019 union ieee754_double u = { .d = data };
1020 uprintmax_t hi = u.ieee_nan.mantissa0;
1021 return sprintf (buf, &"-%"pMu".0e+NaN"[!u.ieee_nan.negative],
1022 (hi << 31 << 1) + u.ieee_nan.mantissa1);
1023#else
1014 /* Prepend "-" if the NaN's sign bit is negative. 1024 /* Prepend "-" if the NaN's sign bit is negative.
1015 The sign bit of a double is the bit that is 1 in -0.0. */ 1025 The sign bit of a double is the bit that is 1 in -0.0. */
1016 static char const NaN_string[] = "0.0e+NaN"; 1026 static char const NaN_string[] = "0.0e+NaN";
@@ -1029,6 +1039,7 @@ float_to_string (char *buf, double data)
1029 1039
1030 strcpy (buf + negative, NaN_string); 1040 strcpy (buf + negative, NaN_string);
1031 return negative + sizeof NaN_string - 1; 1041 return negative + sizeof NaN_string - 1;
1042#endif
1032 } 1043 }
1033 1044
1034 if (NILP (Vfloat_output_format) 1045 if (NILP (Vfloat_output_format)