MySQL Bug? (Тригонометрия) - PullRequest
       10

MySQL Bug? (Тригонометрия)

7 голосов
/ 24 марта 2011

Я оптимизировал запрос, предварительно рассчитав некоторые тригонометрические функции для полей в таблице, когда наткнулся на это:

SELECT 6371 * acos( 0.793521289617132 * 0.793521289617132 + 0.608542490648241 * 0.608542490648241 * cos( 0.235244203230056 - 0.235244203230056 ) ) 

возвращает ноль

запрос с нерасчетными значениями:

SELECT 6371 * acos( sin( radians( 52.51581 ) ) * sin( radians( 52.51581 ) ) + cos( radians( 52.51581 ) ) * cos( radians( g.lat ) ) * cos( radians( 13.4785 ) - radians( 13.4785 ) ) )

возвращает 0 (это правильный результат)

Это ошибка? или это ожидается?

Ответы [ 2 ]

6 голосов
/ 24 марта 2011

В вашем запросе есть ошибки округления, которые являются результатом арифметики с плавающей точкой.

Если вы попробуете этот запрос

SELECT -1 + ( 0.793521289617132 * 0.793521289617132 + 0.608542490648241 * 0.608542490648241 * cos( 0.235244203230056 - 0.235244203230056 ) )

, вы получите 6.66133814775094e-016.Итак, вы пытаетесь сделать

SELECT 6371 * acos( 1 + 6.66133814775094e-016 ) 

, что, очевидно, не сработает, потому что acos определено только в домене [-1,1].

Я незнаю, что именно вы пытаетесь выполнить, но вам нужно переделать свои вычисления, например, проверить, не вышел ли параметр для acos, а затем установить соответствующее значение, например, так:

ACOS( IF(val BETWEEN -1 AND 1, val, SIGN(val))
4 голосов
/ 24 марта 2011

ACOS возвращает NULL, если X не находится в диапазоне от -1 до 1

может быть в случае с нерасчетными значениями, MySQL делает некоторое упрощение перед применением ACOS

...