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