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

Reply via email to