私は座標間の距離を計算するためのスクリプトを使用しています。 しかし、合計距離は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();
をSQLでcos1'値が道オフと私ですので、あなたがあなたの '例えば、あなたのコードを投稿する必要がありますこれは、SQLで再現することはできません。 – jeroen
あなたはDBMSを使用しているものを言っていない、MySQLとPostgresのが、0.5991798236858185私のためにあなたの 'cos1'例えば両出力 - 彼らはいつも同じ溶液を生成しても精度が16 – iainn
に設定されている場合、PHPと同じですが、あなたはまだ彼らはまったく同じであることを前提としません必要があります。それほど異なる実装評価から、 - あなたは直接彼らはおそらく同じ機能($ x)から「例えば '罪($ x)は' 'COS対(M_PI_2)であっても、の評価し、浮動小数点を比較するべきではありません。この@jeroen – SOFe