# HG changeset patch # User Paul Eggert # Date 904598308 0 # Node ID b468525b44b8690de800b5d5235ffd9601e82f4e # Parent 5c0a4ed1390046fa25cdba69c08215b8cbda344f (read1): Don't assume that atof ("-0.0") yields -0.0. Handle leading '-' uniformly for zeros, infinities, and NaNs. diff -r 5c0a4ed13900 -r b468525b44b8 src/lread.c --- a/src/lread.c Mon Aug 31 19:59:02 1998 +0000 +++ b/src/lread.c Mon Aug 31 21:18:28 1998 +0000 @@ -2106,22 +2106,35 @@ #ifdef LISP_FLOAT_TYPE if (isfloat_string (read_buffer)) { + /* Compute NaN and infinities using 0.0 in a variable, + to cope with compilers that think they are smarter + than us. */ double zero = 0.0; - double value = atof (read_buffer); - if (read_buffer[0] == '-' && value == 0.0) - value *= -1.0; - /* The only way this can be true, after isfloat_string + + double value; + + /* Negate the value ourselves. This treats 0, NaNs, + and infinity properly on IEEE floating point hosts, + and works around a common bug where atof ("-0.0") + drops the sign. */ + int negative = read_buffer[0] == '-'; + + /* The only way p[-1] can be 'F' or 'N', after isfloat_string returns 1, is if the input ends in e+INF or e+NaN. */ - if (p[-1] == 'F' || p[-1] == 'N') + switch (p[-1]) { - if (p[-1] == 'N') - value = zero / zero; - else if (read_buffer[0] == '-') - value = - 1.0 / zero; - else - value = 1.0 / zero; + case 'F': + value = 1.0 / zero; + break; + case 'N': + value = zero / zero; + break; + default: + value = atof (read_buffer + negative); + break; } - return make_float (value); + + return make_float (negative ? - value : value); } #endif }