diff options
author | Tom Tromey <tom@tromey.com> | 2018-08-09 17:56:53 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-08-09 17:56:53 -0600 |
commit | accb7b7ecc19f85c2750ded1046a464bc73c6a52 (patch) | |
tree | 1aa94af022d6700a93a8ff2b73f5b210046ac010 /src/print.c | |
parent | f822a2516d88eeb2118fbbc8554f155e86dfd74e (diff) | |
parent | 53483df0de0085dbc9ef0b15a0f629ab808b0147 (diff) | |
download | emacs-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.c | 48 |
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)) |