Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

_double.Equals(_float);

Sample code:

double d = 0;
float  f = 0;

// Dump() prints result in LinqPad application

(f == d).Dump(); // 1) true
(d == f).Dump(); // 2) true

(f.Equals(d)).Dump(); // 3) false
(d.Equals(f)).Dump(); // 4) true

1) returns true as expected
2) same as above
3) false - because we using Equals(object), and it checks internally:

  public override bool Equals(Object obj) {
        if (!(obj is Single)) {
            return false;
        }
        ...

4) true? why?

public override bool Equals(Object obj) {
        if (!(obj is Double)) {
            return false;
        }

How float can pass this if guard?

like image 581
apocalypse Avatar asked Feb 06 '23 20:02

apocalypse


2 Answers

It doesn't.

The overload you're using in case 4 is double.Equals(double obj). This is because there is an implicit conversion from float to double.

In case 3, there is no implicit conversion from double to float, as it may result in a loss of precision. In this case, double will be boxed and you're using object.Equals.

You can show the actual result of object.Equals by casting to object:

d.Equals((object)f)).Dump(); // this will be false

See this fiddle.

like image 191
Charles Mager Avatar answered Feb 15 '23 13:02

Charles Mager


The function called is public bool Equals(Double obj) (instead of public override bool Equals(Object obj)) which is:

public bool Equals(Double obj)
{
    if (obj == m_value) {
        return true;
    }
    return IsNaN(obj) && IsNaN(m_value);
}

Thanks to the implicit cast of float to Double

like image 43
Thomas Ayoub Avatar answered Feb 15 '23 13:02

Thomas Ayoub