Почему моя построенная формула дает результаты, отличные от той же формулы, используемой в качестве UDF в Excel?

Почему моя построенная формула дает результаты, отличные от той же формулы, используемой в качестве UDF в Excel?

Вот длинная формула для расчета расстояния между двумя точками координат на Земле.

=ACOS(COS(РАДИАНЫ(90-ЛАТ1)) *COS(РАДИАНЫ(90-ЛАТ2)) +SIN(РАДИАНЫ(90-ЛАТ1)) *SIN(РАДИАНЫ(90-ЛАТ2)) *COS(РАДИАНЫ(Long1-Long2))) *6371

Поскольку использовать его внутри других формул немного неудобно, я написал для этого пользовательскую функцию.

Функция DistXY(Lat1 As Single, Lng1 As Single, Lat2 As Single, Lng2 As Single) As Single

DistXY = WorksheetFunction.Acos(Cos(WorksheetFunction.Radians(90 - Lat1)) * Cos(WorksheetFunction.Radians(90 - Lat2)) + Sin(WorksheetFunction.Radians(90 - Lat1)) * Sin(WorksheetFunction.Radians(90 - Lat2)) * Cos(WorksheetFunction.Radians(Lng1 - Lng2))) * 6371

Конечная функция

Как видите, они совершенно одинаковы. Поскольку в VBA нет функций Acos или Radians, он даже использует метод "worksheetFunction".

Почему, когда я применяю эту формулу к одной и той же паре координат XY, я получаю разные результаты?

Например:

От ABC 45.4960674,-73.514446 до XYZ 43.5369,-71.8592

DistXY()результаты: 254.313156128

Метод длинной формулы: 254.313268914

Соглашаясь с комментарием @raystafarian, изменение всех типов на double улучшило точность. Но разница все равно есть.

Функция DistXY(Lat1 As double, Lng1 As double, Lat2 As double, Lng2 As double) As double ...

Новые результаты:

DistXY(): 254.3132689135060км

Метод длинной формулы: 254.3132689135250км

решение1

Вы используете (и возвращаете) тип данныходинокий. Это приведет к тому, что функции будут оцениваться по-разному, если они примут другой тип данных по умолчанию.

решение2

На основеРэйстафарианотвечать:

Public Function DistXY(Lat1 As Double, Lng1 As Double, Lat2 As Double, Lng2 As Double) As Double
   Dim i As Double, f As Double
   Dim wf As WorksheetFunction
   Set wf = Application.WorksheetFunction

   i = 90
   f = 6371

   DistXY = wf.Acos(Cos(wf.Radians(i - Lat1)) * Cos(wf.Radians(i - Lat2)) + Sin(wf.Radians(i - Lat1)) * Sin(wf.Radians(i - Lat2)) * Cos(wf.Radians(Lng1 - Lng2))) * f
End Function

введите описание изображения здесь

Связанный контент