В настоящее время я делаю расчеты расстояния между координатами и получаю немного разные результаты в зависимости от используемого языка.
Часть расчета занимает вычисление cosine
данного radian
. Я получаю следующие результаты
// cos(0.8941658257446736)
// 0.6261694290123146 node
// 0.6261694290123146 rust
// 0.6261694290123148 go
// 0.6261694290123148 python
// 0.6261694290123148 swift
// 0.6261694290123146 c++
// 0.6261694290123146 java
// 0.6261694290123147 c
Я хотел бы попытаться понять, почему. Если вы смотрите мимо 16dp
c
- это единственный «правильный» ответ с точки зрения округления. Что меня удивило, так это python
с другим результатом.
Эта небольшая разница усиливается в настоящее время, и для тысяч позиций она добавляет немаловажное расстояние.
Не совсем уверен, какэто дубликат. Кроме того, я больше прошу целостного ответа, чем языковой. У меня нет ученой степени в области вычислительной техники.
ОБНОВЛЕНИЕ Я принимаю, что, возможно, это слишком широкий вопрос, я полагаю, мне было любопытно, почему, поскольку мой фон не является CS. Я высоко ценю ссылки на блоги, которые были размещены в комментариях.
ОБНОВЛЕНИЕ 2
Этот вопрос возник при переносе службы с nodejs
на go
. Go
еще более странно, так как теперь я не могу запускать тесты, поскольку сумма расстояний варьируется в зависимости от нескольких значений.
Учитывая список координат, вычисляя расстояние и складывая их вместе, я получаю разные результаты. Я не задаю вопрос, но кажется сумасшедшим, что go
даст другие результаты.
9605.795975874069
9605.795975874067
9605.79597587407
Для полноты здесь приведен расчет расстояния, который я использую:
func Distance(pointA Coordinate, pointB Coordinate) float64 {
const R = 6371000 // Earth radius meters
phi1 := pointA.Lat * math.Pi / 180
phi2 := pointB.Lat * math.Pi / 180
lambda1 := pointA.Lon * math.Pi / 180
lambda2 := pointB.Lon * math.Pi / 180
deltaPhi := phi2 - phi1
deltaLambda := lambda2 - lambda1
a := math.Sin(deltaPhi/2)*math.Sin(deltaPhi/2) + math.Cos(phi1)*math.Cos(phi2)*math.Sin(deltaLambda/2)*math.Sin(deltaLambda/2)
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
d := R * c
return d
}