PI/2を浮動小数点で正確に表すことはできないので、cos(a)は決して正確なゼロを返すことはできません。浮動小数点でcos(a)が0になることはありません
このような場合は、次の擬似コードは、ブロックに入ることはありません(それが安全に除去することができる):
...
y = h/cos(a);
if (!isfinite(a))
{
// handle infinite y
}
PI/2を浮動小数点で正確に表すことはできないので、cos(a)は決して正確なゼロを返すことはできません。浮動小数点でcos(a)が0になることはありません
このような場合は、次の擬似コードは、ブロックに入ることはありません(それが安全に除去することができる):
...
y = h/cos(a);
if (!isfinite(a))
{
// handle infinite y
}
ゼロは、正確に表現できるいくつかの値の1つです。多くのシステムではsinとcosの共通の値のルックアップテーブルがあるため、正確にゼロを返すことはできません。
しかし、あなたは、デルタを使用して安全ですが、分割を行う前に、比較する:
ゼロ以外if (Abs(cos(a)) < 0.0000001)
{
}
「複数」のうちの1つですか?私は(2^64 - 2^53)に "いくつかの"という言葉を使うとは思わない。 –
1/2、1/4、1/8、..... –
すべての有限浮動小数点値は浮動小数点で正確に表現できます(衝撃的です、私は知っています)。 1/2、1/4だけでなく、0.333333333333333314829616256247390992939472198486328125および3.141592653589790007373494518105871975421905517578125も同様です。 –
cos
がで計算そのものであるので、いや、これは、保証することはできませんエラーですので、その値はかなり正確にゼロになります。
、π/ 2の倍数に最も接近する倍精度値は6381956970095103 * 2^797であります、に等しい。したがって、すべての倍精度値xについて、我々は結合した
(an odd integer) * π/2 + 2.983942503748063...e−19
:
|cos(x)| >= cos(2.983942503748063...e−19)
これは、ライブラリ関数cos
によって返された値ではなく、数学的に正確な値の境界であることに注意してください。良質な数学ライブラリを備えたプラットフォームでは、この境界は十分に良いので、cos(x)
は倍精度x
でゼロではないと言うことができます。実際には、これは二重にユニークではないことが判明しました。 cos
が忠実に丸められている場合、このプロパティはすべてのIEEE-754基本タイプに適用されます。
しかし、これは、三角関数の引数削減が劇的に実装されていないプラットフォームでは起こり得ないとは限りません。
#include <math.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
double a = 0x1.6ac5b262ca1ffp+849;
double h = 0x1.0p1022;
printf("cos(a) = %g\n", cos(a));
printf("h/cos(a) = %g\n", h/cos(a));
return 0;
}
コンパイルおよび実行します:
scanon$ clang example.c && ./a.out
cos(a) = -4.68717e-19
h/cos(a) = -inf
私はこれに正確に答えたいと思っていました。そして、それの横に、0.0000001のような許容値が完全に恣意的に聞こえる理由を手がかりにしています。オーバーフロー保護は、if(abs(cos(x))<1);)のようなものでなければなりません。 –
を時々システムがそれを強制するかもしれない
は、さらに重要なのは、それはあなたの例では
y
がゼロであることcos(a)
なし無限できることに注意することが重要です'a'がaproxのときはゼロです。 'pi/2'に等しい。 – ja72