summaryrefslogtreecommitdiff
path: root/src/print.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2018-08-09 17:56:53 -0600
committerTom Tromey <tom@tromey.com>2018-08-09 17:56:53 -0600
commitaccb7b7ecc19f85c2750ded1046a464bc73c6a52 (patch)
tree1aa94af022d6700a93a8ff2b73f5b210046ac010 /src/print.c
parentf822a2516d88eeb2118fbbc8554f155e86dfd74e (diff)
parent53483df0de0085dbc9ef0b15a0f629ab808b0147 (diff)
downloademacs-accb7b7ecc19f85c2750ded1046a464bc73c6a52.tar.gz
emacs-accb7b7ecc19f85c2750ded1046a464bc73c6a52.tar.bz2
emacs-accb7b7ecc19f85c2750ded1046a464bc73c6a52.zip
Merge remote-tracking branch 'origin/master' into feature/bignum
Diffstat (limited to 'src/print.c')
-rw-r--r--src/print.c48
1 files changed, 16 insertions, 32 deletions
diff --git a/src/print.c b/src/print.c
index 998ff2dc0c6..3819c505b12 100644
--- a/src/print.c
+++ b/src/print.c
@@ -38,6 +38,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <c-ctype.h>
#include <float.h>
#include <ftoastr.h>
+#include <math.h>
+
+#if IEEE_FLOATING_POINT
+# include <ieee754.h>
+#endif
#ifdef WINDOWSNT
# include <sys/socket.h> /* for F_DUPFD_CLOEXEC */
@@ -1001,43 +1006,22 @@ float_to_string (char *buf, double data)
int width;
int len;
- /* Check for plus infinity in a way that won't lose
- if there is no plus infinity. */
- if (data == data / 2 && data > 1.0)
- {
- static char const infinity_string[] = "1.0e+INF";
- strcpy (buf, infinity_string);
- return sizeof infinity_string - 1;
- }
- /* Likewise for minus infinity. */
- if (data == data / 2 && data < -1.0)
+ if (isinf (data))
{
static char const minus_infinity_string[] = "-1.0e+INF";
- strcpy (buf, minus_infinity_string);
- return sizeof minus_infinity_string - 1;
+ bool positive = 0 < data;
+ strcpy (buf, minus_infinity_string + positive);
+ return sizeof minus_infinity_string - 1 - positive;
}
- /* Check for NaN in a way that won't fail if there are no NaNs. */
- if (! (data * 0.0 >= 0.0))
+#if IEEE_FLOATING_POINT
+ if (isnan (data))
{
- /* 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";
- int i;
- union { double d; char c[sizeof (double)]; } u_data, u_minus_zero;
- bool negative = 0;
- u_data.d = data;
- u_minus_zero.d = - 0.0;
- for (i = 0; i < sizeof (double); i++)
- if (u_data.c[i] & u_minus_zero.c[i])
- {
- *buf = '-';
- negative = 1;
- break;
- }
-
- strcpy (buf + negative, NaN_string);
- return negative + sizeof NaN_string - 1;
+ 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);
}
+#endif
if (NILP (Vfloat_output_format)
|| !STRINGP (Vfloat_output_format))