Bug 17160 – Apparently faulty behavior comparing enum members using `is`
Status
RESOLVED
Resolution
WONTFIX
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2017-02-08T20:59:48Z
Last change time
2020-11-08T06:38:46Z
Keywords
performance, wrong-code
Assigned to
No Owner
Creator
Sophie
Comments
Comment #0 by meapineapple — 2017-02-08T20:59:48Z
With DMD v2.072.2 on Windows 7 this code produces an assertion error:
unittest{
enum Enum: double{A = 0.1}
bool test(in Enum a){return a is Enum.A;}
assert(test(Enum.A));
}
When `A = 1` or other values that can be represented more exactly as a floating point, the code does not produce an error.
Given that this code does not produce such an error, I'm especially inclined to think this is not intended behavior:
unittest{
enum Enum: double{A = 0.1}
assert(Enum.A is Enum.A);
}
Comment #1 by meapineapple — 2017-02-08T21:15:04Z
This issue seems not to occur when using `enum Enum: real` instead of double.
From IRC:
<skl> hmm it does a byte comparison but they differ, one is 00D0CC... the other is CDCCCCCC...
<adam_d_ruppe> i am guessing that the enum treats it more like a literal than the variable does so it gets imprecise passed to functions
<skl> it stores the literial enum value as a real 80-bit floating point number
<skl> but it looks like it passes a double into the function
Comment #2 by jiki — 2017-02-08T22:15:05Z
This seems to work without the parameter attr 'in'.
test(Enum a)
Comment #3 by b2.temp — 2019-12-12T02:49:18Z
compiler explorer shows clearly that for (in Enum) a real (80 bits) comparison occurs while for (Enum) a more correct (and faster) 64 bits.
https://godbolt.org/z/W5PYMn
Comment #4 by bugzilla — 2020-11-08T06:38:46Z
0.1 cannot be represented exactly with floating point types. In particular, taking an 80 bit value and comparing it with a rounded 64 bit value will not come out as identical.
Rounding and inexact floating point operations are just something we have to deal with.