Question/request/bug(?) re. floating-point in dmd

qznc qznc at web.de
Thu Oct 24 00:39:39 PDT 2013


On Thursday, 24 October 2013 at 07:27:09 UTC, qznc wrote:
> 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.

Ah, finally found the relevant part of the spec:
"It's possible that, due to greater use of temporaries and common 
subexpressions, optimized code may produce a more accurate answer 
than unoptimized code."
http://dlang.org/float.html


More information about the Digitalmars-d mailing list