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

Apollo Hogan apollo.hogan at gmail.com
Wed Oct 23 08:44:52 PDT 2013


Hi all-

I'm a newcomer to the D language, but am quite impressed with it. 
  I've run into an issue, though, in a little learning project.  
I'm implementing a "double-double" class based on a well-known 
trick using standard floating-point arithmetic.  (See, for 
example, 
http://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic 
and links).

The techniques used to get this kind of code to work correctly, 
rely on subtle properties of IEEE floating point numbers.  Mixing 
precisions or optimisations in floating point code can destroy 
the results.

For example, the appended code produces the following output when 
compiled (DMD32 D Compiler v2.063.2 under WinXP/cygwin) with no 
optimization:

immutable(pair)(1.1, -2.03288e-20)
pair(1, 0.1)
pair(1.1, -8.32667e-17)

and the following results when compiled with optimization (-O):

immutable(pair)(1.1, -2.03288e-20)
pair(1, 0.1)
pair(1.1, 0)

The desired result would be:

immutable(pair)(1.1, -8.32667e-17)
pair(1, 0.1)
pair(1.1, -8.32667e-17)

That is: without optimization the run-time "normalization" is 
correct.  With optimization it is broken.  That is pretty easy to 
work around by simply compiling the relevant library without 
optimization.  (Though it would be nice to have, for example, 
pragmas to mark some functions as "delicate" or 
"non-optimizable".)  A bigger issue is that the compile-time 
normalization call gives the 'wrong' answer consistently with or 
without optimization.  One would expect that evaluating a pure 
function at run-time or compile-time would give the same result...

Cheers,
--Apollo

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)));
}


More information about the Digitalmars-d mailing list