* Q on NaN
@ 2005-06-24 19:06 Drew Adams
2005-06-24 19:33 ` Drew Adams
0 siblings, 1 reply; 12+ messages in thread
From: Drew Adams @ 2005-06-24 19:06 UTC (permalink / raw)
Consider this:
(condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
In older versions of Emacs (at least prior to April 2005 CVS), this would
evaluate to nil. Now, it evaluates to -0.0NaN (on Windows, at least), which
breaks the encompassing code (which tests the above expression for non-nil).
Fair enough. I can modify the code like so:
(and (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
(bar foo)) ; foo must be a number, not a NaN
What function do I use for bar?
`numberp' doesn't work, since (numberp -0.0NaN) is non-nil. That seems odd
to me, since NaN means "not a number" and numberp means "a number", but I
guess I can live with a little oddness.
In the Elisp manual, I didn't find a predicate to test for NaN.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Q on NaN
2005-06-24 19:06 Q on NaN Drew Adams
@ 2005-06-24 19:33 ` Drew Adams
2005-06-24 19:46 ` Drew Adams
2005-06-24 21:01 ` Eli Zaretskii
0 siblings, 2 replies; 12+ messages in thread
From: Drew Adams @ 2005-06-24 19:33 UTC (permalink / raw)
I said this:
(condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
In older versions of Emacs (at least prior to April 2005 CVS),
this would evaluate to nil. Now, it evaluates to -0.0NaN.
I can modify the code like so:
(and (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
(bar foo)) ; foo must be a number, not a NaN
What function do I use for bar?
`numberp' doesn't work, since (numberp -0.0NaN) is non-nil.
To make the point simpler:
(numberp (/0.0 0.0)) returns t. That seems like a bug to me.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Q on NaN
2005-06-24 19:33 ` Drew Adams
@ 2005-06-24 19:46 ` Drew Adams
2005-06-24 21:01 ` Eli Zaretskii
1 sibling, 0 replies; 12+ messages in thread
From: Drew Adams @ 2005-06-24 19:46 UTC (permalink / raw)
Still following up on my own post:
(condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
In older versions of Emacs (at least prior to April 2005 CVS),
this would evaluate to nil. Now, it evaluates to -0.0NaN.
I can modify the code like so:
(and (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
(bar foo)) ; foo must be a number, not a NaN
What function do I use for bar?
`numberp' doesn't work, since (numberp -0.0NaN) is non-nil.
To make the point simpler:
(numberp (/0.0 0.0)) returns t. That seems like a bug to me.
If this is not considered a bug, and `numberp' should return non-nil for
NaN, as it currently does, then what are all the possible NaN values to
test?
The Elisp manual mentions that the read syntax for (/ 0.0 0.0) is 0.0e+NaN.
On my system it is in fact -0.0e+NaN. Are there additional NaN values, or
would this be a sufficient test for NaN-ness, to replace `numberp':
(let ((foo (/0.0 0.0)))
(and (not (equal -0.0e+NaN foo)) (not (equal 0.0e+NaN foo))))
(Note that (= -0.0e+NaN foo) returns nil, while (equal -0.0e+NaN foo)
returns `t'.)
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Q on NaN
2005-06-24 21:01 ` Eli Zaretskii
@ 2005-06-24 20:26 ` Drew Adams
2005-06-24 20:56 ` Gaëtan LEURENT
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Drew Adams @ 2005-06-24 20:26 UTC (permalink / raw)
> (numberp (/0.0 0.0)) returns t. That seems like a bug to me.
Maybe it is, maybe it isn't. (elisp)Arithmetic Operations says:
If you divide an integer by 0, an `arith-error' error is signaled.
(*Note Errors::.) Floating point division by zero returns either
infinity or a NaN if your machine supports IEEE floating point;
otherwise, it signals an `arith-error' error.
So if the machine supports IEEE floating point (most modern machines
do), you aren't supposed to get `arith-error' in this case. Maybe
this is a bit counter-intuitive for someone who never did futz with
NaNs, but at least Emacs behaves consistently with the docs.
I didn't say above that (/0.0 0.0) should give `arith-error'. I suggested
that perhaps `numberp' should return nil for a NaN argument, since "NaN"
means "not a number" and "numberp" means "a number". NaN is a floating-point
value, but is it a number?
As for a way to test for a NaN, try this:
(= (/ 0.0 0.0) (/ 0.0 0.0))
It should evaluate to nil, since a NaN is defined to fail _any_
arithmetic comparison, even a comparison to itself.
That doesn't tell me how to test if `foobar' is a NaN. See my previous
email: I knew I could test `(equal foo 0.0e+Nan)', but I thought I would
need to test against all of the possible NaN values.
A bit of experimenting shows, however, that, at least on my system, the
mantissa doesn't matter: (equal 0.0e+NaN -0.0e+NaN) is `t', as is (equal
1.0e+NaN -99.5e+NaN). There is effectively only a single NaN value.
So I guess the answer to my original question is this:
(and (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
(not (equal 0.0e+NaN foo)))
Ugly, perhaps, but usable.
BTW, here is something I didn't expect:
`M-: 0.0e+NaN' returns -0.0e+NaN
`M-: -0.0e+NaN' returns 0.0e+NaN
The reader seems to flip the (irrelevant) sign.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 20:26 ` Drew Adams
@ 2005-06-24 20:56 ` Gaëtan LEURENT
2005-06-24 20:59 ` Luc Teirlinck
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Gaëtan LEURENT @ 2005-06-24 20:56 UTC (permalink / raw)
Cc: emacs-devel
Drew Adams wrote on 24 Jun 2005 22:26:23 +0200:
> That doesn't tell me how to test if `foobar' is a NaN. See my previous
> email: I knew I could test `(equal foo 0.0e+Nan)', but I thought I would
> need to test against all of the possible NaN values.
You just need to test (= foobar foobar)
--
Gaëtan LEURENT
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 20:26 ` Drew Adams
2005-06-24 20:56 ` Gaëtan LEURENT
@ 2005-06-24 20:59 ` Luc Teirlinck
2005-06-24 22:03 ` Eli Zaretskii
2005-06-25 13:35 ` Richard M. Stallman
3 siblings, 0 replies; 12+ messages in thread
From: Luc Teirlinck @ 2005-06-24 20:59 UTC (permalink / raw)
Cc: emacs-devel
Drew Adams wrote:
That doesn't tell me how to test if `foobar' is a NaN. See my previous
email: I knew I could test `(equal foo 0.0e+Nan)', but I thought I would
need to test against all of the possible NaN values.
The GNU C library has an isnan macro. From Lisp you could do:
(defun nanp (obj)
"Return t if OBJ is a NaN; nil otherwise,"
(and (numberp obj) (/= obj obj)))
Sincerely,
Luc.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 19:33 ` Drew Adams
2005-06-24 19:46 ` Drew Adams
@ 2005-06-24 21:01 ` Eli Zaretskii
2005-06-24 20:26 ` Drew Adams
1 sibling, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2005-06-24 21:01 UTC (permalink / raw)
Cc: emacs-devel
> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Fri, 24 Jun 2005 12:33:53 -0700
>
> (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
> In older versions of Emacs (at least prior to April 2005 CVS),
> this would evaluate to nil. Now, it evaluates to -0.0NaN.
> I can modify the code like so:
> (and (condition-case nil (setq foo (/ 0.0 0.0)) (arith-error nil))
> (bar foo)) ; foo must be a number, not a NaN
> What function do I use for bar?
> `numberp' doesn't work, since (numberp -0.0NaN) is non-nil.
>
> To make the point simpler:
>
> (numberp (/0.0 0.0)) returns t. That seems like a bug to me.
Maybe it is, maybe it isn't. (elisp)Arithmetic Operations says:
If you divide an integer by 0, an `arith-error' error is signaled.
(*Note Errors::.) Floating point division by zero returns either
infinity or a NaN if your machine supports IEEE floating point;
otherwise, it signals an `arith-error' error.
So if the machine supports IEEE floating point (most modern machines
do), you aren't supposed to get `arith-error' in this case. Maybe
this is a bit counter-intuitive for someone who never did futz with
NaNs, but at least Emacs behaves consistently with the docs.
As for a way to test for a NaN, try this:
(= (/ 0.0 0.0) (/ 0.0 0.0))
It should evaluate to nil, since a NaN is defined to fail _any_
arithmetic comparison, even a comparison to itself.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Q on NaN
2005-06-24 22:03 ` Eli Zaretskii
@ 2005-06-24 21:49 ` Drew Adams
2005-06-24 22:31 ` Luc Teirlinck
0 siblings, 1 reply; 12+ messages in thread
From: Drew Adams @ 2005-06-24 21:49 UTC (permalink / raw)
> I didn't say above that (/0.0 0.0) should give `arith-error'.
Well, you seemed to: you complained that it did so in previous
versions.
No, I said "fair enough" to that change in behavior. I did not suggest it
was a bug. My question was about numberp's behavior:
> I suggested that perhaps `numberp' should return nil for
> a NaN argument, since "NaN"
> means "not a number" and "numberp" means "a number".
> NaN is a floating-point value, but is it a number?
Any floating-point value is a ``number'' as far as `numberp' is
concerned. The fact that NaN is a short for not-a-number does not
mean that Lisp should treat it like that.
I can see that from the behavior, but then perhaps it should be mentioned
explicitly in the doc. Since the names suggest something different, perhaps
a note of clarification should be added.
> As for a way to test for a NaN, try this:
> (= (/ 0.0 0.0) (/ 0.0 0.0))
> It should evaluate to nil, since a NaN is defined to fail _any_
> arithmetic comparison, even a comparison to itself.
>
> That doesn't tell me how to test if `foobar' is a NaN.
Exactly the same: (= foobar foobar). (Did you try that?)
Right. Got it; thanks. A couple of people replied with the same solution.
I am using (equal 0.0e+Nan), which also seems to work (and if equivalent,
would perhaps be clearer, since it mentions NaN: anything equal to NaN is
NaN). Does anyone know that these are not equivalent:
(equal 0.0e+NaN) <=?=> (and (numberp x) (/= x x))
That is, are there any objects equal to 0.0e+NaN that are not NaN?
It might also be useful to mention such an idiom - either expression - in
the doc, or else to provide a predicate.
> See my previous email: I knew I could test
> `(equal foo 0.0e+Nan)', but I thought I would
> need to test against all of the possible NaN values.
No need: the arithmetic equality trick takes care of all of the
possible values.
Right. All NaNs are `equal', but they are not `=', even to themselves.
Note that you should use `=', not `equal' (nor `eql', btw).
Yes, for testing a numberp to see if it is not NaN. However, I am testing an
arbitrary object. For that, (and (numberp x) (/= x x)) works and (equal x
0.0e+Nan) works. For the latter test, it must be `equal' or `eql', not `='
or `eq'.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 20:26 ` Drew Adams
2005-06-24 20:56 ` Gaëtan LEURENT
2005-06-24 20:59 ` Luc Teirlinck
@ 2005-06-24 22:03 ` Eli Zaretskii
2005-06-24 21:49 ` Drew Adams
2005-06-25 13:35 ` Richard M. Stallman
3 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2005-06-24 22:03 UTC (permalink / raw)
Cc: emacs-devel
> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Fri, 24 Jun 2005 13:26:23 -0700
>
> I didn't say above that (/0.0 0.0) should give `arith-error'.
Well, you seemed to: you complained that it did so in previous
versions.
> I suggested
> that perhaps `numberp' should return nil for a NaN argument, since "NaN"
> means "not a number" and "numberp" means "a number". NaN is a floating-point
> value, but is it a number?
Any floating-point value is a ``number'' as far as `numberp' is
concerned. The fact that NaN is a short for not-a-number does not
mean that Lisp should treat it like that.
> As for a way to test for a NaN, try this:
> (= (/ 0.0 0.0) (/ 0.0 0.0))
> It should evaluate to nil, since a NaN is defined to fail _any_
> arithmetic comparison, even a comparison to itself.
>
> That doesn't tell me how to test if `foobar' is a NaN.
Exactly the same: (= foobar foobar). (Did you try that?)
> See my previous
> email: I knew I could test `(equal foo 0.0e+Nan)', but I thought I would
> need to test against all of the possible NaN values.
No need: the arithmetic equality trick takes care of all of the
possible values. Note that you should use `=', not `equal' (nor
`eql', btw).
> BTW, here is something I didn't expect:
>
> `M-: 0.0e+NaN' returns -0.0e+NaN
> `M-: -0.0e+NaN' returns 0.0e+NaN
>
> The reader seems to flip the (irrelevant) sign.
I think it's not the reader, but the underlying library's printf
family.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 21:49 ` Drew Adams
@ 2005-06-24 22:31 ` Luc Teirlinck
2005-06-24 22:54 ` Drew Adams
0 siblings, 1 reply; 12+ messages in thread
From: Luc Teirlinck @ 2005-06-24 22:31 UTC (permalink / raw)
Cc: emacs-devel
Drew Adams wrote:
Does anyone know that these are not equivalent:
(equal 0.0e+NaN) <=?=> (and (numberp x) (/= x x))
That is, are there any objects equal to 0.0e+NaN that are not NaN?
They are equivalent. internal_equal contains:
case Lisp_Float:
{
double d1, d2;
d1 = extract_float (o1);
d2 = extract_float (o2);
/* If d is a NaN, then d != d. Two NaNs should be `equal' even
though they are not =. */
return d1 == d2 || (d1 != d1 && d2 != d2);
}
Yes, for testing a numberp to see if it is not NaN. However, I am
testing an arbitrary object. For that, (and (numberp x) (/= x x))
works and (equal x 0.0e+Nan) works.
Yes.
Sincerely,
Luc.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Q on NaN
2005-06-24 22:31 ` Luc Teirlinck
@ 2005-06-24 22:54 ` Drew Adams
0 siblings, 0 replies; 12+ messages in thread
From: Drew Adams @ 2005-06-24 22:54 UTC (permalink / raw)
(equal 0.0e+NaN) <=?=> (and (numberp x) (/= x x))
That is, are there any objects equal to 0.0e+NaN that are not NaN?
They are equivalent. internal_equal contains:
...
/* If d is a NaN, then d != d. Two NaNs should be `equal' even
though they are not =. */
Thanks for confirming. I guess I could have searched the code myself - mea
culpa.
Given the equivalence, I suggest that the clearest idiom is (equal foo
0.0e+NaN).
We should mention this use of `equal' with NaN in the doc: anything `equal'
to a NaN is NaN (all NaN are `equal').
We should also mention the trick (and (numberp foo) (/= foo foo)) ==> foo is
NaN.
We might still want to add a standard predicate for testing NaN-ness:
`nanp'. (`not-a-number-p' would be confusing.)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Q on NaN
2005-06-24 20:26 ` Drew Adams
` (2 preceding siblings ...)
2005-06-24 22:03 ` Eli Zaretskii
@ 2005-06-25 13:35 ` Richard M. Stallman
3 siblings, 0 replies; 12+ messages in thread
From: Richard M. Stallman @ 2005-06-25 13:35 UTC (permalink / raw)
Cc: emacs-devel
BTW, here is something I didn't expect:
`M-: 0.0e+NaN' returns -0.0e+NaN
`M-: -0.0e+NaN' returns 0.0e+NaN
The reader seems to flip the (irrelevant) sign.
I fixed that. Thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-06-25 13:35 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-24 19:06 Q on NaN Drew Adams
2005-06-24 19:33 ` Drew Adams
2005-06-24 19:46 ` Drew Adams
2005-06-24 21:01 ` Eli Zaretskii
2005-06-24 20:26 ` Drew Adams
2005-06-24 20:56 ` Gaëtan LEURENT
2005-06-24 20:59 ` Luc Teirlinck
2005-06-24 22:03 ` Eli Zaretskii
2005-06-24 21:49 ` Drew Adams
2005-06-24 22:31 ` Luc Teirlinck
2005-06-24 22:54 ` Drew Adams
2005-06-25 13:35 ` Richard M. Stallman
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
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).