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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With