digitalmars.D.learn - Float compare broke!
- "Era Scarecrow" <rtcvb32 yahoo.com> Jun 11 2012
- "Matej Nanut" <matejnanut gmail.com> Jun 11 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Jun 11 2012
- "Adam D. Ruppe" <destructionator gmail.com> Jun 11 2012
- David <d dav1d.de> Jun 11 2012
- David <d dav1d.de> Jun 11 2012
- "bearophile" <bearophileHUGS lycos.com> Jun 11 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Jun 11 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Jun 11 2012
- Dmitry Olshansky <dmitry.olsh gmail.com> Jun 11 2012
Most curiously while making unittests the asserts fail when I've confirmed it's working. The difference seems to be if it's immutable/const vs non, and why this makes a difference I don't see... Can someone give some light to this? const float i_f = 3.14159265; float a = i_f; float b = i_f; assert(a==b); //passes assert(a==i_f); //fails
Jun 11 2012
On Monday, 11 June 2012 at 10:33:22 UTC, Era Scarecrow wrote:Most curiously while making unittests the asserts fail when I've confirmed it's working. The difference seems to be if it's immutable/const vs non, and why this makes a difference I don't see... Can someone give some light to this? const float i_f = 3.14159265; float a = i_f; float b = i_f; assert(a==b); //passes assert(a==i_f); //fails
Works for me. (Arch Linux x64, DMD from repositories, says the version is 2.059.)
Jun 11 2012
On Monday, 11 June 2012 at 11:47:59 UTC, Matej Nanut wrote:On Monday, 11 June 2012 at 10:33:22 UTC, Era Scarecrow wrote:Most curiously while making unittests the asserts fail when I've confirmed it's working. The difference seems to be if it's immutable/const vs non, and why this makes a difference I don't see... Can someone give some light to this? const float i_f = 3.14159265; float a = i_f; float b = i_f; assert(a==b); //passes assert(a==i_f); //fails
Works for me. (Arch Linux x64, DMD from repositories, says the version is 2.059.)
Hmmm I'm using 2.059 but for win32. Perhaps a 32bit specific bug or something else? I doubt it has anything to do with me running Win7 64bit...
Jun 11 2012
It probably has to do with different rounding with the constant and the assignment. http://dlang.org/float.html Check out the section: Floating Point Constant Folding Different compiler settings, optimization settings, and inlining settings can affect opportunities for constant folding, therefore the results of floating point calculations may differ depending on those settings. a == b is probably done by the bits at runtime which match because it is the same assignment. But a == i_f might be propagated down there as 80 bit compared to 32 bit and thus be just slightly different. When comparing floating point you want to consider a little wiggle room to be ok due to little rounding error. This function should help: http://dlang.org/phobos/std_math.html#approxEqual
Jun 11 2012
Am 11.06.2012 16:47, schrieb bearophile:Adam D. Ruppe:This function should help: http://dlang.org/phobos/std_math.html#approxEqual
This is better: http://dlang.org/phobos/std_math.html#feqrel Bye, bearophile
Wasn't there a bug with feqrel? I think so, that's the reason why I implemented almost_equal in gl3n: https://github.com/Dav1dde/gl3n/blob/master/gl3n/math.d#L80
Jun 11 2012
Am 11.06.2012 18:42, schrieb David:Am 11.06.2012 16:47, schrieb bearophile:Adam D. Ruppe:This function should help: http://dlang.org/phobos/std_math.html#approxEqual
This is better: http://dlang.org/phobos/std_math.html#feqrel Bye, bearophile
Wasn't there a bug with feqrel? I think so, that's the reason why I implemented almost_equal in gl3n: https://github.com/Dav1dde/gl3n/blob/master/gl3n/math.d#L80
Found it: Fixed: http://d.puremagic.com/issues/show_bug.cgi?id=5089
Jun 11 2012
Adam D. Ruppe:This function should help: http://dlang.org/phobos/std_math.html#approxEqual
This is better: http://dlang.org/phobos/std_math.html#feqrel Bye, bearophile
Jun 11 2012
On Monday, 11 June 2012 at 12:54:37 UTC, Adam D. Ruppe wrote:a == b is probably done by the bits at runtime which match because it is the same assignment. But a == i_f might be propagated down there as 80 bit compared to 32 bit and thus be just slightly different.
Unfortunately I used FloatRep and printed out the exponent and fractions, and they were identical (false, 128, 4788187). Besides, shouldn't the same types do a direct bit-wise copy?
Jun 11 2012
On Monday, 11 June 2012 at 20:28:06 UTC, Era Scarecrow wrote:On Monday, 11 June 2012 at 12:54:37 UTC, Adam D. Ruppe wrote:a == b is probably done by the bits at runtime which match because it is the same assignment. But a == i_f might be propagated down there as 80 bit compared to 32 bit and thus be just slightly different.
Unfortunately I used FloatRep and printed out the exponent and fractions, and they were identical (false, 128, 4788187). Besides, shouldn't the same types do a direct bit-wise copy?
Although re-reading your post it may make a little more sense... So I added a couple more tests.. Strangely the exact same issue is there while the rest aren't. The question then, is why the 32bit may be upgraded to an 80bit (if that indeed is happening)? But that doesn't make sense since the 80bit can hold identically anything the 32bit can hold and should still compare the same. -- const float i_f = 3.14159265; float a = i_f; float b = i_f; union fi { float f; ubyte[4] b; } fi c; c.b = [219, 15, 73, 64]; //bit for bit of the same value. float d = a; //float to float copy assert(a==b); //passes (float/float copied from const) assert(a==c.f); //passes (float/float union) assert(b==d); //passes (float/float) assert(a==i_f); //fails (float/const float)
Jun 11 2012
On 11.06.2012 14:33, Era Scarecrow wrote:Most curiously while making unittests the asserts fail when I've confirmed it's working. The difference seems to be if it's immutable/const vs non, and why this makes a difference I don't see... Can someone give some light to this? const float i_f = 3.14159265;
a help of constfold-engine that prefers to keep precision intact (regardless of whether the type can actually hold it).float a = i_f; float b = i_f; assert(a==b); //passes assert(a==i_f); //fails
-- Dmitry Olshansky
Jun 11 2012









"Matej Nanut" <matejnanut gmail.com> 