Float equality testing, Whidbey suggestion (Not A Bug)

S

Stu Smith

A feature we'd like to see in VS 2004 is a compiler warning for equality
comparisons on floating values. Why? Because the behaviour allowed under the
ECMA spec is somewhat suprising. (Well it suprised us).

If you run the program below in debug mode (F5), it prints True. If you run
it in non-debug mode (Ctrl-F5), you get False.

We had a look at the ECMA spec (CLI - 12.1.3 line 35) and this behaviour
seems perfectly acceptable.

"Storage locations for floating point numbers (statics, array elements, and
fields of classes) are of fixed size. The supported storage sizes
are float32 and float64. Everywhere else (on the evaluation stack, as
arguments, as return types, and as local variables) floating point numbers
are represented using an internal floating-point type. In each such
instance, the nominal type of the variable or expression is either R4 or
R8, but its value may be represented internally with additional range
and/or precision. The size of the internal floating-point representation
is implementation-dependent, may vary, and shall have precision at least as
great as that of the variable or expression being represented."

A compiler warning for our admitted error would probably be a useful thing.


using System;

namespace FloatWeirdness
{

class Floaty
{
public Floaty( float a, float b )
{
_a = a;
_b = b;
}

public float Total
{
get
{
return _a + _b;
}
}
float _a, _b;
}

class Class1
{
static float storedValue;

[STAThread]
static void Main(string[] args)
{
Floaty floaty = new Floaty( 145.347519f, 6.878819f );
storedValue = floaty.Total;
Console.WriteLine( floaty.Total == storedValue );
Console.Read();
}
}
}

(NB According to 12.1.3 line 8 even storing the value in the static isn't
guaranteed to change the representation, but on our X86 VS.NET 2003, the
demo shows the problem).


Any thoughts?

Stu & Lee
 
C

Christoph Nahr

Forgot to add an even better tip...

NEVER EVER COMPARE FLOATING-POINT VALUES FOR EQUALITY!!!!

(Sorry for shouting but this is really important... and practically
everyone who is new to FP processing does it wrong.)

You must always compare FP values using some minimum threshold below
which they should be considered equal, and this threshold must be
greater than the smallest representable value for the least precise
variable or constant you're using, and also greater than whatever
error you anticipate your FP algorithm to introduce.

In your example, change this line:
Console.WriteLine( floaty.Total == storedValue );

to that line:
Console.WriteLine(Math.Abs(floaty.Total - storedValue) < 1e-5f);

and even better, use a symbolic constant for 1e-5. Now your program
should work correctly in both release & debug mode (it does for me).
Reducing this constant *just* to 1e-6 makes the program fail in
release mode, by the way -- that's how fiddly FP rounding is!

Obligatory links:
http://www.lahey.com/float.htm
http://docs.sun.com/source/806-3568/ncg_goldberg.html

This is all completely language-independent and also independent of
..NET, by the way. If you need decimal values without such problems
use the System.Decimal (C# decimal) data type... but it's slow and
doesn't have the range of values that float/double have.
 
C

Christoph Nahr

Well in that case I would prefer a warning, and that's what Stu is getting
at. Time would have been saved if a warning came up whilst the code was
being written. It's an easy mistake to make and as such the compiler could
help to flag this type of mistake.

Okay, a warning about equality comparisons of FP values might be
useful but I don't know of any other compiler that produces such a
warning (though lint programs do). What I'm saying is, this is not a
C# or .NET issue -- you're simply expected to know such things when
you use floating-point algorithms.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top