D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 17160 - Apparently faulty behavior comparing enum members using `is`
Summary: Apparently faulty behavior comparing enum members using `is`
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 All
: P1 major
Assignee: No Owner
URL:
Keywords: performance, wrong-code
Depends on:
Blocks:
 
Reported: 2017-02-08 20:59 UTC by Sophie
Modified: 2020-11-08 06:38 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Sophie 2017-02-08 20:59:48 UTC
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 Sophie 2017-02-08 21:15:04 UTC
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 jiki 2017-02-08 22:15:05 UTC
This seems to work without the parameter attr 'in'.

test(Enum a)
Comment 3 basile-z 2019-12-12 02:49:18 UTC
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 Walter Bright 2020-11-08 06:38:46 UTC
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.