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
doubel floats how in purebasic 3.93 ?
-
doodlemunch
- Enthusiast

- Posts: 237
- Joined: Tue Apr 05, 2005 11:20 pm
Danilo wrote:Try this.
Doubles are returned in ST(0), so CallFunctionF() and CallFunctionFastF()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)
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.
-
doodlemunch
- Enthusiast

- Posts: 237
- Joined: Tue Apr 05, 2005 11:20 pm
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)
-
doodlemunch
- Enthusiast

- Posts: 237
- Joined: Tue Apr 05, 2005 11:20 pm
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
btw, the register esp is the stack pointer, and parameters in a procedure are pushed onto the stack.
for example
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
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 a structure from local variable into a register, do LEA EAX,[ESP+whatever]
hope this makes sense
