8

Here's my code:

<?php

$lat1 = 35.697959;
$lat2 = 35.697959;
$lon1 = 139.707085;
$lon2 = 139.707085;
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
var_dump($dist); // returns 1

$dist = acos($dist); 
var_dump($dist); // returns NAN

As you can see from the comments, $dist is equal to 1 after the calculation, but when I apply acos() it returns NAN.

If I try to replicate it manually, it works just fine:

$x = 1;
$x = acos($x);
var_dump($x);  // returns 0 as expected

What's going on here and how can I fix it?

Here's the same code in an online shell, so you can see that it actually returns those values.

Victor Marchuk
  • 13,045
  • 12
  • 43
  • 67

2 Answers2

11

Found the solution. It seems that the problem is related to precision. If I make sure that $dist is within [-1,1] range, it works fine:

$dist = acos(min(max($dist,-1.0),1.0)); 

Working example: https://3v4l.org/dlunK

Victor Marchuk
  • 13,045
  • 12
  • 43
  • 67
  • You genius! this saved me a lot of annoyance once I found the source of the NAN. – lakewood Jun 26 '18 at 22:17
  • An alternative answer would be round($dist,12) which has an advantage that it is only fixing the rounding issue. Other errors such as $dist=8 would still flag up. – MortimerCat Jun 24 '22 at 14:47
2

It is because $dist is a little greater than 1, due to rounding.

var_export($dist);

gives me

1.0000000000000002
v7d8dpo4
  • 1,399
  • 8
  • 9