www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Floating point differences at compile-time

reply bearophile <bearophileHUGS lycos.com> writes:
I don't understand where the result differences come from in this code:

import std.math: sqrt, PI;
import std.stdio: writefln;

void main() {
  const double x1 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x1));

  double x2 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x2));

  real x3 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x3));

  real x4 = 3.0L * PI / 16.0L;
  writefln("%.17f", sqrt(1.0L / x4));
}

Output with various D compilers:

DMD1:
1.30294003174111994
1.30294003174111972
1.30294003174111979
1.30294003174111979

DMD2:
1.30294003174111972
1.30294003174111972
1.30294003174111979
1.30294003174111979

LDC:
1.30294003174111994
1.30294003174111994
1.30294003174111972
1.30294003174111972

I'd like the compiler(s) to give more deterministic results here.

Bye,
bearophile
Dec 31 2009
parent Don <nospam nospam.com> writes:
bearophile wrote:
 I don't understand where the result differences come from in this code:
 
 import std.math: sqrt, PI;
 import std.stdio: writefln;
 
 void main() {
   const double x1 = 3.0 * PI / 16.0;
   writefln("%.17f", sqrt(1.0 / x1));
 
   double x2 = 3.0 * PI / 16.0;
   writefln("%.17f", sqrt(1.0 / x2));
 
   real x3 = 3.0 * PI / 16.0;
   writefln("%.17f", sqrt(1.0 / x3));
 
   real x4 = 3.0L * PI / 16.0L;
   writefln("%.17f", sqrt(1.0L / x4));
 }
This is caused by compile-time constant folding being done at higher precision than at run time; and compile-time doubles and floats are actually stored at real precision. If you change 'const double' into 'enum double' for D2, the values for D1 and D2 will match. But I agree, we ought to do better than this.
 
 Output with various D compilers:
 
 DMD1:
 1.30294003174111994
 1.30294003174111972
 1.30294003174111979
 1.30294003174111979
 
 DMD2:
 1.30294003174111972
 1.30294003174111972
 1.30294003174111979
 1.30294003174111979
 
 LDC:
 1.30294003174111994
 1.30294003174111994
 1.30294003174111972
 1.30294003174111972
 
 I'd like the compiler(s) to give more deterministic results here.
 
 Bye,
 bearophile
Jan 01 2010