math equation evaluates to true in code and false in immediate window

  • Thread starter Thread starter TS
  • Start date Start date
T

TS

I have this simple equation that returns a boolean:
if( ti.NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))

ti.NumberIncorrect is int : 4
TotalQuestions is int : 20
FailurePercentage is float : 80

When the code runs, it evaluates to true incorrectly. When I put this exact
expression in the watch or immediate window, it evaluates correctly to
false. I tried to cast TotalQuestions and ti.NumberIncorrect to float, but
this didn't help

What is going on here?
 
Hi,

I can't explain the difference but when you say the 'correct' answer is
false you are wrong. This is a floating point expression and as such is
subject to inexact binary equivalence so you should in general expect an
expression like (TotalQuestions - (TotalQuestions * FailurePercentage) to
evaluate to something slightly different from exactly 4. In other words in
this case the 'correct' answer could be either true or false depending on
the float conversions involved. You *must* allow for this when doing
floating point comparison where equality matters.

Cheers

Doug Forster
 
TS said:
I have this simple equation that returns a boolean:
if( ti.NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))

ti.NumberIncorrect is int : 4
TotalQuestions is int : 20
FailurePercentage is float : 80

When the code runs, it evaluates to true incorrectly. When I put this exact
expression in the watch or immediate window, it evaluates correctly to
false. I tried to cast TotalQuestions and ti.NumberIncorrect to float, but
this didn't help

What is going on here?

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

I can't see why it would be true though, as 4 is not greater than
20-(20*80).

If you meant to say that FailurePercentage is 0.80, you should read
http://www.pobox.com/~skeet/csharp/floatingpoint.html
 
using System;

namespace Math
{
public class Form1 : System.Windows.Forms.Form
{
[STAThread]
static void Main()
{
float FailurePercentage = .8f;
int TotalQuestions = 30;
int NumberIncorrect = 6;

if( NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))
{
MessageBox.Show("Incorrectly Evaluted true");
}

FailurePercentage = .7f;
NumberIncorrect = 9;

if( NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))
{
MessageBox.Show("Incorrectly Evaluted true");
}
else
MessageBox.Show("Correctly Evaluted");
}
}
}
 
TS said:
using System;

namespace Math
{
public class Form1 : System.Windows.Forms.Form
{
[STAThread]
static void Main()
{
float FailurePercentage = .8f;
int TotalQuestions = 30;
int NumberIncorrect = 6;

if( NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))
{
MessageBox.Show("Incorrectly Evaluted true");
}

FailurePercentage = .7f;
NumberIncorrect = 9;

if( NumberIncorrect > (TotalQuestions - (TotalQuestions *
FailurePercentage) ))
{
MessageBox.Show("Incorrectly Evaluted true");
}
else
MessageBox.Show("Correctly Evaluted");
}
}
}

Thank you. (Admittedly it doesn't actually compile, and uses message
boxes instead of Console.WriteLine for no good reason, but never
mind...)

Now, did you read the article I linked to about floating point? Using
the DoubleConverter class referenced in that, when you specify .8f you
actually get 0.800000011920928955078125. Put that into the equation and
you'll see why it's failing.

I suggest you have a failure level rather than a failure proportion -
or use an integer failure proportion (eg the actual percentage) and
deal entirely with integer arithmetic.
 
Back
Top