* min, max and nans @ 2003-05-05 23:26 Kevin Ryde 2003-05-17 20:02 ` Marius Vollmer 0 siblings, 1 reply; 9+ messages in thread From: Kevin Ryde @ 2003-05-05 23:26 UTC (permalink / raw) While nosing around mpz_cmp_d in min and max, I noticed guile> (max +nan.0 0) +nan.0 guile> (max 0 +nan.0) 0.0 which strikes me as a bit inconsistent. Is there a theory on what min and max should do with nans? I'd think returning nan if any argument is a nan would be a good idea. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-05-05 23:26 min, max and nans Kevin Ryde @ 2003-05-17 20:02 ` Marius Vollmer 2003-05-30 0:20 ` Kevin Ryde 2003-06-15 0:17 ` Kevin Ryde 0 siblings, 2 replies; 9+ messages in thread From: Marius Vollmer @ 2003-05-17 20:02 UTC (permalink / raw) Cc: guile-devel Kevin Ryde <user42@zip.com.au> writes: > Is there a theory on what min and max should do with nans? I'd think > returning nan if any argument is a nan would be a good idea. That's what I think, too. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-05-17 20:02 ` Marius Vollmer @ 2003-05-30 0:20 ` Kevin Ryde 2003-06-04 16:08 ` Kevin Ryde 2003-06-15 0:17 ` Kevin Ryde 1 sibling, 1 reply; 9+ messages in thread From: Kevin Ryde @ 2003-05-30 0:20 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 504 bytes --] Marius Vollmer <mvo@zagadka.de> writes: > > That's what I think, too. * numbers.c (scm_max, scm_min): For inum, bignum and real, if other operand is NaN, then return NaN. Also avoid passing NaN to mpz_cmp_d. * tests/numbers.test (max, min): Add tests involving NaNs. Some cases just need the sense of the > or < test put the right way to allow for it being false when involving a NaN. A couple are right already. For bignums and for real/real an actual isnan is necessary. [-- Attachment #2: numbers.c.min-max-nan.diff --] [-- Type: text/plain, Size: 3908 bytes --] --- 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); } [-- Attachment #3: numbers.test.min-max-nan.diff --] [-- Type: text/plain, Size: 2664 bytes --] --- numbers.test.~1.23.~ 2003-05-10 13:01:51.000000000 +1000 +++ numbers.test 2003-05-26 17:45:08.000000000 +1000 @@ -1646,6 +1646,9 @@ ;;; (with-test-prefix "max" + (pass-if (= 456.0 (max 123.0 456.0))) + (pass-if (= 456.0 (max 456.0 123.0))) + (let ((big*2 (* fixnum-max 2)) (big*3 (* fixnum-max 3)) (big*4 (* fixnum-max 4)) @@ -1654,7 +1657,15 @@ (pass-if (= +inf.0 (max big*5 +inf.0))) (pass-if (= +inf.0 (max +inf.0 big*5))) (pass-if (= big*5 (max big*5 -inf.0))) - (pass-if (= big*5 (max -inf.0 big*5)))) + (pass-if (= big*5 (max -inf.0 big*5))) + + (pass-if (nan? (max 123 +nan.0))) + (pass-if (nan? (max big*5 +nan.0))) + (pass-if (nan? (max 123.0 +nan.0))) + (pass-if (nan? (max +nan.0 123))) + (pass-if (nan? (max +nan.0 big*5))) + (pass-if (nan? (max +nan.0 123.0))) + (pass-if (nan? (max +nan.0 +nan.0)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that @@ -1672,7 +1683,12 @@ (1+ (ash 1 1024)) (- (1- (ash 1 1024))) (- (ash 1 1024)) - (- (1+ (ash 1 1024)))))) + (- (1+ (ash 1 1024))))) + + ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make + ;; sure we've avoided that + (pass-if (nan? (max (ash 1 2048) +nan.0))) + (pass-if (nan? (max +nan.0 (ash 1 2048))))) ;;; ;;; min @@ -1681,6 +1697,9 @@ ;; FIXME: unfinished... (with-test-prefix "min" + (pass-if (= 123.0 (min 123.0 456.0))) + (pass-if (= 123.0 (min 456.0 123.0))) + (let ((big*2 (* fixnum-max 2)) (big*3 (* fixnum-max 3)) (big*4 (* fixnum-max 4)) @@ -1706,7 +1725,15 @@ (pass-if (= big*5 (min big*5 +inf.0))) (pass-if (= big*5 (min +inf.0 big*5))) (pass-if (= -inf.0 (min big*5 -inf.0))) - (pass-if (= -inf.0 (min -inf.0 big*5)))) + (pass-if (= -inf.0 (min -inf.0 big*5))) + + (pass-if (nan? (min 123 +nan.0))) + (pass-if (nan? (min big*5 +nan.0))) + (pass-if (nan? (min 123.0 +nan.0))) + (pass-if (nan? (min +nan.0 123))) + (pass-if (nan? (min +nan.0 big*5))) + (pass-if (nan? (min +nan.0 123.0))) + (pass-if (nan? (min +nan.0 +nan.0)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that @@ -1724,7 +1751,12 @@ (1+ (ash 1 1024)) (- (1- (ash 1 1024))) (- (ash 1 1024)) - (- (1+ (ash 1 1024)))))) + (- (1+ (ash 1 1024))))) + + ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make + ;; sure we've avoided that + (pass-if (nan? (min (- (ash 1 2048)) (- +nan.0)))) + (pass-if (nan? (min (- +nan.0) (- (ash 1 2048)))))) ;;; ;;; + [-- Attachment #4: Type: text/plain, Size: 142 bytes --] _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-05-30 0:20 ` Kevin Ryde @ 2003-06-04 16:08 ` Kevin Ryde 2003-06-05 12:48 ` Marius Vollmer 0 siblings, 1 reply; 9+ messages in thread From: Kevin Ryde @ 2003-06-04 16:08 UTC (permalink / raw) I wrote: > * numbers.c (scm_max, scm_min): For inum, bignum and real, if other > operand is NaN, then return NaN. Also avoid passing NaN to mpz_cmp_d. > > * tests/numbers.test (max, min): Add tests involving NaNs. I made this change. Actually, I had a bit of a brain fade and added the tests the other day, but not the code. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-06-04 16:08 ` Kevin Ryde @ 2003-06-05 12:48 ` Marius Vollmer 2003-06-06 16:03 ` Mikael Djurfeldt 0 siblings, 1 reply; 9+ messages in thread From: Marius Vollmer @ 2003-06-05 12:48 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> writes: > I made this change. Actually, I had a bit of a brain fade and added > the tests the other day, but not the code. :-) I noticed because the snapshots didn't build successfully, but I thought I'd give you a day or two before sending you the build log... Should I make the build logs available as well? In what form? For a short time, they were posted to guile-cvs@gnu.org. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-06-05 12:48 ` Marius Vollmer @ 2003-06-06 16:03 ` Mikael Djurfeldt 2003-06-06 23:17 ` Marius Vollmer 0 siblings, 1 reply; 9+ messages in thread From: Mikael Djurfeldt @ 2003-06-06 16:03 UTC (permalink / raw) Cc: guile-devel Marius Vollmer <mvo@zagadka.de> writes: > Kevin Ryde <user42@zip.com.au> writes: > >> I made this change. Actually, I had a bit of a brain fade and added >> the tests the other day, but not the code. > > :-) I noticed because the snapshots didn't build successfully, but I > thought I'd give you a day or two before sending you the build log... > > Should I make the build logs available as well? In what form? For a > short time, they were posted to guile-cvs@gnu.org. In my opinion, the idea of sending build logs at failure (not when Guile compiles and tests OK) to guile-cvs@gnu.org is an excellent idea. If I have at any time been critical against it, it was because it is a good idea to start off with no build failures so that people feel motivated to fix things. M _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-06-06 16:03 ` Mikael Djurfeldt @ 2003-06-06 23:17 ` Marius Vollmer 0 siblings, 0 replies; 9+ messages in thread From: Marius Vollmer @ 2003-06-06 23:17 UTC (permalink / raw) Cc: guile-devel Mikael Djurfeldt <djurfeldt@nada.kth.se> writes: > In my opinion, the idea of sending build logs at failure (not when > Guile compiles and tests OK) to guile-cvs@gnu.org is an excellent > idea. > > If I have at any time been critical against it, it was because it is a > good idea to start off with no build failures so that people feel > motivated to fix things. Hehe, yeah, I could totally understand your point (if I understood it ;-). For those interested: the snapshots were failing for over a week due to problems in the build environment (I think). I didn't get around to fix the build environment in a timely manner and so people saw error logs that were not relevant to them. That could only teach them to ignore these logs. So I stopped posting them automatically. We _did_ start off with no build failures but that was hard to notice since no logs are sent when there is no build failure. I think it is also OK when just I myself watch the logs and contact the people that I deem responsible for failures. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-05-17 20:02 ` Marius Vollmer 2003-05-30 0:20 ` Kevin Ryde @ 2003-06-15 0:17 ` Kevin Ryde 2003-06-18 23:36 ` Marius Vollmer 1 sibling, 1 reply; 9+ messages in thread From: Kevin Ryde @ 2003-06-15 0:17 UTC (permalink / raw) I notice C99 fmin and fmax return the other operand when one is a NaN, and return NaN only when both are NaNs. I tend to think of nan as indicating something evil, and it should be propagated. But the c99 way would be a possibility to consider. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: min, max and nans 2003-06-15 0:17 ` Kevin Ryde @ 2003-06-18 23:36 ` Marius Vollmer 0 siblings, 0 replies; 9+ messages in thread From: Marius Vollmer @ 2003-06-18 23:36 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> writes: > I notice C99 fmin and fmax return the other operand when one is a NaN, > and return NaN only when both are NaNs. > > I tend to think of nan as indicating something evil, and it should be > propagated. But the c99 way would be a possibility to consider. Yep. Does the IEEE standard say aomething about max and min? -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2003-06-18 23:36 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-05-05 23:26 min, max and nans Kevin Ryde 2003-05-17 20:02 ` Marius Vollmer 2003-05-30 0:20 ` Kevin Ryde 2003-06-04 16:08 ` Kevin Ryde 2003-06-05 12:48 ` Marius Vollmer 2003-06-06 16:03 ` Mikael Djurfeldt 2003-06-06 23:17 ` Marius Vollmer 2003-06-15 0:17 ` Kevin Ryde 2003-06-18 23:36 ` Marius Vollmer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).