diff options
| author | Paul Eggert | 1998-08-31 21:18:28 +0000 |
|---|---|---|
| committer | Paul Eggert | 1998-08-31 21:18:28 +0000 |
| commit | a8972052908f8ca89bf5f1dd87dd33cc4bbf42a0 (patch) | |
| tree | 728d1cc7adf9d4c598c2ecdb4601065a1520070f /src/lread.c | |
| parent | 56c8bc03c4728043d79e4928274d3fac308158d6 (diff) | |
| download | emacs-a8972052908f8ca89bf5f1dd87dd33cc4bbf42a0.tar.gz emacs-a8972052908f8ca89bf5f1dd87dd33cc4bbf42a0.zip | |
(read1): Don't assume that atof ("-0.0") yields -0.0.
Handle leading '-' uniformly for zeros, infinities, and NaNs.
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/lread.c b/src/lread.c index 8ff3bd4206d..04f34e88690 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2106,22 +2106,35 @@ read1 (readcharfun, pch, first_in_list) | |||
| 2106 | #ifdef LISP_FLOAT_TYPE | 2106 | #ifdef LISP_FLOAT_TYPE |
| 2107 | if (isfloat_string (read_buffer)) | 2107 | if (isfloat_string (read_buffer)) |
| 2108 | { | 2108 | { |
| 2109 | /* Compute NaN and infinities using 0.0 in a variable, | ||
| 2110 | to cope with compilers that think they are smarter | ||
| 2111 | than us. */ | ||
| 2109 | double zero = 0.0; | 2112 | double zero = 0.0; |
| 2110 | double value = atof (read_buffer); | 2113 | |
| 2111 | if (read_buffer[0] == '-' && value == 0.0) | 2114 | double value; |
| 2112 | value *= -1.0; | 2115 | |
| 2113 | /* The only way this can be true, after isfloat_string | 2116 | /* Negate the value ourselves. This treats 0, NaNs, |
| 2117 | and infinity properly on IEEE floating point hosts, | ||
| 2118 | and works around a common bug where atof ("-0.0") | ||
| 2119 | drops the sign. */ | ||
| 2120 | int negative = read_buffer[0] == '-'; | ||
| 2121 | |||
| 2122 | /* The only way p[-1] can be 'F' or 'N', after isfloat_string | ||
| 2114 | returns 1, is if the input ends in e+INF or e+NaN. */ | 2123 | returns 1, is if the input ends in e+INF or e+NaN. */ |
| 2115 | if (p[-1] == 'F' || p[-1] == 'N') | 2124 | switch (p[-1]) |
| 2116 | { | 2125 | { |
| 2117 | if (p[-1] == 'N') | 2126 | case 'F': |
| 2118 | value = zero / zero; | 2127 | value = 1.0 / zero; |
| 2119 | else if (read_buffer[0] == '-') | 2128 | break; |
| 2120 | value = - 1.0 / zero; | 2129 | case 'N': |
| 2121 | else | 2130 | value = zero / zero; |
| 2122 | value = 1.0 / zero; | 2131 | break; |
| 2132 | default: | ||
| 2133 | value = atof (read_buffer + negative); | ||
| 2134 | break; | ||
| 2123 | } | 2135 | } |
| 2124 | return make_float (value); | 2136 | |
| 2137 | return make_float (negative ? - value : value); | ||
| 2125 | } | 2138 | } |
| 2126 | #endif | 2139 | #endif |
| 2127 | } | 2140 | } |