PureBasic Forum https://www.purebasic.fr/english/ |
|
Function DMS https://www.purebasic.fr/english/viewtopic.php?f=35&t=71542 |
Page 1 of 1 |
Author: | Mesa [ Wed Oct 10, 2018 11:14 am ] |
Post subject: | Function DMS |
Do you have in your archive, a function in assembler to convert decimal degrees to degree minutes seconds ? Like that: dms(10.50) = 10.30 (10 degrees and 30 minutes) dms(10.50833333) = 10.3030 Thanks. M. |
Author: | Helle [ Sat Oct 13, 2018 2:54 pm ] |
Post subject: | Re: Function DMS |
For fun with FPU, SSE and SSE2; PB 64-bit: Code: ;PB 5.61 (x64)
Procedure.s DMS_FPU(DD.d) !fstcw word[CW_FPU] !mov ax,[CW_FPU] !or [CW_FPU],0000110000000000b ;no rounding, truncation !fldcw word[CW_FPU] !fld qword[p.v_DD] ;no check of range! !fist word[DMS_FPU] !fisub word[DMS_FPU] !fmul qword[V60_FPU] !fist word[DMS_FPU+2] !mov [CW_FPU],ax !fldcw word[CW_FPU] ;restore ControlWord, rounding seconds !fisub word[DMS_FPU+2] !fmul qword[V60_FPU] !fistp word[DMS_FPU+4] ;second as rounded integer DMS_FPU$ = Str(PeekW(?DMS_FPU)) + "." + RSet(Str(PeekW(?DMS_FPU + 2)), 2, "0") + RSet(Str(PeekW(?DMS_FPU + 4)), 2, "0") ProcedureReturn DMS_FPU$ DataSection DMS_FPU: ;Degree Minute Second !DMS_FPU dq ? !V60_FPU dq 60.0 !CW_FPU dw ? ;FPU-ControlWord EndDataSection EndProcedure Debug DMS_FPU(10.50833333) Debug DMS_FPU(10.50) Debug DMS_FPU(123.987654) Debug "=============" Procedure.s DMS_SSE(DD.f) !cvttss2si eax,xmm0 !mov word[DMS_SSE],ax !cvtsi2ss xmm1,eax !subss xmm0,xmm1 !mulss xmm0,[V60_SSE] !cvttss2si eax,xmm0 !mov word[DMS_SSE+2],ax !cvtsi2ss xmm1,eax !subss xmm0,xmm1 !mulss xmm0,[V60_SSE] !cvtss2si eax,xmm0 !mov word[DMS_SSE+4],ax DMS_SSE$ = Str(PeekW(?DMS_SSE)) + "." + RSet(Str(PeekW(?DMS_SSE + 2)), 2, "0") + RSet(Str(PeekW(?DMS_SSE + 4)), 2, "0") ProcedureReturn DMS_SSE$ DataSection DMS_SSE: ;Degree Minute Second !DMS_SSE dq ? !V60_SSE dd 60.0 EndDataSection EndProcedure Debug DMS_SSE(10.50833333) Debug DMS_SSE(10.50) Debug DMS_SSE(123.987654) Debug "=============" Procedure.s DMS_SSE2(DD.d) !cvttsd2si eax,xmm0 !mov word[DMS_SSE2],ax !cvtsi2sd xmm1,eax !subsd xmm0,xmm1 !mulsd xmm0,[V60_SSE2] !cvttsd2si eax,xmm0 !mov word[DMS_SSE2+2],ax !cvtsi2sd xmm1,eax !subsd xmm0,xmm1 !mulsd xmm0,[V60_SSE2] !cvtsd2si eax,xmm0 !mov word[DMS_SSE2+4],ax DMS_SSE2$ = Str(PeekW(?DMS_SSE2)) + "." + RSet(Str(PeekW(?DMS_SSE2 + 2)), 2, "0") + RSet(Str(PeekW(?DMS_SSE2 + 4)), 2, "0") ProcedureReturn DMS_SSE2$ DataSection DMS_SSE2: ;Degree Minute Second !DMS_SSE2 dq ? !V60_SSE2 dq 60.0 EndDataSection EndProcedure Debug DMS_SSE2(10.50833333) Debug DMS_SSE2(10.50) Debug DMS_SSE2(123.987654) |
Author: | Mesa [ Mon Oct 22, 2018 5:59 pm ] |
Post subject: | Re: Function DMS |
Woah, very impressive. Thanx. DMS_FPU(DD.d) works very well with x86 but not DMS_SSE(DD.f) and DMS_SSE2(DD.d). Could you tell me why DMS_SSE(DD.f) and DMS_SSE2(DD.d) return 0 with x86 ? ( they use 32b eax and xmm0,1 so they should work in x86, no ?) Thanx. M. |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |