floating-WTF

sclytrack sclytrack at fake.com
Tue Jan 24 01:03:52 PST 2012


On 01/24/2012 04:13 AM, Caligo wrote:
> alias double Real;
> //alias float Real;
>
> // simple linear interpolation; I partitioned the internals to help me
> figure out what was happening.
> Real lerp(Real t, Real a, Real b){
>    Real s1 = (1.0 - t) * a;
>    Real s2 = t * b;
>    Real rt1 = s1 + s2;
>    Real rt2 = ((1.0 - t) * a) + (t * b);
>    writefln("t=%.2f, a=%.2f, b=%.2f, s1=%.2f, s2=%.2f, rt1=%.2f,
> rt2=%.2f  :::", t, a, b, s1, s2, rt1, rt2);
>    return rt2;
> }
>
> unittest{
>
>    writeln(lerp(0.75, -2.0, 2.0));  // the correct result is 1.0
> }
>
> compile and run with 'dmd -inline -unittest' and the output should be:
>
> t=0.75, a=-2.00, b=2.00, s1=-0.50, s2=1.50, rt1=1.00, rt2=1.00  :::
> 1
>
> Now, change 'Real' to float by uncommenting the second line and
> compile and run with 'dmd -unittest'.  This is what I get for the
> output:
>
> t=0.75, a=0.00, b=2.00, s1=-0.50, s2=0.00, rt1=-0.50, rt2=1.50  :::
> 1.5

This: (with float)

   writefln("t=%.2f, a=%.2f, b=%.2f, s1=%.2f, s2=%.2f, rt1=%.2f, 
rt2=%.2f  :::", t, a, b, s1, s2, rt1, rt2);
   writefln("t=%.2f, a=%f, b=%.2f, s1=%.2f, s2=%.2f, rt1=%.2f, rt2=%.2f 
  :::", t, a, b, s1, s2, rt1, rt2);

Outputs: (with float)
	
t=0.75, a=0.00, b=2.00, s1=-0.50, s2=0.00, rt1=-0.50, rt2=1.50  :::
t=0.75, a=-2.000000, b=2.00, s1=-0.50, s2=0.00, rt1=-0.50, rt2=1.50  :::

difference:
			
%.2f ---> %f
  		


>
> I have no idea why 'a' is zero.  'rt1' and 'rt2' do not have the same
> value, and 'lerp' does not return 1.0.  Compiling with 'dmd -inline
> -unittest' does produce the correct result as before, though.
>
> You can play with different compiler options, such as -O, to get the
> same weird behavior.
>
> I presume this is another DMD bug?



More information about the Digitalmars-d-learn mailing list