Jump to page: 1 2 3
Thread overview
floating-WTF
Jan 24, 2012
Caligo
Jan 24, 2012
sclytrack
Jan 24, 2012
sclytrack
Jan 24, 2012
sclytrack
Jan 24, 2012
Dejan Lekic
Jan 24, 2012
sclytrack
Jan 24, 2012
sclytrack
Jan 24, 2012
Caligo
Jan 24, 2012
sclytrack
Jan 24, 2012
dennis luehring
Jan 24, 2012
dennis luehring
Jan 24, 2012
sclytrack
Re: floating-WTF - Compiler-BUG with 64bit
Jan 24, 2012
dennis luehring
Jan 24, 2012
Caligo
Jan 24, 2012
dennis luehring
Jan 24, 2012
%u
Jan 25, 2012
Timon Gehr
Jan 28, 2012
sclytrack
Jan 28, 2012
Timon Gehr
Jan 28, 2012
Caligo
Jan 28, 2012
sclytrack
Jan 29, 2012
Caligo
Jan 29, 2012
sclytrack
Jan 29, 2012
Jonathan M Davis
January 24, 2012
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
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
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
---------------------------------------
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
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

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
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
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
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
double works correct under dmd64, but float not?

what is the behavior of dmd32 in this szenario?
« First   ‹ Prev
1 2 3