2012-04-17 60 views
2

我在SQL Server中運行到這個bug 2012 ACOS功能:SQL 2012錯誤的ACOS功能

declare @lat1 decimal(12,10), @lon1 decimal(12,10), @lat2 decimal(12,10), @lon2 decimal(12,10) 
declare @dist float 

select @lat1=51.1790825000, @lon1= 4.1590020000, @lat2= 51.1790825000, @lon2= 4.1590020000 
set @dist = SIN(RADIANS(@lat1)) * SIN(RADIANS(@lat2)) + COS(RADIANS(@lat1)) * COS(RADIANS(@lat2)) * COS(RADIANS(@lon1 - @lon2)) 

print @dist 
print ACOS(1) 
print ACOS(@dist) 

最後的打印功能提供了一個「出現無效的浮點運算。」這個工程在SQL Server 2008精

弗拉德

+0

這不是問題。如果您發現了一個錯誤,請將其發佈到[connect](https://connect.microsoft.com/SQLServer) – DaveShaw 2012-04-17 09:43:28

+1

具有2個不同實例或2個不同計算機的相同服務器?我在本地PC上遇到SQL Server 2012 RC0和SQL Server 2008 R2 Express上的錯誤。並在聯網的SQL Server 2008 R2上。所以這歸結爲硬件(zhe CPU)可能 – gbn 2012-04-17 09:43:51

回答

1

使用

print ACOS(CASE WHEN @dist > 1 THEN 1 ELSE @dist END) 

@distfloat數據類型,實際上是略多於1由於四捨五入問題,這可以從下面可以看到。

SELECT CAST(@dist AS BINARY(8)) AS [@dist], 
     CAST(CAST(1 AS FLOAT) AS BINARY(8)) AS [1] 

返回

@dist    1 
------------------ ------------------ 
0x010000000000F03F 0x000000000000F03F 

010000000000F03Fthe IEEE converter here表明,這是大約1.0000000000000002220446049250313080847263可以從以下(退貨Y

SELECT 
    CASE WHEN @dist between 1.0000000000000002220446049250313080847 AND 
          1.0000000000000002220446049250313080848 
    THEN 'Y' ELSE 'N' END 
3

它看起來像你想驗證來計算地球上兩點之間的距離。讓您的生活更輕鬆,並使用內置的地理類型。

DECLARE @lat1 DECIMAL(12, 10) , 
    @lon1 DECIMAL(12, 10) , 
    @lat2 DECIMAL(12, 10) , 
    @lon2 DECIMAL(12, 10) 
DECLARE @dist FLOAT 

SELECT @lat1 = 51.1790825000 , 
     @lon1 = 4.1590020000 , 
     @lat2 = 51.1790825000 , 
     @lon2 = 4.1590020000 

DECLARE @p1 GEOGRAPHY = GEOGRAPHY::Point(@lat1, @lon1, 4326) , 
    @p2 GEOGRAPHY = GEOGRAPHY::Point(@lat2, @lon2, 4326) 

SELECT @dist = @p1.STDistance(@p2) 
+0

+1 - 這正是地理類型的意義! – 2012-04-17 16:21:51

+0

超酷!歡呼不需要罪孽處理自己!但這個'4326'是什麼? – Zia 2013-11-29 12:10:34

+0

沒問題。 STSrid是表示實例的空間參考標識符(SRID)的整數。 – Zia 2013-11-29 12:14:01

1

浮子值參數爲ACOS()函數具有-1之間是到1米的範圍..因此

FUNCTION [dbo].[Calculate_Distance] 
( 
@Lat1 float, @Long1 float, @Lat2 float, @Long2 float 
) 
RETURNS float 
AS 
BEGIN 

    DECLARE @acosValue float  
    DECLARE @R float 
    SET @R = 3958.7558657440545 -- mi  
    DECLARE @Distance float 
    Set @acosValue= cos(radians(@Lat1)) * cos(radians(@Lat2)) * cos(radians(@Long2) - radians(@Long1)) + sin(radians(@Lat1)) * sin(radians(@Lat2)) ; 
    IF @acosValue>1.0 
    Begin 
    Set @acosValue=1.0; 
    End 
    IF @acosValue<-1.0 
    Begin 
    Set @acosValue=-1.0; 
    End 

    SET @Distance = acos(@acosValue) 
    * @R; 

    RETURN @Distance 

END 
GO 

嘗試此

0

作爲其他的答案都表示,則必須一個浮點問題,根據不同的CPU架構,它會有不同的表現。然而,有一個簡單的單線程可以解決您的問題:

declare @dist float需要更改爲declare @dist decimal(12, 10)