Проблема с плавающей точкой в ​​SQL Server 2005 - PullRequest
2 голосов
/ 04 августа 2010

Код ниже используется для расчета миль между двумя городами. В данном случае это расстояние от Ярмута, ME до Ярмута, ME - очевидно, ноль - это означает, что результаты для городов в пределах X миль от Ярмута должны включать сам Ярмут.

Проблема в том, что широта и долгота для Ярмута, кажется, вызывают некоторую проблему с плавающей запятой (я не видел этого с другими городами):

DECLARE @fromlong FLOAT, @fromlat FLOAT, @tolong FLOAT, @tolat FLOAT, @test FLOAT

SET @fromlong = 43.8219
SET @fromlat = -70.1758
SET @tolong = 43.8219
SET @tolat = -70.1758
SET @test = SIN(@fromlong / ( 180 / PI() )) * SIN(@tolong / ( 180 / PI() )) + COS(@fromlong / ( 180 / PI() )) * COS(@tolong / ( 180 / PI() )) * COS(@fromlat / ( 180 / PI() ) - @tolat / ( 180 / PI() ))

PRINT @test /*** Displays "1" ***/

SELECT 3963.0 * ACOS(@test) /*** Displays "a domain error has occurred" ***/

Во-первых, это ошибка SQL Server?

Во-вторых, что я могу сделать, чтобы обойти это? Я знаю, что в приведенном выше примере у меня может быть некоторая логика для IF @test > 1, но этот пример взят из запроса, встроенного в веб-приложение (не мой выбор), поэтому мне нужно исправить запрос, т.е. исправить вычисления, не прибегая к в TSQL, если это возможно, и без искажения каких-либо других возвращаемых значений. Есть идеи?

1 Ответ

3 голосов
/ 04 августа 2010

Согласие с комментариями, кажется, использование FLOAT.Я использовал FLOAT только в этом примере, потому что это был тип данных столбцов, из которых читалась широта / долгота, но, похоже, в этом суть проблемы.Поскольку я не могу изменить типы данных самих столбцов, самым простым решением было изменить тип данных результирующего вычисления, который, кажется, работает нормально во всех случаях:

SELECT 3963.0 * ACOS(CONVERT(DECIMAL(10, 6), @test))

Я понимаю, что оставив расчетfloat может привести к небольшим ошибкам округления, но они приемлемо малы для этого приложения.Спасибо всем, кто прокомментировал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...