--- numbers.c.~1.188.~ 2003-05-13 09:14:53.000000000 +1000 +++ numbers.c 2003-05-26 17:42:15.000000000 +1000 @@ -2806,7 +2806,8 @@ return (sgn < 0) ? x : y; } else if (SCM_REALP (y)) { double z = xx; - return (z <= SCM_REAL_VALUE (y)) ? y : scm_make_real (z); + /* if y==NaN then ">" is false and we return NaN */ + return (z > SCM_REAL_VALUE (y)) ? scm_make_real (z) : y; } else { SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max); } @@ -2820,7 +2821,11 @@ scm_remember_upto_here_2 (x, y); return (cmp > 0) ? x : y; } else if (SCM_REALP (y)) { - int cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y)); + double yy = SCM_REAL_VALUE (y); + int cmp; + if (xisnan (yy)) + return y; + cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (x), yy); scm_remember_upto_here_1 (x); return (cmp > 0) ? x : y; } else { @@ -2829,13 +2834,23 @@ } else if (SCM_REALP (x)) { if (SCM_INUMP (y)) { double z = SCM_INUM (y); + /* if x==NaN then "<" is false and we return NaN */ return (SCM_REAL_VALUE (x) < z) ? scm_make_real (z) : x; } else if (SCM_BIGP (y)) { - int cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x)); + double xx = SCM_REAL_VALUE (x); + int cmp; + if (xisnan (xx)) + return x; + cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x)); scm_remember_upto_here_1 (y); return (cmp < 0) ? x : y; } else if (SCM_REALP (y)) { - return (SCM_REAL_VALUE (x) < SCM_REAL_VALUE (y)) ? y : x; + /* if x==NaN then our explicit check means we return NaN + if y==NaN then ">" is false and we return NaN + a call to isnan is unavoidable, since it's the only way to know + which of x or y causes any compares to be false */ + double xx = SCM_REAL_VALUE (x); + return (xisnan (xx) || xx > SCM_REAL_VALUE (y)) ? x : y; } else { SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max); } @@ -2872,6 +2887,7 @@ return (sgn < 0) ? y : x; } else if (SCM_REALP (y)) { double z = xx; + /* if y==NaN then "<" is false and we return NaN */ return (z < SCM_REAL_VALUE (y)) ? scm_make_real (z) : y; } else { SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min); @@ -2886,7 +2902,11 @@ scm_remember_upto_here_2 (x, y); return (cmp > 0) ? y : x; } else if (SCM_REALP (y)) { - int cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y)); + double yy = SCM_REAL_VALUE (y); + int cmp; + if (xisnan (yy)) + return y; + cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (x), yy); scm_remember_upto_here_1 (x); return (cmp > 0) ? y : x; } else { @@ -2895,13 +2915,23 @@ } else if (SCM_REALP (x)) { if (SCM_INUMP (y)) { double z = SCM_INUM (y); - return (SCM_REAL_VALUE (x) <= z) ? x : scm_make_real (z); + /* if x==NaN then ">" is false and we return NaN */ + return (SCM_REAL_VALUE (x) > z) ? scm_make_real (z) : x; } else if (SCM_BIGP (y)) { - int cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x)); + double xx = SCM_REAL_VALUE (x); + int cmp; + if (xisnan (xx)) + return x; + cmp = xmpz_cmp_d (SCM_I_BIG_MPZ (y), xx); scm_remember_upto_here_1 (y); return (cmp < 0) ? y : x; } else if (SCM_REALP (y)) { - return (SCM_REAL_VALUE (x) < SCM_REAL_VALUE (y)) ? x : y; + /* if x==NaN then our explicit check means we return NaN + if y==NaN then "<" is false and we return NaN + a call to isnan is unavoidable, since it's the only way to know + which of x or y causes any compares to be false */ + double xx = SCM_REAL_VALUE (x); + return (xisnan (xx) || xx < SCM_REAL_VALUE (y)) ? x : y; } else { SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min); }