Re: Meaning of Double.Epsilon
Damn. Errata:
NaN cannot be used to test for is-not-a-number anyway. You *have to* use
IsNaN instead.
The same is true for NegativeInfinit y and PositiveInfinit y.
--
cody
Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
"cody" <no_spam_deutro nium@gmx.net> schrieb im Newsbeitrag
news:#LxFkoXlEH A.3476@tk2msftn gp13.phx.gbl...[color=blue]
> I tend to say that operators == result is undefined for floating point[/color]
types[color=blue]
> (except decimal).
> You never know how variables are stored in memory. testing for equality[/color]
for[color=blue]
> a floating point variables never makes sense, even if you do:
>
> float a = 1f;
> float b = 1f;
> if (a==b) { }
>
> The Jitter may choose to place a and b in difference register types (32,[/color]
64[color=blue]
> or 80 bits), so a==b may return true or false depending on the machine[/color]
type,[color=blue]
> framework version, debug or release settings or if a debugger is attached[/color]
or[color=blue]
> in which way the variables are used in code or wheather the method is
> inlined or not.
>
> So it would be great if the compiler would at least issue a warning if it
> spots code which tests for equality with floating point values.
>
> The only thing I could imagine is testing for NaN but in that case one
> should use IsNaN() methods of struct Double and Single.
>
> --
> cody
>
> Freeware Tools, Games and Humour
> http://www.deutronium.de.vu || http://www.deutronium.tk
> "Jon Skeet [C# MVP]" <skeet@pobox.co m> schrieb im Newsbeitrag
> news:MPG.1ba815 e2cc7c8ef698b35 e@msnews.micros oft.com...[color=green]
> > Niki Estner <niki.estner@cu be.net> wrote:[color=darkred]
> > > > It's the last step that I'm not sure about though - is it possible[/color][/color][/color]
for[color=blue][color=green][color=darkred]
> > > > a and b to be different, but their difference to be so close to 0 as[/color][/color]
> to[color=green][color=darkred]
> > > > be unrepresentably small? It feels unlikely, but I know that[/color][/color][/color]
intuition[color=blue][color=green][color=darkred]
> > > > is often horribly flawed when it comes to floating point maths.
> > >
> > > I guess it's possible if a and b are stored in 80-bit FPU registers:[/color][/color][/color]
b-a[color=blue]
> (80[color=green][color=darkred]
> > > bit) could still be different form 0 (using an 80-bit comparison), but[/color][/color]
> the[color=green][color=darkred]
> > > difference would be smaller than double.Epsilon. Also Math.Abs(b-a)[/color][/color]
> would[color=green][color=darkred]
> > > actually return 0 (if not inlined) as b-a would get casted to a[/color][/color][/color]
(64-bit)[color=blue][color=green][color=darkred]
> > > double value.[/color]
> >
> > Aargh, yes. I knew there was a good reason to be hesitant :)
> >[color=darkred]
> > > Sample code (compares (double.Epsilon/2) with 0):[/color]
> >
> > <snip>
> >
> > Good, thanks. Here's something interesting, based on your code:
> >
> > using System;
> > public class MyClass
> > {
> > public static void Main()
> > {
> > double two = double.Parse("2 ");
> > double a = double.Epsilon/two;
> > double b = 0;
> > Console.WriteLi ne(a==b);
> > Console.WriteLi ne(Math.Abs(b-a) < double.Epsilon) ;
> > }
> > }
> >
> > That prints out (on my box):
> > True
> > True
> >
> > If you comment out the last line, however, it just prints out
> > False
> >
> > Presumably the call to Math.Abs forces a and b to be "normal" 64-bit
> > values rather than just 80-bit registers, or something like that.
> >
> > --
> > Jon Skeet - <skeet@pobox.co m>
> > http://www.pobox.com/~skeet
> > If replying to the group, please do not mail me too[/color]
>
>[/color]
Damn. Errata:
NaN cannot be used to test for is-not-a-number anyway. You *have to* use
IsNaN instead.
The same is true for NegativeInfinit y and PositiveInfinit y.
--
cody
Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
"cody" <no_spam_deutro nium@gmx.net> schrieb im Newsbeitrag
news:#LxFkoXlEH A.3476@tk2msftn gp13.phx.gbl...[color=blue]
> I tend to say that operators == result is undefined for floating point[/color]
types[color=blue]
> (except decimal).
> You never know how variables are stored in memory. testing for equality[/color]
for[color=blue]
> a floating point variables never makes sense, even if you do:
>
> float a = 1f;
> float b = 1f;
> if (a==b) { }
>
> The Jitter may choose to place a and b in difference register types (32,[/color]
64[color=blue]
> or 80 bits), so a==b may return true or false depending on the machine[/color]
type,[color=blue]
> framework version, debug or release settings or if a debugger is attached[/color]
or[color=blue]
> in which way the variables are used in code or wheather the method is
> inlined or not.
>
> So it would be great if the compiler would at least issue a warning if it
> spots code which tests for equality with floating point values.
>
> The only thing I could imagine is testing for NaN but in that case one
> should use IsNaN() methods of struct Double and Single.
>
> --
> cody
>
> Freeware Tools, Games and Humour
> http://www.deutronium.de.vu || http://www.deutronium.tk
> "Jon Skeet [C# MVP]" <skeet@pobox.co m> schrieb im Newsbeitrag
> news:MPG.1ba815 e2cc7c8ef698b35 e@msnews.micros oft.com...[color=green]
> > Niki Estner <niki.estner@cu be.net> wrote:[color=darkred]
> > > > It's the last step that I'm not sure about though - is it possible[/color][/color][/color]
for[color=blue][color=green][color=darkred]
> > > > a and b to be different, but their difference to be so close to 0 as[/color][/color]
> to[color=green][color=darkred]
> > > > be unrepresentably small? It feels unlikely, but I know that[/color][/color][/color]
intuition[color=blue][color=green][color=darkred]
> > > > is often horribly flawed when it comes to floating point maths.
> > >
> > > I guess it's possible if a and b are stored in 80-bit FPU registers:[/color][/color][/color]
b-a[color=blue]
> (80[color=green][color=darkred]
> > > bit) could still be different form 0 (using an 80-bit comparison), but[/color][/color]
> the[color=green][color=darkred]
> > > difference would be smaller than double.Epsilon. Also Math.Abs(b-a)[/color][/color]
> would[color=green][color=darkred]
> > > actually return 0 (if not inlined) as b-a would get casted to a[/color][/color][/color]
(64-bit)[color=blue][color=green][color=darkred]
> > > double value.[/color]
> >
> > Aargh, yes. I knew there was a good reason to be hesitant :)
> >[color=darkred]
> > > Sample code (compares (double.Epsilon/2) with 0):[/color]
> >
> > <snip>
> >
> > Good, thanks. Here's something interesting, based on your code:
> >
> > using System;
> > public class MyClass
> > {
> > public static void Main()
> > {
> > double two = double.Parse("2 ");
> > double a = double.Epsilon/two;
> > double b = 0;
> > Console.WriteLi ne(a==b);
> > Console.WriteLi ne(Math.Abs(b-a) < double.Epsilon) ;
> > }
> > }
> >
> > That prints out (on my box):
> > True
> > True
> >
> > If you comment out the last line, however, it just prints out
> > False
> >
> > Presumably the call to Math.Abs forces a and b to be "normal" 64-bit
> > values rather than just 80-bit registers, or something like that.
> >
> > --
> > Jon Skeet - <skeet@pobox.co m>
> > http://www.pobox.com/~skeet
> > If replying to the group, please do not mail me too[/color]
>
>[/color]
Comment