10 posts

Possible bug in C# math?

Back to Forum: Tech Off
• The following expression should return true.

(1133 * 6.0 / 1133) == (1133 * (6.0 / 1133))

Although the math is sound in, C# disagrees.

1133 * 6.0 / 1133 returns 6.0

whereas

1133 * (6.0 / 1133) returns 6.0000000000000009

Is this a bug, or am I supposed to expect some rounding error when I divide first?

• That's just how floating-point math works.  Using == or != is rarely correct for floats or doubles.

• It's not just that the expressions aren't equal,
using 1133*(6.0/1133), which returns 6.0000000000000009, (which is mathematically incorrect) in further expressions will result in further errors.

• It's because 6.0 / 1133 is being rounded up at the last digit stored in the float.  Then when you multiply by 1133 the rounding shows itself as the extra .00..09.

The same thing happens in base 10.  Consider 6 * (2 / 3) on a calculator with a finite number of digits:

2 / 3 = 0.66...67
6 * 0.66...67 = 4.00...02

• hmmm, yes I see how that works, I guess it can't be helped then.

• BrianPeiris wrote:
hmmm, yes I see how that works, I guess it can't be helped then.

It can't, but it involves you implementing an "Infinite Prescision" engine. The Windows calculator had this flaw until recently, so you're not alone.

There's an example written in C here.

• Thanks for the links W3bbo and AndyC.
Infinite Precision isn't really necessary for my current application and I've found a work-around for the FP problem, but definitely good resources to add to my bookmarks.

• You could use macros:

#define CLOSE_ENOUGH 0.00001
#define FLOAT_EQUAL(f, g) (abs((f) - (g)) <= CLOSE_ENOUGH)
#define FLOAT_NOT_EQUAL(f, g) (!FLOAT_EQUAL(f, g))

• I sometimes wonder why the comparison operators for floating point values isn't just defined to take this into account. Surely that would eliminate a whole raft of unnecessary bugs in a much cleaner, more OO way.

You could still have a float.CloseEnough static property to adjust the accuracy if needed.