David Wender
David Wender

Reputation: 19

Equals versus == when comparing a double to zero

I'm trying to compare a double value to see if it is equal to zero. The following will work:

Assert.IsTrue(0d==0);

However this will fail:

Assert.IsTrue(Equals(0d,0));

I think the second argument (0) is being treated as an integer. However, I don't understand why Equals(0d, 0) evaluates as false whereas 0d==0 is true. It can't be rounding because both values are directly input as zeros.

Upvotes: 1

Views: 5146

Answers (3)

acrespo
acrespo

Reputation: 1144

In the first line the == operator casts the values to a common type, while in the second the Double.Equals method is called as a result, and it before comparing does a type-check which returns false, as one value is a double and the other is an integer.

Upvotes: 0

Blindy
Blindy

Reputation: 67544

Intuitively it's as easy as "they're not both doubles".

If you want to go in depth however, Object.Equals (the static method you call in your second example) is this:

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static bool Equals(object objA, object objB)
{
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
}

The 2 references are not equal, neither is null, so Double.Equals gets called virtually:

public override bool Equals(object obj)
{
    if (!(obj is double))
    {
        return false;
    }
    double d = (double) obj;
    return ((d == this) || (IsNaN(d) && IsNaN(this)));
}

The argument is not a double so it returns false.

This is taken from mscorlib for .NET 4.0 64-bit.

Upvotes: 4

Caimen
Caimen

Reputation: 2619

I believe Equals(0d,0) may be doing a type comparison also. 0d is not technically equal to 0 because they are not same type.

Edit:

http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx

This is the case it seems.

MSDN: true if the specified Object is equal to the current Object; otherwise, false.

Alternatively you could to something like Convert.ToDouble(0) and it should work. I'm not near a C# compiler right now so I can't check if that's correct.

Upvotes: 2

Related Questions