(a != b) equivelant to !(a == b)?

  • Thread starter Thread starter Daniel Billingsley
  • Start date Start date
D

Daniel Billingsley

My understanding is that classes must implement/override these operators as
a pair, so I would expect it's safe to expect these two to return the same
results. Is there any difference, performance or otherwise?

if (! (a == b))
{
blah blah blah
}

if (a !=b)
{
blah blah blah
}

I'm reviewing some code and the author uses the former exclusively, but the
2nd seems slightly more straightforward to me. I just want to be sure it
really is just personal opinion.
 
*Daniel Billingsley* tippselte am *21.10.2003 22:19* MESZ:

[...]

They are equivalent and I vote for the second to be easier to read.

Best regards,

Michael
 
Daniel Billingsley said:
My understanding is that classes must implement/override these operators as
a pair, so I would expect it's safe to expect these two to return the same
results. Is there any difference, performance or otherwise?

if (! (a == b))
{
blah blah blah
}

if (a !=b)
{
blah blah blah
}

I'm reviewing some code and the author uses the former exclusively, but the
2nd seems slightly more straightforward to me. I just want to be sure it
really is just personal opinion.

Yes - if any classes don't obey the above, then they're *asking* to
fail horribly.
 
Yep - exactly the same.

Always interesting to see what gets emitted to IL.

In both cases, the Opcode beq.s is being used to jump to the target label if the values are equal (skipping the codeblock that matches the condition), so if they're not, it would continue with that code block that matches (a!=b).

Hope that makes sense somehow.

Cheers,
Wim Hollebrandse
http://www.wimdows.net
http://www.wimdows.com
 
The first one is converted to the second one by the compiler (at least on my
machine.) The IL is the same.
 
Jon Skeet said:
Yes - if any classes don't obey the above, then they're *asking* to
fail horribly.

What if a and b are floating point and one of them is NAN? The IEEE rules say
that NAN is unordered with respect to any other value (even the same NAN). Then
(a != b) should be false and !(a == b) should be true.

I would assume C# follows this rule, but I don't really know.

Bruce Seiler
 
Bruce Seiler said:
What if a and b are floating point and one of them is NAN? The IEEE rules say
that NAN is unordered with respect to any other value (even the same NAN). Then
(a != b) should be false and !(a == b) should be true.

I would assume C# follows this rule, but I don't really know.

No, a!=b should be true as well - at least by the C# spec. From section
14.9.2 of ECMA-334, which is talking about floating-point comparisons:

<quote>
If either operand is NaN, the result is false for all operators except
!=, for which the result is true.
</quote>

It claims that it follows IEEE 754 in this respect - but without access
to IEEE 754 itself, I can't check this.
 
A gentleman by the name of De Moivre wrote a theorem years ago that said the
two are equivalent. However, he pre-dated the three-level logic introduced
with null values

Object x = new Object();
if (null == null)
// do we ever get here?
if (!(null == x))

You would need to read the spec very carefully to work out these
complications.

Regards

Ron
 
Ron McNulty said:
A gentleman by the name of De Moivre wrote a theorem years ago that said the
two are equivalent. However, he pre-dated the three-level logic introduced
with null values

Object x = new Object();
if (null == null)
// do we ever get here?
if (!(null == x))

You would need to read the spec very carefully to work out these
complications.

When x is defined as type object, it's very easy: it's just a simple
reference comparison, when null is just another value.

Other classes with user-defined comparison operators are a different
matter, however, and you can do very nasty things. For instance:

using System;

public class Test
{
public static bool operator== (Test x, Test y)
{
return true;
}

public static bool operator!= (Test x, Test y)
{
return true;
}

static void Main()
{
Test a = new Test();
Test b = new Test();

Console.WriteLine (a!=b);
Console.WriteLine (!(a==b));
}
}

(Ignore the warnings to do with GetHashCode and Object.Equals for the
moment.)

Types which don't follow "normal" logic should at the very least *very
clearly* state that they don't follow normal logic.

Even types which aren't reflexive (i.e. where x==x isn't always true,
such as Double and DBNull) should almost always follow
!(a==b) == (a!=b) - I can't think of a single example where this
isn't true, fortunately.
 
Jon Skeet said:
No, a!=b should be true as well - at least by the C# spec. From section
14.9.2 of ECMA-334, which is talking about floating-point comparisons:

<quote>
If either operand is NaN, the result is false for all operators except
!=, for which the result is true.
</quote>

It claims that it follows IEEE 754 in this respect - but without access
to IEEE 754 itself, I can't check this.

I looked into this an found out you (and C#) are right and I'm wrong. Sigh.
!= is the one comparison that returns true with NAN as an operand.
I didn't look at the official IEEE spec as that costs money, but Kahan's article
"Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point
Arithmetic"
is on the web.

Bruce Seiler
 
this is logic

(pq)' = p'+q'

let's trace
accept a=5, b=4

if (! (a == b))
=> if(!(false))
=>if(true) this means that when they are not equal

if(a!=b) this also when they are not equal,
the sembol you use " ! " takes reverse of pharantesis
 
Back
Top