I needed a custom float comparison for my project and I ended up using a method provided here: https://stackoverflow.com/a/3877206/393406
Though, knowing that float.GetHashCode()
returns the bits as would the unsafe de-referencing variation of code, I skipped both the bit-conversion and de-referencing and am utilizing the GetHashCode()
instead.
After finding out about the problem which I am experiencing, I tested if BitConverter would provide different values, but that's not the case.
The problem appears in two different places and coincidentally due to comparing the same values, respectively: 1f
and -4f
. The values made me curious and I went on to debug the case when the call to Math.Abs(a - b)
hits the OverflowException
(a - b
being equal to Int32.MinValue
).
I was quite surprised, when I found out, that the absolute hash codes (bit values) for 1f
and -4f
are the same, which ultimately, messes up the math.
I went on to debug a little more (also taking in mind some of the flaws provided here), providing different values (float
->
GetHashCode()
) and witnessing interesting results:
0f -> 0
-0f -> -2147483648
float.MinValue -> -8388609
float.MaxValue -> 2139095039
1f -> 1065353216
-1f -> -1082130432
2f -> 1073741824
-2f -> -1073741824
4f -> 1082130432
-4f -> -1065353216
The interesting parts being... given that 2f
and -2f
have the same, absolute, bit values:
- why there are differences for
1f
and4f
pairs? - why the
1f
and4f
pairs are somewhat inversely related?
I bet that my reasoning is totally illogical, but I'm just curious.
Well, and yes, the relation between 1f
and -4f
is killing my comparison, because:
int aBits = a.GetHashCode(); // -4 => -1065353216
if (aBits < 0)
aBits = Int32.MinValue - aBits; // -1082130432
int bBits = b.GetHashCode(); // 1 => 1065353216
if (bBits < 0)
bBits = Int32.MinValue - bBits; // no changes, 1065353216
int bitDifference = aBits - bBits; // -1082130432 - 1065353216 = -2147483648 = Int32.MinValue
int absoluteBitDifference = Math.Abs(bitDifference); // an obvious OverflowException
- How to prevent this problem?