* 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).