Page 1 of 1

doubel floats how in purebasic 3.93 ?

Posted: Fri Apr 22, 2005 11:39 pm
by doodlemunch
how to use / make double floats in purebasic?
is passing 2 times each float ok? isnt there any elegant way to do this? with real double floats? how? examples? thankz

Posted: Sat Apr 23, 2005 12:08 am
by jack
Danilo wrote:Try this.

Code: Select all

Structure DOUBLE
  high.l
  low.l
EndStructure

Procedure Your_Function_That_Returns_Double()
  !FLDPI
EndProcedure

Procedure.f CatchDoubleReturn(*x.DOUBLE)
  !MOV  dword EAX,[ESP]
  !FST  qword [EAX]
  ;ProcedureReturn
EndProcedure

Procedure.f Double2Float(*x.DOUBLE)
  !MOV  dword EAX,[ESP]
  !FLD  qword [EAX]
  ;ProcedureReturn
EndProcedure

; Call your function
CallFunctionFast(@Your_Function_That_Returns_Double()) ; call DLL function
Debug CatchDoubleReturn(my.DOUBLE)

; now our double is in 'my'
; PB cant handle doubles directly, so
; lets convert it to float
Debug Double2Float(my)
Doubles are returned in ST(0), so CallFunctionF() and CallFunctionFastF()
would automatically convert it to float - if Fred adds this 1 day.

You should be careful, maybe your DLL returns a pointer to double.
In this case the above doesnt work and you have to do:
*x.DOUBLE = CallFunction....

To work with the DOUBLE variables in PureBasic after you got it
from the DLL, take a look at the F64 library from freedimension.

Posted: Sat Apr 23, 2005 12:14 am
by doodlemunch
well i just want to pass a float i have as if it was a double to a dll how?
i got myfloat.f = 2.30 and i want to pass it to a dll but it requires double floats instead of single floats how can i pass it as double then its drivin me nutz

Posted: Sat Apr 23, 2005 12:57 am
by jack

Code: Select all

;if you have the F64 lib installed, then this structure is already defined.
Structure double
  a.l
  b.l
EndStructure

Procedure FtoDouble(x.f,*y.double)
! fld dword [esp]
! mov eax,[esp+4]
! fstp qword [eax]
ProcedureReturn
EndProcedure

mydouble.double
FtoDouble(myfloat,mydouble)

;if passed by value
CallFunctionFast(*FunctionPointer, mydouble\a, mydouble\b)

;if passed by reference
CallFunctionFast(*FunctionPointer, mydouble)

Posted: Sat Apr 23, 2005 1:17 am
by doodlemunch
hi thanks can you explain me what are the ASM commands doing exactly? i am just starting with asm and i dont know much about it so i would like to know what are you exactly doing at the FtoDouble() procedure. thanks!!!

Posted: Sat Apr 23, 2005 2:25 am
by jack

Code: Select all

Procedure FtoDouble(x.f,*y.double) 
! fld dword [esp]     ;load fpu (st0) with the value of x.f, which is on the stack
   ;floats in PB are 32 bit or dword, therefore you instruct the cpu to load
   ;a single precision float by using 'dword'
! mov eax,[esp+4]  ;move pointer to double precision float into 32 bit register eax
! fstp qword [eax]  ;store the value in st0 as double precision into memory
   ;pointed to by eax, or 'y' 
ProcedureReturn ;eax contains the pointer to 'y' which is returned.
   ;it allows you to nest the procedure like this:
   ;only if passed by reference.
   ;CallFunctionFast(*FunctionPointer, FtoDouble(myfloat, mydouble))
EndProcedure 
hope this helps :)

Posted: Sat Apr 23, 2005 3:11 am
by jack
btw, the register esp is the stack pointer, and parameters in a procedure are pushed onto the stack.
for example

Code: Select all

Procedure myfunction(a$,a.l,b.w,c.l,*d.double)
;[esp] points to a$
;[esp+4] holds value of a.l ;the previous argument size is 4 bytes (0+4=4)
;[esp+8] holds value of b.w ;the previous argument size is 4 bytes (4+4=8)
;[esp+10] holds value of c.l ;the previous argument size is 2 bytes (8+2=10)
;[esp+14] holds pointer to d.double ;the previous argument size is 4 bytes (10+4=14)
x.double
n.l
y.double
m.l
;lea [esp+18] holds pointer to x.double ;the previous argument size is 4 bytes (14+4=18)
;[esp+26] holds value to n.l ;the previous structure size is 8 bytes (18+8=26)
;lea [esp+30] holds pointer to y.double ;the previous size is 4 bytes (26+4=30)
;[esp+38] holds value to m.l ;the previous structure size is 8 bytes (30+8=38)
EndProcedure
to put a pointer to structure from argument list into a register, do MOV EAX [ESP+whatever]
to put a pointer to a structure from local variable into a register, do LEA EAX,[ESP+whatever]
hope this makes sense :lol: