Question/request/bug(?) re. floating-point in dmd
qznc
qznc at web.de
Thu Oct 24 00:27:07 PDT 2013
On Thursday, 24 October 2013 at 06:12:03 UTC, qznc wrote:
>> import std.stdio;
>> struct pair { double hi, lo; }
>> pair normalize(pair q)
>> {
>> double h = q.hi + q.lo;
>> double l = q.lo + (q.hi - h);
>> return pair(h,l);
>> }
>> void main()
>> {
>> immutable static pair spn = normalize(pair(1.0,0.1));
>> writeln(spn);
>> writeln(pair(1.0,0.1));
>> writeln(normalize(pair(1.0,0.1)));
>> }
> I cannot see any significant difference. The fadd-fsub-fadd
> sequence seems to be the same in both cases.
More observations. It requires -m32 to reproduce. On 64bit is
gives the desired output even in optimized form.
I wrote a small C program for comparison:
------
#include <stdio.h>
typedef struct pair {
double hi, lo;
} pair;
pair normalize(pair q) {
double h = q.hi + q.lo;
double l = q.lo + (q.hi - h);
//double l = q.lo + (q.hi - (q.hi + q.lo));
pair res = {h,l};
return res;
}
int main() {
pair x = {1.0, 0.1};
pair y = normalize(x);
printf("%g %g\n", y.hi, y.lo);
return 0;
}
------
gcc -m32 normtest_replicate.c; ./a.out
Output: 1.1 -8.32667e-17
Note the commented line, if you use that instead of the line
above, then
Output: 1.1 0
The C semantic says that h must be rounded to double. In the
second case l is computed with full hardware precision instead.
For a shorter example, two versions:
double x = a - b; double y = c + (a - b);
double y = c + x;
In C those have different semantics in terms of the precision,
but in D they are the equivalent.
More information about the Digitalmars-d
mailing list