私は方程式を持っています:
double center = self.Altitude * tan(Pitch);
高度 = 130
ピッチ = 90 度。この式では、1.570796 ラジアンに変換しました。
電卓を使って答えを得た: 397802904
プログラムは次のようになりました: -362461013356.731689
理由はありますか?
ありがとうございました!
私は方程式を持っています:
double center = self.Altitude * tan(Pitch);
高度 = 130
ピッチ = 90 度。この式では、1.570796 ラジアンに変換しました。
電卓を使って答えを得た: 397802904
プログラムは次のようになりました: -362461013356.731689
理由はありますか?
ありがとうございました!
バリアントの結果は、度からラジアンへの変換が適切に実行されずtan()
、期待される結果が得られなかったためです。「tan(PI/2) が未定義」の問題ではありません。ラジアンとタンジェント (xは90 度付近) の問題です。
90 度をラジアンに変換すると、報告どおり 1.570796 になりませんでした。代わりに、90 度をラジアンに変換すると、結果は1.570796近くになりました。1.570796 に変換したと考えた可能性が非常に高いです。これは、変換の 10 進表現を見たときに表示されたものだからです。その 10 進変換は、内部浮動小数点表現の丸め表現です。おそらく、あなたが持っていた値は 1.570796324 のようなものでした...その数値の正接は約 397802904 です。
度をラジアンに変換しようとするときは、 のようなものを使用しますdegrees*2*PI/360
。問題は、PI を正確に表すことができないため、変換結果がおおよそのものになることです。 tan(x)
はPI/2 のわずかな変動に非常に敏感であり、おそらくわずかに異なる PI の値を使用したり、関数がすべてわずかに異なるため、非常に異なる答えが得られます。
精度に関係なく、Pi を浮動小数点表記で正確に表すことはできないため、0tan(MACHINE_APPROXIMATE_PI/2)
にはなりません。
度を使用してより良い答えを得るには、ラジアンに変換する前に引数の範囲を度単位で縮小する必要があります。
// Only for 0 <= angle <= 90
double tan_degree(double angle) {
if (angle > 45) {
if (angle == 90) {
return INF;
}
angle = 90 - angle;
return 1/tan(angle*2*PI/360);
}
else {
return tan(angle*2*PI/360);
}
}
他の角度の tan_degree() を決定するには、同様の角度縮小が必要です。
sin_degree() と cos_degree() についても、同様の範囲縮小が必要です。