Bug 5565 – [64-bit] Wrong Floating Point Results, Related to Mixing With size_t
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2011-02-11T22:06:00Z
Last change time
2011-02-12T21:57:02Z
Keywords
wrong-code
Assigned to
nobody
Creator
dsimcha
Comments
Comment #0 by dsimcha — 2011-02-11T22:06:07Z
The following code produces erratic results. I don't know where exactly the culprit is, but I'm hoping I've reduced it enough that someone with a decent mental model of how the compiler works will be able to finish the job.
import std.stdio;
double foo(int[] data, double q = 0.25) {
immutable double N = data.length;
// This actually affects the result, making it more severe and obvious
// in addition to showing that the value is correct.
stderr.writeln(N); // Prints 8. Correct.
// lowEnd should be floor(7 * 0.25) == 1.
immutable lowEnd = cast(size_t) ((N - 1) * q);
// highEnd should be floor(7 * 0.75) - 1 = 4.
immutable highEnd = cast(size_t) ((N - 1) * (1.0 - q) - lowEnd);
// highFract should be 7 * 0.75 - 4 - 1 = 0.25
immutable highFract = (N - 1) * (1.0 - q) - lowEnd - highEnd;
stderr.writeln(lowEnd, '\t', highEnd, '\t', highFract);
return highFract;
}
void main() {
writeln(foo([1,2,3,4,5,6,7,8]));
}
Prints:
8
0 4545916 -4.54591e+06
-4.54591e+06
Comment #1 by dsimcha — 2011-02-11T22:08:48Z
Forgot to mention: This test case doesn't reproduce the bug if -O is enabled, though the test case I reduced it from did, I think. (I'm not 100% sure that I wasn't just seeing two different bugs simultaneously.)
I think this was actually two bugs that I thought had a single root cause. You only got one of them. Now, the result from running this code with -m64 and without -O on linux is:
8
1 4545912 -4.54591e+06
-4.54591e+06
On the line with the three columns, the first one is now correct. The other two are still wrong, unless -O is enabled.