Procedure.f WrapAngle(angle.f); <- wraps a value into [0,2*Pi) fringe
!fldpi; <- now i have pi into st0
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[p.v_angle]; <- now i have angle in st0, 2*pi into st1
!fprem; <- now i have the remainder of angle/(2*pi) division (i.e. angle%(2*pi)) in st0, 2*pi in st1
!fadd st1,st0;<- now i have angle%(2*pi) in st0, 2*pi+angle%(2*pi) into st1
!fldz;<- now i have 0 in st0, angle%(2*pi) in st1, 2*pi+angle%(2*pi) into st2
!fcomip st1; <- compare st0 and st1, and pop the stack, which means i have now angle%(2*pi) in st0, 2*pi+remainder into st1
!fcmovnbe st0,st1; <- transfer st1 to st0 if not below or equal.
!fstp st1; <- store st0 in st1 and pops stack, which means i have now the result in st0
ProcedureReturn; <- return the result with this last pop
EndProcedure
Procedure.f WrapAngleSigned(angle.f); <- wraps a value into [-Pi,Pi] fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[p.v_angle]
!fprem1
!fstp st1
ProcedureReturn
EndProcedure
Procedure.f WrapAngleDeg(angle.f); <- wraps a value into [0,360) fringe
!fild dword[@f] ; <- now i have 360 into st0
!fld dword[p.v_angle]
!fprem
!fadd st1,st0
!fldz
!fcomip st1
!fcmovnbe st0,st1
!fstp st1
ProcedureReturn
!@@:dd 360
EndProcedure
Procedure.f WrapAngleDegSigned(angle.f); <- wraps a value into [-180,180] fringe
!fild dword[@f] ; <- now i have 360 into st0
!fld dword[p.v_angle]
!fprem1
!fstp st1
ProcedureReturn
!@@:dd 360
EndProcedure
;It works in radians.
;Usage examples for degrees:
#DEGTORAD=#PI/180.0:#RADTODEG=180.0/#PI
;
angle.f=45
angleadd.f=-90
angle.f=WrapAngle((angle.f+angleadd.f)*#DEGTORAD)*#RADTODEG
Debug angle
;
angle.f=45
angleadd.f=-90
angle.f=WrapAngleSigned((angle.f+angleadd.f)*#DEGTORAD)*#RADTODEG
Debug angle
EDIT: updated to PB4.0B7
Last edited by Psychophanta on Thu Mar 23, 2006 9:30 pm, edited 3 times in total.
Procedure.f WrapAngle(f1.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!ftst ;test to see if modulo <= 0
!fnstsw ax ;transfers FPU status word to ax
!fwait
!sahf ;transfers ah to CPU flags.
!jnc near @f ;if number has a negative value (modulo <= 0) then:
!fadd st0,st1
!@@:fstp st1
EndProcedure
Procedure.f WrapValue(Angle.f)
Angle/360
Angle-Int(Angle)
If Angle<0
ProcedureReturn (Angle+1)*360
Else
ProcedureReturn Angle*360
EndIf
EndProcedure
;It works in radians.
;Usage examples for degrees:
#PI=3.14159265:#DEGTORAD=0.01745329:#RADTODEG=57.2957795
#Max= 1000000
;Premier Test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapAngle(i*#DEGTORAD)*#RADTODEG
;angleNew.f=WrapAngle(i)
i + 0.1
Wend
Total1=ElapsedMilliseconds()-Tps
;
; ;Deuxième test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapValue(i)
i + 0.1
Wend
Total2=ElapsedMilliseconds()-Tps
MessageRequester("Test","WrapAngle = " + Str(Total1) + #LFCR$ + "WrapValue = " + Str(Total2),0)
Last edited by Comtois on Fri Jan 13, 2006 3:35 pm, edited 1 time in total.
Procedure.f WrapAngle(f1.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!ftst ;test to see if modulo <= 0
!fnstsw ax ;transfers FPU status word to ax
!fwait
!sahf ;transfers ah to CPU flags.
!jnc near @f ;if number has a negative value (modulo <= 0) then:
!fadd st0,st1
!@@:fstp st1
EndProcedure
Procedure.f WrapValue(Angle.f)
Angle/360
Angle-Int(Angle)
If Angle<0
ProcedureReturn (Angle+1)*360
Else
ProcedureReturn Angle*360
EndIf
EndProcedure
;It works in radians.
;Usage examples for degrees:
#PI=3.14159265:#DEGTORAD=0.01745329:#RADTODEG=57.2957795
#Max= 365
i.f=0
While i < #Max
Debug StrF(WrapAngle(i*#DEGTORAD)*#RADTODEG,3) + " / " + StrF(WrapValue(i),3)
i + 0.1
Wend
I'll add here a degree versions of both functions, i hope today
Procedure.f WrapAngle(angle.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!ftst ;test to see if modulo <= 0
!fstsw ax ;transfers FPU status word to ax
!sahf ;transfers ah to CPU flags.
!jnc near @f ;if number has a negative value (modulo <= 0) then:
!fadd st0,st1
!@@:fstp st1
EndProcedure
Procedure.f WrapAngle(angle.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!fadd st1,st0
!fldz
!fcomip st1
!fcmovnbe st0,st1
!fstp st1
EndProcedure
DisableDebugger
Procedure.f WrapAngle1(angle.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!ftst ;test to see if modulo <= 0
!fstsw ax ;transfers FPU status word to ax
!sahf ;transfers ah to CPU flags.
!jnc near @f ;if number has a negative value (modulo <= 0) then:
!fadd st0,st1
!@@:fstp st1
EndProcedure
Procedure.f WrapAngle2(angle.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!fadd st1,st0
!fldz
!fcomip st1
!fcmovnbe st0,st1
!fstp st1
EndProcedure
Procedure.f WrapAngle3(f1.f); <- wraps a value into [0,2*Pi) fringe
!fldpi
!fadd st0,st0; <- now i have 2*pi into st0
!fld dword[esp]
!fprem1
!ftst ;test to see if modulo <= 0
!fnstsw ax ;transfers FPU status word to ax
!fwait
!sahf ;transfers ah to CPU flags.
!jnc near @f ;if number has a negative value (modulo <= 0) then:
!fadd st0,st1
!@@:fstp st1
EndProcedure
Procedure.f WrapAngleDeg(angle.f); <- wraps a value into [0,360) fringe
!fild dword[@f] ; <- now i have 360 into st0
!fld dword[esp]
!fprem1
!fadd st1,st0
!fldz
!fcomip st1
!fcmovnbe st0,st1
!fstp st1
ProcedureReturn
!@@:dd 360
EndProcedure
Procedure.f WrapValue(Angle.f)
;Auteur Filperj
Angle/360
Angle-Int(Angle)
If Angle<0
ProcedureReturn (Angle+1)*360
Else
ProcedureReturn Angle*360
EndIf
EndProcedure
;It works in radians.
;Usage examples for degrees:
#PI=3.14159265:#DEGTORAD=0.01745329:#RADTODEG=57.2957795
#Max= 1000000
;1er Test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapAngle1(i*#DEGTORAD)*#RADTODEG
i + 0.1
Wend
Total1=ElapsedMilliseconds()-Tps
;2eme Test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapAngle2(i*#DEGTORAD)*#RADTODEG
i + 0.1
Wend
Total2=ElapsedMilliseconds()-Tps
;3eme Test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapAngle3(i*#DEGTORAD)*#RADTODEG
i + 0.1
Wend
Total3=ElapsedMilliseconds()-Tps
;4eme Test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapAngleDeg(i)
i + 0.1
Wend
Total4=ElapsedMilliseconds()-Tps
;5eme test
i.f=0
Tps=ElapsedMilliseconds()
While i < #Max
angleNew.f=WrapValue(i)
i + 0.1
Wend
Total5=ElapsedMilliseconds()-Tps
MessageRequester("Test","WrapAngle1 = " + Str(Total1) + #LFCR$ + "WrapAngle2 = " + Str(Total2) + #LFCR$ + "WrapAngle3 = " + Str(Total3) + #LFCR$ + "WrapAngleDeg = " + Str(Total4) + #LFCR$ + "WrapValue = " + Str(Total5),0)
Does someone know about this wierd Comtois PC behaviour?
Can't understand
The only thing i can say is that obviously this way is not conclusive for testing speed :roll:
I have AMD Athlon 64 3000+
However, good news to know PB is so fast
EDIT: 468 344 406 375 688 was the result in a pentium centrino 1.8GHz
NOTE: Since Pentium4 seem to have a speed problem with fprem1 ASM instruction i replaced it to fprem only in the unsigned result functions bcoz it works the same, but signed functions must have fprem1.
This optimization guide is not bad, but theres others out there: http://www.website.masmforum.com/mark/index.htm
I really can't stand Intel processors (more likely P4) But oh well, got to support them to produce results as fast as possible... Although people keeps on arguing with me.. "p4 is better".. They just have a bigger cache because their processor is bigger bloated!. You don't gain much with a processor that is so bloated...
! Black holes are where God divided by zero ! My little blog! (Not for the faint hearted!)