2016-09-13 14 views
1

java.lang.Mathを使用して、多くの三角関数を扱うJavaクラスがあります。次のコードは、0度と180度の平均方向を決定します。 0度と180度が反対方向であり、互いに打ち消しあうため、結果はNaNになります。しかし、私がやるとき:三角関数を扱うときの浮動小数点精度

double[] angles = {0, 180}; 
double sines = 0; 
double cosines = 0; 
double avg; 
for (int i = 0; i < angles.length; i++) { 
    double rad = Math.toRadians(angles[i]); 
    sines += Math.sin(rad); 
    cosines += Math.cos(rad); 
} 
double sin = sines/angles.length; 
double cos = cosines/angles.length; 
System.out.println("Avg sin: " + sin + "\nAvg cos: " + cos); // sin != 0 but it should 
double avgRad = Math.atan2(sin, cos); 
avg = Math.toDegrees(avgRad); 
System.out.println("Average: " + avg); 

avg90.0代わりのNaN等しいです。これは、180度と0度の平均正弦は、(浮動小数点精度の仕組みのため)非常に小さいが正の数になります。上記のコードを実行すると、私の言いたいことがわかります。この精度の欠如を避けるにはどうすればよいですか?平均的なサインとコサインだけでなく、最終的な結果を丸めることができることを知っていますが、それは私にはやや不愉快なようです。

+0

浮動小数点数は丸め誤差の影響を受けやすいです。それと一緒に生きる。 – Mick

+0

私はそれが分かっています。私はそれを回避する方法を求めています。 – Kootling

+0

あなたは正確に何をしようとしていますか? – Mick

答えて

0

sin/cos/tanを使う前に平均化角度を(mod 360を使って)直接考慮していたに違いありません。それは、あなたがあなたのコードで意図したものを得る上で正しい方向にあると言われています(最後の例では、おそらく負の符号の反転を除いて)。

~> java Main 0 180 
Avg sin: 6.123233995736766E-17 
Avg cos: 0.0 
Average: 90.0 

~> java Main 0 179 
Avg sin: 0.00872620321864172 
Avg cos: 7.615242180436521E-5 
Average: 89.50000000000011 

~> java Main 1 179 
Avg sin: 0.017452406437283477 
Avg cos: 0.0 
Average: 90.0 

~> java Main 1 180 
Avg sin: 0.008726203218641817 
Avg cos: -7.615242180436521E-5 
Average: 90.49999999999991 

~> java Main 1 181 
Avg sin: 1.5959455978986625E-16 
Avg cos: 0.0 
Average: 90.0 

~> java Main 1 182 
Avg sin: -0.008723545132608694 
Avg cos: 2.2843406864775373E-4 
Average: -88.50000000000001 
関連する問題