Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# NaN comparison differences between Equals() and ==

Tags:

c#

nan

equals

Check this out :

    var a = Double.NaN;

    Console.WriteLine(a == a);
    Console.ReadKey();

Prints "False"

    var a = Double.NaN;

    Console.WriteLine(a.Equals(a));
    Console.ReadKey();

Prints "True"!

Why it prints "True"? Due to floating point numbers specification, value that is NaN is not equal to itself! So it seems that Equals() method is implemented wrong... Am I missing something ?

like image 358
illegal-immigrant Avatar asked Feb 08 '11 13:02

illegal-immigrant


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Why do we write C?

We write C for Carbon Because in some element the symbol of the element is taken form its first words and Co for Cobalt beacause in some elements the symbol of the element is taken from its first second letters, so that the we don't get confuse.


1 Answers

I found an article addressing your question: .NET Security Blog: Why == and the Equals Method Return Different Results for Floating Point Values

According to IEC 60559:1989, two floating point numbers with values of NaN are never equal. However, according to the specification for the System.Object::Equals method, it's desirable to override this method to provide value equality semantics. [...]

So now we have two conflicting ideas of what Equals should mean. Object::Equals says that the BCL value types should override to provide value equality, and IEC 60559 says that NaN does not equal NaN. Partition I of the ECMA spec provides resolution for this conflict by making a note about this specific case in section 8.2.5.2 [below]


Update: The full text of section 8.2.5 from the CLI spec (ECMA-335) sheds some more light on this. I've copied the relevant bits here:

8.2.5 Identity and equality of values

There are two binary operators defined on all pairs of values: identity and equality. They return a Boolean result, and are mathematical equivalence operators; that is, they are:

  • Reflexive – a op a is true.
  • Symmetric – a op b is true if and only if b op a is true.
  • Transitive – if a op b is true and b op c is true, then a op c is true.

In addition, while identity always implies equality, the reverse is not true. [...]

8.2.5.1 Identity

The identity operator is defined by the CTS as follows.

  • If the values have different exact types, then they are not identical.
  • Otherwise, if their exact type is a value type, then they are identical if and only if the bit sequences of the values are the same, bit by bit.
  • Otherwise, if their exact type is a reference type, then they are identical if and only if the locations of the values are the same.

Identity is implemented on System.Object via the ReferenceEquals method.

8.2.5.2 Equality

For value types, the equality operator is part of the definition of the exact type. Definitions of equality should obey the following rules:

  • Equality should be an equivalence operator, as defined above.
  • Identity should imply equality, as stated earlier.
  • If either (or both) operand is a boxed value, [...]

Equality is implemented on System.Object via the Equals method.

[Note: Although two floating point NaNs are defined by IEC 60559:1989 to always compare as unequal, the contract for System.Object.Equals requires that overrides must satisfy the requirements for an equivalence operator. Therefore, System.Double.Equals and System.Single.Equals return True when comparing two NaNs, while the equality operator returns False in that case, as required by the IEC standard. end note]

The above does not specify the properties of the == operator at all (except for the final note); it is primarily defining the behavior of ReferenceEquals and Equals. For the behavior of the == operator, the C# language spec (ECMA-334) (section 14.9.2) is clear about how to treat NaN values:

If either operand [to operator ==] is NaN, the result is false

like image 60
Justin Avatar answered Sep 30 '22 02:09

Justin