¿Por qué esta función almacenada de MySQL da resultados diferentes que hacer el cálculo en la consulta?

Esta es una pregunta sobre el cálculo de la distancia entre dos puntos de latitud y longitud en la tierra usando una fórmula de Haversine, para usar en proyectos donde necesita tener una función 'encontrar mi más cercano'.

La fórmula de Haversine está bien discutida y resuelta en MySQL enesta publicació.

Luego pregunté aesta pregunt acerca de convertirlo en una función almacenada para que esté disponible para futuros proyectos sin tener que buscar, recordar o volver a escribir la fórmula en su forma larga.

Está todo bien. Excepto que mi función difiere en los resultados (ligeramente) para escribir la fórmula directamente en la consulta, todas las demás cosas son iguales. ¿Por qué es esto

Así que aquí está la función que escribí:

DELIMITER $

DROP FUNCTION IF EXISTS haversine $

CREATE FUNCTION `haversine`
    (fromLatitude FLOAT,
     fromLongitude FLOAT,
     toLatitude FLOAT,
     toLongitude FLOAT,
     unit VARCHAR(20)
     )
    RETURNS FLOAT
    DETERMINISTIC    
    COMMENT 'Returns the distance on the Earth between two known points of longitude and latitude'
    BEGIN
    DECLARE radius FLOAT;
    DECLARE distance FLOAT;

    IF unit = 'MILES' THEN SET radius = '3959';
    ELSEIF (unit = 'NAUTICAL_MILES' OR unit='NM') THEN SET radius = '3440.27694';   
    ELSEIF (unit = 'YARDS' OR unit='YD') THEN SET radius = '6967840';
    ELSEIF (unit = 'FEET' OR unit='FT') THEN SET radius = '20903520';
    ELSEIF (unit = 'KILOMETRES' OR unit='KILOMETERS' OR unit='KM') THEN SET radius = '6371.3929';
    ELSEIF (unit = 'METRES' OR UNIT='METERS' OR unit='M') THEN SET radius = '6371392.9';
    ELSE SET radius = '3959'; /* default to miles */
    END IF;

    SET distance = (radius * ACOS(COS(RADIANS(fromLatitude)) * COS(RADIANS(toLatitude)) * COS(RADIANS(toLongitude) - RADIANS(fromLongitude)) + SIN(RADIANS(fromLatitude)) * SIN(RADIANS(toLatitude))));

    RETURN distance;
    END$

DELIMITER ;

Aquí hay un conjunto de consultas de prueba para encontrar la distancia entre el London Eye y el Palacio de Buckingham, solo por ejemplo. Obviamente, normalmente sustituiría el destino con campos de su base de datos de 'cosas' geográficas ubicadas con las que desea comparar.

SET @milesModifier = 3959;

SET @myLat = 51.503228;
SET @myLong = -0.119703;

SET @destLat = 51.501267;  
SET @destLong = -0.142697;

SELECT  @kilometerModifier AS radius,
    @myLat AS myLat,
    @myLong AS myLong,
    @destLat AS destLat,
    @destLong AS destLong,
    (@milesModifier * ACOS(COS(RADIANS(@myLat)) * COS(RADIANS(@destLat)) * COS(RADIANS(@destLong) - RADIANS(@myLong)) + SIN(RADIANS(@myLat)) * SIN(RADIANS(@destLat)))) AS longFormat,
    haversine(@myLat,@myLong,@destLat,@destLong,'MILES') AS distanceMiles,
    haversine(@myLat,@myLong,@destLat,@destLong,'NAUTICAL_MILES') AS distanceNautical,
    haversine(@myLat,@myLong,@destLat,@destLong,'KM') AS distanceKm,
    haversine(@myLat,@myLong,@destLat,@destLong,'METRES') AS distanceMetres,    
    haversine(@myLat,@myLong,@destLat,@destLong,'YARDS') AS distanceYards,
    haversine(@myLat,@myLong,@destLat,@destLong,'FEET') AS distanceFeet,
    haversine(@myLat,@myLong,@destLat,@destLong,'') AS distanceDefault

En el ejemplo, estamos usando millas, por lo que hemos establecido el radio @ milesModifier en la prueba,radi en la función) a 3959 exactamente.

El resultado que obtuve fue interesante (en MySQL 5.2.6 edición comunitaria), destaca:

| longFormat       | distanceMiles   |
|------------------|-----------------|
| 0.99826000106148 | 0.9982578754425 |

longFormat son las matemáticas realizadas en la consulta, distanceMiles es el resultado de la función.

Los resultados son diferentes ... OK, entonces es una insignificancia en cuanto al uso de la función en un proyecto, pero estoy interesado en saber cómo la misma fórmula dentro o fuera de la función tiene resultados diferentes.

Supongo que tiene que ver con las longitudes de FLOAT: no están especificadas en la función, he intentado especificarlas (hasta 30,15) para dar suficiente espacio para todas las figuras que tengo y salida que espero, pero los resultados aún difieren ligeramente.

Respuestas a la pregunta(1)

Su respuesta a la pregunta