3

SQL Server2012ACOS関数でこのバグが発生しました。

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)

最後の印刷関数は、「無効な浮動小数点演算が発生しました」を示します。これはSQLServer2008で正常に機能します

ウラド

4

4 に答える 4

3

地球上の2点間の距離を計算しようとしているようです。生活を楽にし、組み込みの地理タイプを使用します。

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)
于 2012-04-17T14:48:00.513 に答える
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

ここでIEEEコンバーターに010000000000F03F差し込むと、これが以下から確認できるおおよそのものであることがわかります( が返されます)1.0000000000000002220446049250313080847263Y

SELECT 
     CASE WHEN @dist between 1.0000000000000002220446049250313080847 AND 
                             1.0000000000000002220446049250313080848 
     THEN 'Y' ELSE 'N' END
于 2012-04-17T12:38:17.890 に答える
1

acos() 関数の float 値の引数は、-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

これを試して

于 2012-08-13T11:24:25.953 に答える
0

他の回答が述べているように、浮動小数点の問題があります。これは、CPU アーキテクチャによって異なる方法で提示されます。ただし、問題を解決する簡単なワンライナーがあります。

declare @dist floatに変更する必要がありますdeclare @dist decimal(12, 10)

于 2013-12-31T16:43:48.547 に答える