为什么该MySQL存储函数给出的结果与查询中的计算结果不同?

这是一个有关使用haversine公式计算地球上两个纬度和经度之间的距离的问题,用于需要“查找我最近的”功能的项目中。

haversine公式很好地讨论并在MySQL解决了这个帖子。

然后,我问了一个有关将其转换为存储函数的问题,这样它就可以在以后的项目中使用,而不必查找,记住或重新键入长格式的公式。

都很好。除了我的函数的结果(略有不同)以外,其他条件相同时,直接在查询中直接键入公式即可。为什么是这样?

所以这是我写的函数:

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 ;

这是一组测试查询,旨在查找伦敦眼和白金汉宫之间的距离,仅作为示例。显然,通常您会将目的地替换为您要与之比较的地理位置“事物”数据库中的字段。

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

在示例中,我们使用英里-因此我们将半径( 中的 ,函数中的 )精确设置为3959。

我得到的结果很有趣(在MySQL 5.2.6社区版上),重点是:

| longFormat       | distanceMiles   |

|------------------|-----------------|

| 0.99826000106148 | 0.9982578754425 |

是在查询中完成的数学 , 是函数的结果。

结果是不同的…确定,所以就在项目中使用该函数而言,它是微不足道的,但是我很想知道函数内部或外部的相同公式如何产生不同的结果。

我猜想这与FLOAT的长度有关-在函数中未指定长度,我尝试指定它们(最多30,15),以便为所有图形和输出留出足够的空间我希望-但结果仍然略有不同。

回答:

FLOAT 是一种近似的数据类型-请参阅:

浮点值

数字类型的问题

尝试更改FLOATDECIMAL(30,15)确保您具有正确的精度。

如果要深入讨论浮点,可以尝试以下文章:

每个计算机科学家都应了解的浮点运算法则

以上是 为什么该MySQL存储函数给出的结果与查询中的计算结果不同? 的全部内容, 来源链接: utcz.com/qa/413910.html

回到顶部