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