2010-08-03 101 views
2

下面的代碼用於計算兩個城市之間的英里數。在這種情況下,從雅茅斯,ME到Yarmouth,ME的距離 - 顯然爲零 - 這意味着雅茅斯X英里範圍內的城市的結果應包括雅茅斯本身。SQL Server 2005中的浮點問題

的問題是,雅茅斯的經度和緯度似乎是導致浮點問題的某種(我還沒有與其他城市看到了這一點):

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設置一些邏輯,但是這個例子是從嵌入在web應用程序中的查詢提取的(不是我的選擇),所以我需要修復查詢,即修復計算,而不使用TSQL如果可能,並且不扭曲任何其他返回值。有任何想法嗎?

+0

爲什麼浮動如果你需要確切的價值? – buckbova 2010-08-03 20:54:06

+0

我是否應該執行代碼時出錯?我沒有得到一個只是結果爲0. – buckbova 2010-08-03 21:05:33

+0

良好的捕獲 - 我回去看看數據庫,並意識到我使用的是SSMS 2008,但數據庫是2005年。我將相應地更改該帖子。 – gfrizzle 2010-08-03 21:13:08

回答

3

評論的共識似乎是使用FLOAT。我只在示例中使用了FLOAT,因爲這是讀取緯度/經度的列的數據類型,但似乎是問題的核心。既然不能改變列的數據類型本身,最簡單的解決辦法是改變所產生的計算,這似乎在所有的情況下,以做工精細的數據類型:

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

我意識到離開計算爲float可能會導致小的舍入誤差,但對於此應用程序來說它們可以接受的很小。謝謝所有評論。