4

Can anyone show me an example of two C# variables containing float values that "seem" to be equal but in fact are not. When I say "seem equal", what I mean is that they intuitively seem to be equal.

The reason why I'm looking for such an example is because I have code that compares two float variables for equality and Visual Studio is warning me that Comparison of floating point numbers can be unequal due to the differing precision of the two values.. I understand that float variables are not precise (here's a StackOverflow question where this is discussed and explained very clearly) but I am failing to find an actual example where two values that seem to be equal are actually considered different by C#.

For instance, the first answer to the SO question I referenced earlier mentions that 9.2 and 92/10 are internally represented differently so I wrote the following code to verify if C# would treat them as equal or not and the result is that they are considered equal.

var f1 = 92f / 10f;
var f2 = 9.2f;
if (f1 == f2)
{
    Console.Write("Equal, as expected");
}
else
{
    Console.Write("Surprisingly not equal");
}

So, I'm looking for an example of f1 and f2 that "seem" to be equal but would cause C# to treat them as different.

desautelsj
  • 3,587
  • 4
  • 37
  • 55
  • Try summing a float that is irrational when expressed as binary. A base 10 example would be 3,000 additions of 1.0 / 3.0 compared to 1,000. – Dave S May 27 '17 at 21:28
  • 1
    `if (Math.Sqrt(2.0) * Math.Sqrt(2.0) != 2.0) Console.Write("Surprisingly not equal");` but it's `double`, not `float` (`Single`) example – Dmitry Bychenko May 27 '17 at 22:00
  • @DmitryBychenko excellent example. Thank you. In fact, if you submit as an answer I'll make sure to vote it up. – desautelsj May 28 '17 at 15:03

2 Answers2

3

Try the code below. value1 and value2 both represent toSum * 10, but they are not equal. At least on my working machine. Float type has especially low precision on large values.

const float toSum = 1000000000.1f;
const int count = 10;
float value1 = 0;

for (int i = 0; i < count; i++)
{
    value1 += toSum;
}

float value2 = toSum * count;

var equal = value1 == value2;
sasha_gud
  • 1,635
  • 13
  • 18
  • This is interesting, adding the same value 10 times yields a value different than multiplying the value by 10. This is indeed counterintuitive! – desautelsj May 27 '17 at 21:49
3

If you don't insist on float (Single) type, but actually want any floating point types (Single, Double) example you can try:

   if (Math.Sqrt(2.0) * Math.Sqrt(2.0) == 2.0) 
     Console.Write("Equal, as expected");
   else 
     Console.Write("Surprisingly not equal");
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215