View mode: basic / threaded / horizontal-split · Log in · Help
January 24, 2012
floating-WTF
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

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?
January 24, 2012
Re: floating-WTF
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?
January 24, 2012
Re: floating-WTF
t=0.750000, a=-2.000000, b=2.000000, s1=-0.500000, s2=0.000000, 
rt1=-0.500000, rt2=1.500000  :::
1.5

t = 0.75	ok
a = -2.0	ok
b = 2.0		ok
s1 = -0.5	ok
s2 = 1.5   //<----different above says s2 = 0.0
rt1= 1.0 = s1 + s2   semi-ok depends on s2.
rt2 = 1.0 = ((1.0 - t) * a) + (t * b);  goes nuts.



On 01/24/2012 10:03 AM, sclytrack wrote:
> 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?
>
January 24, 2012
Re: floating-WTF
---------------------------------------
alias float Real;
Real lerp(Real t, Real a, Real b)
{		
  Real s2 = t * b;
  writeln("t*b= ", s2);
  writeln("t*b= ", t * b);
  return s2;
}

Output:
t*b= 1.5
t*b= 1.5
-------------------------------------


alias float Real;

Real lerp(Real t, Real a, Real b)
{

  Real s1 = (1.0 - t) * a;

  Real s2 = t * b;
  writeln("t*b= ", s2);
  writeln("t*b= ", t * b);
  return s2;
}


Output:
t*b= 0
t*b= 1.5
-------------------------------------




>>
>>> I presume this is another DMD bug?
>>
>

yes.
January 24, 2012
Re: floating-WTF
No, it is not a bug.

Here is a hint:

import std.stdio;

int main() {
 float f;
 writeln(f);
 return 0;
}

/+--- output ----------+
nan
+--- end of output ---+/
January 24, 2012
Re: floating-WTF
void calculate2(float a, float b)
{
	float s1 = 1.0 - a;
	float s2 = a * b;
	writeln(s2);
	writeln(a * b);
}

----------------
Output:
t*b= 0
t*b= 1.5
----------------


	assume	CS:.text._D4main10calculate2FffZv
_D4main10calculate2FffZv:
		push	RBP
		mov	RBP,RSP
		sub	RSP,020h
		movss	-010h[RBP],XMM0
		movss	-8[RBP],XMM1
		mov	RAX,03FF0000000000000h
		mov	-020h[RBP],RAX
		movsd	XMM2,-020h[RBP]
		cvtss2sd	XMM1,XMM1
		subsd	XMM2,XMM1
------conversion but xmm2 is no longer used
		cvtsd2ss	XMM2,XMM2
------precision error multiplication
		mulss	XMM1,XMM0
		movss	-018h[RBP],XMM1
		movss	XMM0,-018h[RBP]
		call	  _D3std5stdio14__T7writelnTfZ7writelnFfZv@PC32
		movss	XMM0,-8[RBP]
		movss	XMM1,-010h[RBP]
		mulss	XMM0,XMM1
		call	  _D3std5stdio14__T7writelnTfZ7writelnFfZv@PC32
		leave
		ret
		nop
		nop
		nop

------------
DMD64 D Compiler v2.057
Ubuntu 11.10
January 24, 2012
Re: floating-WTF
On 01/24/2012 01:51 PM, Dejan Lekic wrote:
> No, it is not a bug.
>
> Here is a hint:
>
> import std.stdio;
>
> int main() {
> float f;
> writeln(f);
> return 0;
> }
>
> /+--- output ----------+
> nan
> +--- end of output ---+/
>

I don't understand.
January 24, 2012
Re: floating-WTF
On 01/24/2012 04:41 PM, sclytrack wrote:
> On 01/24/2012 01:51 PM, Dejan Lekic wrote:
>> No, it is not a bug.
>>
>> Here is a hint:
>>
>> import std.stdio;
>>
>> int main() {
>> float f;
>> writeln(f);
>> return 0;
>> }
>>
>> /+--- output ----------+
>> nan
>> +--- end of output ---+/
>>
>
> I don't understand.

I see now I forgot the input values. Sorry my IQ is 87.


void calculate2(float a, float b)
{
    float s1 = 1.0 - a;
    float s2 = a * b;
    writeln(s2);
    writeln(a * b);
}

-------INPUT values


int main()
{
	calculate2(0.75f,2.0f);
	return 0;
}

----------------
Output:
t*b= 0
t*b= 1.5
----------------
January 24, 2012
Re: floating-WTF
can you give us a complete out-of-the-box compileable example (with 
imports,main,etc.) with both examples the working/and nonworking

does it work correct with dmd(32bit)?

is this "calculate2" needed to reproduce the behavior?

and what compiler did you test: dmd64, (dmd32?), ...?

Am 24.01.2012 16:20, schrieb sclytrack:
>
>
> void calculate2(float a, float b)
> {
> 	float s1 = 1.0 - a;
> 	float s2 = a * b;
> 	writeln(s2);
> 	writeln(a * b);
> }
>
> ----------------
> Output:
> t*b= 0
> t*b= 1.5
> ----------------
>
>
> 	assume	CS:.text._D4main10calculate2FffZv
> _D4main10calculate2FffZv:
> 		push	RBP
> 		mov	RBP,RSP
> 		sub	RSP,020h
> 		movss	-010h[RBP],XMM0
> 		movss	-8[RBP],XMM1
> 		mov	RAX,03FF0000000000000h
> 		mov	-020h[RBP],RAX
> 		movsd	XMM2,-020h[RBP]
> 		cvtss2sd	XMM1,XMM1
> 		subsd	XMM2,XMM1
> ------conversion but xmm2 is no longer used
> 		cvtsd2ss	XMM2,XMM2
> ------precision error multiplication
> 		mulss	XMM1,XMM0
> 		movss	-018h[RBP],XMM1
> 		movss	XMM0,-018h[RBP]
> 		call	  _D3std5stdio14__T7writelnTfZ7writelnFfZv@PC32
> 		movss	XMM0,-8[RBP]
> 		movss	XMM1,-010h[RBP]
> 		mulss	XMM0,XMM1
> 		call	  _D3std5stdio14__T7writelnTfZ7writelnFfZv@PC32
> 		leave
> 		ret
> 		nop
> 		nop
> 		nop
>
> ------------
> DMD64 D Compiler v2.057
> Ubuntu 11.10
January 24, 2012
Re: floating-WTF
double works correct under dmd64, but float not?

what is the behavior of dmd32 in this szenario?
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home