빈센트 또는 소르 세인 또는 코사인의 구형 법칙을 사용하든, 사용하려는 코드의 잠재적 인 문제, 조심하고 완화해야 할 것들, 그리고 빈센트 대 하 세르 인 대 슬로크 문제를 다루는 방법을 알고있는 지혜가 있습니다. 각기 숨어있는 문제 / 가장자리를 인식하게되면 다를 수 있습니다. 노련한 프로그래머가 이것을 알고 있습니다. 초보자는 그렇지 않을 수 있습니다. 포럼의 스 니펫이 특정 경우 예기치 않은 일을 할 때 좌절감을 덜어주기를 바랍니다. 빈센트, 헤르자인, 슬로크, SE, SO, 레딧, 쿼라 등의 버전 중 일부를 심각하게 사용하려는 경우 솔루션의 초기 코딩에 제한적인 도움을 줄 수 있지만 그 의미는 아닙니다. 그들의 해결책이나 받아 들여진 '답변'에는 문제가 없습니다. 프로젝트가 충분히 중요하다면, 적절한 리서치가 필요합니다. 설명서를 읽고, 문서를 읽고, 해당 코드에 대한 코드 검토가 있으면 읽어보십시오. 100 회 이상 공표 된 스 니펫 또는 요지를 복사하여 붙여 넣어도 안전성이 포괄적이고 보장되는 것은 아닙니다.
cffk가 게시 한 흥미로운 답변은 패키지 솔루션에서 예외 또는 기타 어려움을 유발할 수있는 숨어있는 엣지 케이스를 인식하고 있다는 점을 지적 합니다. 그 게시물에 대한 구체적인 주장은 현재 추구하는 시간 예산을 초과하지만 적어도 한 사람이 개선을 제안한 것에 대해 적어도 하나의 빈약 한 구현을 포함하여 특정 패키지에 숨어있는 문제가 실제로 있다는 것을 벗어났습니다. 이러한 어려움을 겪을 위험을 최소화하거나 제거하기 위해 나는 빈약에 관한 주제에 대해 더 이상 언급하지 않지만 (너무 무지한 것임) 적어도 부분적으로는 OP와 관련된 주제에 대해 허세 인으로 바뀔 것이다.
파이썬이나 다른 언어로 널리 퍼져있는 헤르 세인 공식은 오늘날 대부분의 인텔 및 인텔 유사 시스템에서 IEEE 754 부동 소수점 사양을 사용하고 ARM 프로세서, powerPC 등을 사용하기 때문에 부동 소수점 근사와 반올림으로 인해 180 도의 아크 거리, 대구점 근처 또는 거의 드물지만 실제적이고 반복 가능한 예외 오류에 취약합니다. 이 상황으로 일부 초보자는 아직 물지 않았을 수 있습니다. 이 fp 사양은 대략적으로 반올림되므로 fp64를 호출하는 코드가 예외 오류를 일으킬 수 있음을 의미하지는 않습니다. 그러나 일부 코드는 일부 공식은 IEEE 754 fp64의 근사와 반올림으로 인해 값이 완벽하게 평가 될 것으로 예상되는 수학 방법의 영역에서 약간 벗어날 수 있습니다. 예를 들어 ... sqrt (). 음수 값이 sqrt (-0.00000000000000000122739)와 같은 sqrt ()로 들어가면 예외 오류가 발생합니다. 해 세린 공식에서 솔루션으로 진행되는 방식에는 atan2 ()에 두 개의 sqrt () 메소드가 있습니다. 그만큼계산하고 SQRT에 사용되는 (), 세계의 정반대 지점에서 약간 매우 약간, 0.0 이하 또는 1.0 이상으로 인해 FP64 근사치를 이탈하고 라운딩 드물게하지만 반복적. 이러한 맥락에서 일관된 신뢰성있는 반복성은 격리 된 랜덤 플루크 (random fluke)가 아니라 보호해야 할 엣지 케이스 인 예외 위험을 초래합니다. 다음은 필요한 보호 기능이없는 짧은 python3 스리 펫의 예입니다.
import math as m
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
아주 가까운 또는 정반대 지점에서, A는 거의하지만 반복적 것과 동일한 위도 경도 좌표, 음극을 이탈 할 수있다 화학식 I의 첫번째 라인에서 계산. 애프터 / 드문 사건을 해결 한 간단하게 추가 할 수 있습니다, 보호하기 위해 아래와 같이 계산 :
import math as m
note = ''
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
if a < 0.0: a = 0.0 ; note = '*'
if a > 1.0: a = 1.0 ; note = '**'
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
# note = '*' # a went below 0.0 and was normalized back to 0.0
# note = '**' # a went above 1.0 and was normalized back to max of 1.0
물론 여기에 전체 기능을 표시하지는 않았지만 너무 자주 게시되는 짧은 발췌 문장. 그러나 이것은 a 를 테스트하고 필요한 경우 정규화 하여 sqrt ()에 대한 보호를 보여줍니다. 또한 모든 것을 시도해 볼 필요가 없습니다. note = ''up top은 바이트 코드 스테이지 가 함수의 결과와 함께 리턴되는 경우 값이 지정되기 전에 해당 노트 가 사용 중임 을 항의하지 않도록 방지하는 것입니다.
이 간단한 변경으로 두 개의 추가하는 테스트는 SQRT () 함수는 행복 할 것이다, 그리고 코드는 이제 추가가 주 결과가 약간 정상화되었음을 경고, 왜에 코드를 호출로 반환 할 수 있습니다. 일부는 관심을 가질 수도 있고, 그렇지 않을 수도 있지만 예외 오류를 방지 할 수도 있습니다. try except 블록은 예외를 포착 할 수 있지만 명시 적으로 작성하지 않는 한이를 수정하지는 않습니다. 그것은 바로 후 코드 수정 라인 (들)에보다 쉽게 보인다 계산 라인. 철저히 문질러 진 입력은 여기서는 블록을 제외하고는 전혀 시도하지 않아도됩니다.
요약 : 패키지 또는 라이브러리를 사용하지 않고 명시 적으로 코딩 된 hasrsine을 사용하는 경우, 선택한 언어에 관계없이 0.0 <= a <= 1.0의 범위로 테스트하고 정규화 하는 것이 좋습니다. c 계산으로 다음 줄을 보호합니다 . 그러나 대부분의 haversine 코드 스 니펫은이를 보여주지 않으며 위험을 언급하지 않습니다.
경험 : 전 세계에서 0.001도 단위로 철저한 테스트를 수행하는 동안, 한 달 동안의 CPU 냉각의 신뢰성을 부수적으로 테스트하는 한 달 동안 예외, 신뢰할 수 있고 일관된 반복 가능한 예외를 유발하는 위도 조합으로 하드 드라이브를 채웠습니다. 팬과 내 인내심. 예, 그 목적은 대부분 포인트를 증명하는 것이기 때문에 그 로그의 대부분을 삭제했습니다 (말장난이 허용되는 경우). 그러나 테스트 목적으로 유지되는 '문제 지연 값'에 대한 짧은 로그가 있습니다.
정확성 : a 와 전체 haversine 결과를 다시 작은 영역으로 정규화하여 정확도를 잃게됩니까? fp64 근사치와 반올림이 이미 소개 된 것보다 많지 않을 수도 있습니다. 간단하고 빠르며 쉽게 사용자 정의, 문제 해결 및 유지 관리하는 데 빈센트보다 허세 인을 수용 할 수있는 경우, 소르 세인은 프로젝트에 적합한 솔루션 일 수 있습니다.
나는 지구상의 위치에서 보았을 때 방위각과 고도를 하늘 구의 위도와 같은 좌표로 매핑하면서 하늘의 물체 사이의 각도 거리를 측정하기 위해 오버 헤드 투영 된 스카이 스피어에서 hasrsine을 사용했습니다. 투영 된 이론적 스카이 스피어는 지구 표면의 한 위치에서 두 물체 사이의 각도 거리 모양 각도를 측정 할 때 완벽한 구체입니다. 그것은 내 요구에 완벽하게 부합합니다. 따라서, 헤르 세인은 특정 용도 (물론 내 목적 내에서)에서 여전히 매우 유용하고 매우 정확합니다. 그러나 GIS 나 내비게이션을 위해 지구상에서 또는 하늘 물체 관측 및 측정에서 사용하는 경우 보호하십시오. 대퇴 점 또는 대퇴 점 근처의 경우 ,그리고 필요할 때 필요한 도메인으로 다시 몰아 넣습니다.
보호되지 않은 헤르 세인은 인터넷 전체에 있으며, 일부 보호 기능을 보여준 오래된 유즈넷 게시물을 보았습니다 .JPL의 누군가로부터 생각하고 1985 년 이전의 IEEE 754 부동 소수점 사양 일 수 있습니다. 다른 두 페이지에서는 대변 지점 근처에서 가능한 문제에 대해 언급했지만 이러한 문제 나 완화 방법에 대해서는 설명하지 않았습니다. 따라서 신입 사원 (나 같은)은 자신이 복사하여 신뢰하는 프로젝트에 붙여 넣은 일부 코드에 대한 추가 연구 및 엣지 케이스를 충분히 이해하기에 충분하지 않을 수도 있습니다. cffk의 흥미로운 게시물은 이러한 유형의 문제에 대해 공개적이어서 자주 언급되지 않았으며 스 니펫 보호를 위해 거의 공개적으로 코딩되지 않았으며 게시되지 않은 비보호 버전과 논의되지 않은 버전의 양과 비교하여 거의 논의되지 않았습니다.
20190923 현재, 헤르 세인 공식 위키 페이지는 실제로 컴퓨팅 장치의 부동 소수점 문제로 인해 대두 지점에서 발생할 수있는 문제를 언급하고 있습니다 ...
https://ko.wikipedia.org/wiki/Haversine_formula
(현재 위키 페이지에는 직접 링크 할 섹션에 대한 HTML 앵커가 없으므로 페이지가로드 된 후 해당 브라우저 페이지에서 '이 수식을 사용할 때'를 검색하십시오. 보다 공식적으로 언급 된 반포도 점에 대한 haversine의 문제를 참조하십시오.)
그리고이 다른 사이트에도 매우 간단히 언급되어 있습니다.
https://www.movable-type.co.uk/scripts/latlong.html
해당 페이지에서 '라운딩 오류 방지 기능'을 찾으면 다음과 같은 결과가 나타납니다.
atan2를 사용할 수없는 경우 c는 2 ⋅ asin (min (1, √a))에서 계산할 수 있습니다 (반올림 오류 방지 포함).
이제는 반올림 오류가 언급되는 경우가 드물고, asin () 버전에 대해서는 보호 기능이 표시되었지만 atan2 () 버전에는 표시되지 않았거나 표시되지 않았습니다. 그러나 반올림 오류의 위험은 언급되어 있습니다.
헤르 세인을 사용하는 24/7/365 애플리케이션 인 imho는 중요하고 간단한 세부 사항으로서 대 지점 근처에서 이러한 보호가 필요합니다.
어떤 보호 기능 패키지가이 보호 기능을 포함하거나 포함하지 않는지 모르겠지만이 모든 기능을 처음 접하는 경우 널리 보급 된 '스 니펫'버전을 사용하려는 경우 이제 보호가 필요하다는 것을 알게되었습니다. 보호 기능은 구현하기가 매우 간단합니다. 즉, 빈센트를 사용하지 않고 패키지 코드를 쉽게 수정할 수있는 패키지 된 소르 신을 사용하지 않는 경우입니다.
IOW, 빈센트 또는 허세 인 또는 슬로크를 사용하든 코드와 관련된 문제, 조심해야 할 사항 및 완화해야 할 사항, 빈센트 대 헤르 세인 대 슬로크 문제를 처리하는 방법은 각 사람이 인식하는 방식에 따라 다릅니다. 잘 알려 지거나 알려지지 않은 숨은 문제 / 가장자리.