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.
Function DMS
Re: Function DMS
For fun with FPU, SSE and SSE2; PB 64-bit:
Code: Select all
;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)
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.
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.