Bug 8745 – floating point comparison ("is" vs "==") inconsistency (on 32)

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2012-10-01T14:21:00Z
Last change time
2015-06-09T05:15:10Z
Assigned to
nobody
Creator
monarchdodra

Comments

Comment #0 by monarchdodra — 2012-10-01T14:21:50Z
From http://forum.dlang.org/group/digitalmars.D.learn //---- import std.stdio; import std.math; @property double getFloat() { return sqrt(1.1); } void main() { writeln(getFloat() == getFloat()); writeln(getFloat() is getFloat()); } //---- x32 Produces http://dpaste.dzfl.pl/e0e0bbae : false true x64 Produces http://dpaste.dzfl.pl/c1c7a415 : true true While one may argue that the comparison *may* return false, the difference in behavior between "==" and "is" not expected behavior (unless I'm missing something...? ). PS: the behavior difference is consistent http://dpaste.dzfl.pl/2ee9ae4e : //---- import std.stdio; import std.math; @property double getFloat() { return sqrt(1.1); } void main() { writeln(getFloat() == getFloat()); writeln(getFloat() is getFloat()); writeln(getFloat() is getFloat()); writeln(getFloat() == getFloat()); writeln(getFloat() is getFloat()); writeln(getFloat() == getFloat()); writeln(getFloat() == getFloat()); writeln(getFloat() is getFloat()); } //---- false true true false true false false true //---- On a side note, I find it strange that "==" return false in such a consistent manner. It might be over-sensitive to extended precision?
Comment #1 by clugdbug — 2012-10-02T01:03:51Z
The idea that for floating point, 'is' and '==' should be the same, is wrong. See bug 3632 for further discussion. I suspect this is a duplicate of the issues raised there.
Comment #2 by monarchdodra — 2012-10-02T01:19:17Z
(In reply to comment #1) > The idea that for floating point, 'is' and '==' should be the same, is wrong. > See bug 3632 for further discussion. I suspect this is a duplicate of the > issues raised there. I read the thread, it mostly relates to how comparison is done in regards to NaN and 0. Here, we are dealing with a "normal" float. It mentions doing an "isIdentical" call if you really want binary comparison: //---- void main() { writeln(isIdentical(getFloat(), getFloat())); writeln(getFloat() is getFloat()); writeln(getFloat() == getFloat()); } //---- true true false //---- :/ So, to get this straight, I got a and b. "a is b" and "a is is identical to b" but "a != b" ? (!) Is that really the intended behavior? If so, can you explain what I am seeing? I'm more confused than trying to request a change of behavior, really.
Comment #3 by r.sagitario — 2012-10-02T11:16:06Z
I haven't checked the disassembly, but I guess the problem of the failing comparison is caused by storing one value to memory as double (and doing some rounding on it along the way), while the other is still available on the FPU stack with real-precision. You might get different results when enabling optimizations. The "is" comparison is a bitwise comparison, so it will probably actually write both values to memory before the comparison, applying the same rounding to both results.
Comment #4 by maxim — 2012-10-16T09:04:44Z
*** This issue has been marked as a duplicate of issue 8476 ***