digitalmars.D.learn - Float compare broke!
- Era Scarecrow (9/9) Jun 11 2012 Most curiously while making unittests the asserts fail when I've
- Matej Nanut (4/13) Jun 11 2012 Works for me.
- Era Scarecrow (4/18) Jun 11 2012 Hmmm I'm using 2.059 but for win32. Perhaps a 32bit specific bug
- Adam D. Ruppe (17/17) Jun 11 2012 It probably has to do with different rounding
- bearophile (5/7) Jun 11 2012 This is better:
- Era Scarecrow (4/8) Jun 11 2012 Unfortunately I used FloatRep and printed out the exponent and
- Era Scarecrow (22/31) Jun 11 2012 Although re-reading your post it may make a little more sense...
- Dmitry Olshansky (6/15) Jun 11 2012 Doesn't fit into float AFAIK. The rest "flows" naturally from here with
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); //failsWorks 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: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...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); //failsWorks for me. (Arch Linux x64, DMD from repositories, says the version is 2.059.)
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
Adam D. Ruppe:This function should help: http://dlang.org/phobos/std_math.html#approxEqualThis is better: http://dlang.org/phobos/std_math.html#feqrel Bye, bearophile
Jun 11 2012
Am 11.06.2012 16:47, schrieb bearophile:Adam D. Ruppe: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#L80This function should help: http://dlang.org/phobos/std_math.html#approxEqualThis is better: http://dlang.org/phobos/std_math.html#feqrel Bye, bearophile
Jun 11 2012
Am 11.06.2012 18:42, schrieb David:Am 11.06.2012 16:47, schrieb bearophile:Found it: Fixed: http://d.puremagic.com/issues/show_bug.cgi?id=5089Adam D. Ruppe: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#L80This function should help: http://dlang.org/phobos/std_math.html#approxEqualThis 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: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)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 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;Doesn't fit into float AFAIK. The rest "flows" naturally from here with 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