www.digitalmars.com         C & C++   DMDScript  

D - reasoning for operator!=

reply "Immanuel Scholz" <digital-mars kutzsche.net> writes:
Hi,

I am new to the list, maybe this was answered before.. (sorry, but google
seems not to index digitalmars-newsserver?)

Why this:

double a = double.nan;
double b = 1.0;

if (a == b)
    assert (a != b);    // assertion failed.. very strange thing, I think...


Maybe to throw some kind of arethmetic_exception in case of comparing
nan-doubles instead of this very strange double-!= behaviour?


Imi

PS: I am using Outlook as newsreader the first time, I hope I got the
settings correct and nothing is messed up... ?!
Mar 05 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
news:a62lfc$2top$1 digitaldaemon.com...

 Why this:

 double a = double.nan;
 double b = 1.0;

 if (a == b)
     assert (a != b);    // assertion failed.. very strange thing, I

 Maybe to throw some kind of arethmetic_exception in case of comparing
 nan-doubles instead of this very strange double-!= behaviour?

I thought that if one of the operands is NAN, both == and != would give false - which is the usual behaviour for floating-point comparisons, AFAIK.
Mar 05 2002
parent reply "Immanuel Scholz" <digital-mars kutzsche.net> writes:
"Pavel Minayev" <evilone omen.ru> schrieb im Newsbeitrag
news:a62rb8$30eg$1 digitaldaemon.com...
 "Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
 news:a62lfc$2top$1 digitaldaemon.com...

 Why this:

 double a = double.nan;
 double b = 1.0;

 if (a == b)
     assert (a != b);    // assertion failed.. very strange thing, I

 Maybe to throw some kind of arethmetic_exception in case of comparing
 nan-doubles instead of this very strange double-!= behaviour?

I thought that if one of the operands is NAN, both == and != would give false - which is the usual behaviour for floating-point comparisons, AFAIK.

Hm, maybe in C, but not in math! NAN is in math really "not a number" and you can't comparing it, because it is, err, not a number! So I think it should not try to compare, but throw an exception. I always thought these two parts are semantical equal: if (a == b) foo (); else bar (); if (a != b) bar (); else foo (); I know, in times when you can override operator!= in c++ this is not guaranteed anymore, but I think forbidding to override != is good, and make it the opposite of == essential. The same bad thing is: double a = double.nan; a += 2; So why to allow comparing and not adding (or why not forbid comparing?) Imi
Mar 05 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
news:a62tui$3m$1 digitaldaemon.com...

 Hm, maybe in C, but not in math! NAN is in math really "not a number"
 and you can't comparing it, because it is, err, not a number!

Agreed. However, computers sometimes think stupidly from our point of view. This is probably such a case =)
 So I think it should not try to compare, but throw an exception.

This would require an additional check to be inserted before each fp-comparison - a bit too much overhead, isn't it? Unfortunately, Intel FPUs don't have the built-in ability to throw D exceptions when some NAN error occurs =)
 I always thought these two parts are semantical equal:

 if (a == b)
   foo ();
 else
   bar ();


 if (a != b)
   bar ();
 else
   foo ();

Not for floating-point numbers.
 I know, in times when you can override operator!= in c++ this is not
 guaranteed anymore,
 but I think forbidding to override != is good, and make it the opposite of
 == essential.

Operators == and != aren't neccessary boolean (remember fuzzy logic!). So I don't think it's the best idea. It's better to leave this up to the programmer.
 The same bad thing is:

 double a = double.nan;
 a += 2;

 So why to allow comparing and not adding (or why not forbid comparing?)

Adding is allowed as well. It will just give you a NAN.
Mar 05 2002
parent reply "Immanuel Scholz" <digital-mars kutzsche.net> writes:
"Pavel Minayev" <evilone omen.ru> schrieb im Newsbeitrag
news:a62ujl$bj$1 digitaldaemon.com...
 "Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
 news:a62tui$3m$1 digitaldaemon.com...

 So I think it should not try to compare, but throw an exception.

This would require an additional check to be inserted before each fp-comparison - a bit too much overhead, isn't it?

But now, you have to check too. Plus the fact, that when you forget to check, very strange results are happen...
 Unfortunately, Intel FPUs don't have the built-in ability to
 throw D exceptions when some NAN error occurs =)

Ok, this one counts. :) (BTW: Shouldn't it be easier to implement that double.nan == double.nan is true? Why it is false here?)
 I know, in times when you can override operator!= in c++ this is not
 guaranteed anymore,
 but I think forbidding to override != is good, and make it the opposite


 == essential.

Operators == and != aren't neccessary boolean (remember fuzzy logic!). So I don't think it's the best idea. It's better to leave this up to the programmer.

Hm.. okok, maybe I start to write !(a == b) instead of a != b. But only if you promise not to define "!a" to "1-a" ;-)
 So why to allow comparing and not adding (or why not forbid comparing?)


Uh, so I can really calculate the magic odd of 1 to 2^(INF-1) ? Imi.
Mar 05 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
news:a62v60$sh$1 digitaldaemon.com...

 But now, you have to check too. Plus the fact, that when you forget to
 check,
 very strange results are happen...

You have to check only when you really care when it happens. After all, if the float is read from the file or keyboard, you can always check it once at the point where it is read - and act accordingly. Why do a check each time comparison happens?
 Ok, this one counts. :)
 (BTW: Shouldn't it be easier to implement that double.nan == double.nan is
 true? Why it is false here?)

 Hm.. okok, maybe I start to write !(a == b) instead of a != b.
 But only if you promise not to define "!a" to "1-a"   ;-)

Well... a == b could return "almost equal", so !(a == b) would be "a bit not equal" =)
 Uh, so I can really calculate the magic odd of  1 to 2^(INF-1)  ?

You could give it a try =)
Mar 05 2002
parent reply "Immanuel Scholz" <digital-mars kutzsche.net> writes:
"Pavel Minayev" <evilone omen.ru> schrieb im Newsbeitrag
news:a634dj$3ol$1 digitaldaemon.com...
 "Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
 news:a62v60$sh$1 digitaldaemon.com...

 But now, you have to check too. Plus the fact, that when you forget to
 check,
 very strange results are happen...

You have to check only when you really care when it happens. After all, if the float is read from the file or keyboard, you can always check it once at the point where it is read - and act accordingly. Why do a check each time comparison happens?

I think it is much the same like exceptions versus return values&errno. I think returning false, when comparing an invalid number is like returning null (an invalid pointer) within the new-operator. I assume, that NAN==1 -> false is never what you really want. You really do not want to compare NANs at all! double a = file.read_next_double(); // here, a could be NAN. so lets check it (only once) if (a.isnan) panic("badguy!"); if (a == 1) ... // of course, you have not to check to NAN again if (a == 5) ... // but you also do not have to check again, if if (a == b) ... // (double.nan == 1) throws an exception. the same applies to adding/subtracting to a NAN or as example dividing by 0 with integers. (Although I think the result "NAN" is ok for a division by 0 in the floating-point-world ;-) Just keep in mind that if you deceide to let NAN == NAN -> false, that is only a performance issue, and NOT a good decision. :-) Imi.
Mar 05 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
news:a63560$41e$1 digitaldaemon.com...

 I think it is much the same like exceptions versus return values&errno. I
 think returning false, when comparing an invalid number is like returning
 null
 (an invalid pointer) within the new-operator.

The problem is, comparison ops happen MUCH frequently than new ops. So the overhead is just too much.
 Just keep in mind that if you deceide to let NAN == NAN -> false, that is
 only
 a performance issue, and NOT a good decision. :-)

Sometimes perfomance issue IS a good decision. It depends on the POV. For example, a game programmer might consider exception-on-NAN to be the most stupid things he'd ever heard of - simply 'cause he'll get 20fps on a PIV, because 100000 vertices have their coordinates checked every frame =)
Mar 05 2002
prev sibling next sibling parent reply "Christophe Bouchon" <cbouchon hotmail.com> writes:
An extract from the D manual (look at the Note at the bottom):

Floating point comparisons
If one or both operands are floating point, then a floating point comparison
is performed.

Useful floating point operations must take into account NAN values. In
particular, a relational operator can have NAN operands. The result of a
relational operation on float values is less, greater, equal, or unordered
(unordered means either or both of the operands is a NAN). That means there
are 14 possible comparison conditions to test for:

	Token		Relation
	<		less
	>		greater
	<=		less or equal
	>=		greater or equal
	==		equal
	!=		unordered, less, or greater
	!<>=		unordered
	<>		less or greater
	<>=		less, equal, or greater
	!<=		unordered or greater
	!<		unordered, greater, or equal
	!>=		unordered or less
	!>		unordered, less, or equal
	!<>		unordered or equal

Note: for floating point comparison operators, (a !op b) is not the same as
!(a op b).

"Immanuel Scholz" <digital-mars kutzsche.net> wrote in news message:
a62lfc$2top$1 digitaldaemon.com...
 Hi,

 I am new to the list, maybe this was answered before.. (sorry, but google
 seems not to index digitalmars-newsserver?)

 Why this:

 double a = double.nan;
 double b = 1.0;

 if (a == b)
     assert (a != b);    // assertion failed.. very strange thing, I

 Maybe to throw some kind of arethmetic_exception in case of comparing
 nan-doubles instead of this very strange double-!= behaviour?


 Imi

 PS: I am using Outlook as newsreader the first time, I hope I got the
 settings correct and nothing is messed up... ?!

Mar 05 2002
parent "Roberto Mariottini" <rmariottini lycosmail.com> writes:
"Christophe Bouchon" <cbouchon hotmail.com> wrote in message
news:a63dil$7il$1 digitaldaemon.com...
[...]
 Token Relation
 < less
 greater

= greater or equal

!= unordered, less, or greater !<>= unordered <> less or greater <>= less, equal, or greater !<= unordered or greater !< unordered, greater, or equal !>= unordered or less !> unordered, less, or equal !<> unordered or equal Note: for floating point comparison operators, (a !op b) is not the same

 !(a op b).

I think I've never understood how I can use these operators. Can you show some examples? Ciao
Mar 06 2002
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message
news:a62lfc$2top$1 digitaldaemon.com...
 I am new to the list, maybe this was answered before.. (sorry, but google
 seems not to index digitalmars-newsserver?)

I've sent google email about that, but so far no reply.
 Why this:
 double a = double.nan;
 double b = 1.0;
 if (a == b)
     assert (a != b);    // assertion failed.. very strange thing, I

 Maybe to throw some kind of arethmetic_exception in case of comparing
 nan-doubles instead of this very strange double-!= behaviour?

It does it that way because that's the way IEEE 754 specifies the behavior of floating point ops. This has been adopted by C99. Changing it in D would subtly and very obscurely break code. Some things it's just too hard to swim upstream against <g>.
Mar 06 2002