Thanks for the analysis.

On 04/20/2013 05:30 AM, Simen Kjaeraas wrote:

>      static const(float) pi = 3.141592654f;
>
> If we compare that to std.math.PI, we see that they're different:
>
>      >> writeln( 3.141592654f - std.math.PI );
>      4.10207e-10

std.math.PI is a 'real'. According to the language definition, the calculation above must be done as 'real'. It is described under "Usual Arithmetic Conversions" here:

  http://dlang.org/type.html

Quoting: "If either operand is real, the other operand is converted to real."

Unfortunately, the variable 'pi' above cannot be as good a representation of pi as std.math.PI.

> If, however, we assign these values to some temporary floats, we see that
> they're equal:
>
>      >> float a = 3.141592654f;
>      >> float b = std.math.PI;

It is arguable whether that lossy conversion from real to float should be allowed. Such rules have been inherited all the way from C. They will not change at this point for D. :/

>      >> writeln( a - b );
>      0

> Replace float with double or real in the above, and the difference
> reappears.
>
> So, we have established that 3.141592654f is a valid approximation to pi
> for a
> float. The problem thus has to be one of precision. I'm not sure if it's
> a valid
> optimization for the compiler to use doubles instead of floats (it
> certainly
> seem innocuous enough). I'd say file a bug on it. Worst case, it gets
> closed as
> invalid.

Unfortunately, it is not a bug in D or dmd.

Ali

Reply via email to