2016-09-23 28 views
0

私は座標間の距離を計算するためのスクリプトを使用しています。 しかし、合計距離は8 KMでなければなりません。これはPHPでは正しいですが、SQL/Doctrineでは3000+です。Sin(SIN)計算PHPとMySQL/Doctrineが異なる

私はPHPとSQL/Doctrineの両方で1つの計算を出力します。これが結果です:

PHP:SIN(* 0.0174532925199433 53.18882060000001)= 0.8006144758170634

SQL:SIN(* 0.0174532925199433 53.18882060000001)= 0.8006144758170636

あなたが見ることができるように。差は0.0000000000000002です。

小さく見えますが、これを使用しています。

PHP:

(ACOS(SIN(53.18882060000001 * 0.0174532925199433)* SIN(53.1655606 * 0.0174532925199433)+ COS(* 0.0174532925199433 53.18882060000001)* COS(53.1655606 * 0.0174532925199433)* COS(異なるがオフの方法であります5.556485699999939 * 0.0174532925199433から5.43966 * 0.0174532925199433))* 6371)

8.204067263544099 KM

SQL /ドクトリン:

(ACOS(SIN(53.1 8882060000001 * 0.0174532925199433)* SIN(53.1655606 * 0.0174532925199433)+ COS(53.18882060000001 * 0.0174532925199433)* COS(53.1655606 * 0.0174532925199433)* COS(5.556485699999939 * 0.0174532925199433から5.43966 * 0.0174532925199433))* 6371)

3296.761195521706 KM

PHPの精度を16(デフォルトは14)に設定しても問題ありません。合計距離は同じです。

どうすればこの問題を解決できますか?私はSIN、COS、ACOSをサポートするDoctrine拡張機能を備えたSymfony 3プロジェクトでこれを使用しています。


より計算:

PHP:

SIN1:罪(53.18882060000001 * 0.0174532925199433)= 0.8006144758170634

SIN2:罪(53.1655606 * 0.0174532925199433)= 0.8003711646618459

COS1:COS(* 0.0174532925199433 53.18882060000001)= 0.5991798236858188

COS2:COS(53.1655606 * 0.0174532925199433)= 0.5995047946245639

cos3:COS(5.556485699999939 * 0.0174532925199433から5.43966 * 0.0174532925199433)= 0。9999979212542568

SQL:

without1:なし(53.18882060000001 * 0.0174532925199433)= 0.8006144758170636

SIN2ありません(* 0.0174532925199433 53.1655606)= 0.800371164661846

COS1:COS( 53.18882060000001 * 0.0174532925199433)= 0.3809279376844091

COS2のCOS(53.1655606 * 0.0174532925199433)= 0.3820183930527858

cos3:COS(5.556485699999939 * 0.0174532925199433から5.43966 * 0.0174532925199433)= 1.568757332266098


これは私がしようとDoctrineのクエリですsymfonyのを使用して実行する:

$lat = 53.18882060000001; 
$lng = 5.556485699999939; 
$tlat = 53.1655606; 
$tlng = 5.43966; 

$sql = "SELECT L, 
        L.latitude AS lat, 
        L.longitude AS lng, 

        SIN(1) AS tmp, 
        SIN($lat*$rad) AS sin1, 
        SIN($tlat*$rad) AS sin2, 
        COS($lat*$rad) AS cos1, 
        COS($tlat*$rad) AS cos2, 
        COS($lng*$rad - $tlng*$rad) AS cos3, 
        (SIN($lat*$rad) * SIN($tlat*$rad) + COS($lat*$rad) * COS($tlat*$rad)) AS test, 
        (sin($lat*$rad) * sin($tlat*$rad) + cos($lat*$rad) * cos($tlat*$rad) * COS($lng*$rad - $tlng*$rad)) AS test1, 
        ACOS(SIN($lat*$rad) * SIN($tlat*$rad) + COS($lat*$rad) * COS($tlat*$rad) * COS($lng*$rad - $tlng*$rad)) AS test2, 
        ACOS(0.5174636941643757) AS test3, 

        (ACOS(SIN($lat*$rad) * SIN($tlat*$rad) + COS($lat*$rad) * COS($tlat*$rad) * COS($lng*$rad - $tlng*$rad)) * 6371) as dist 
      FROM AppBundle:Location AS L 
      "; 
    return $this->getEntityManager()->createQuery($sql)->getResult(); 
+1

をSQLでcos1'値が道オフと私ですので、あなたがあなたの '例えば、あなたのコードを投稿する必要がありますこれは、SQLで再現することはできません。 – jeroen

+0

あなたはDBMSを使用しているものを言っていない、MySQLとPostgresのが、0.5991798236858185私のためにあなたの 'cos1'例えば両出力 - 彼らはいつも同じ溶液を生成しても精度が16 – iainn

+0

に設定されている場合、PHPと同じですが、あなたはまだ彼らはまったく同じであることを前提としません必要があります。それほど異なる実装評価から、 - あなたは直接彼らはおそらく同じ機能($ x)から「例えば '罪($ x)は' 'COS対(M_PI_2)であっても、の評価し、浮動小数点を比較するべきではありません。この@jeroen – SOFe

答えて

0
関連する問題