all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.