14

C ++では、

const double Pi = 3.14159265;
cout << sin(Pi);                          // displays: 3.58979e-009

数字のゼロを表示する必要があります

これはPiが近似されているためだと理解していますが、sin(Pi)に対して0を返すPiの値をプログラムにハードコードする方法はありますか?(多分別の定数?)

私が何をしようとしているのか疑問に思っている場合:極座標を直交座標に変換しています。「0.00」として出力するために実行できるprintf()のトリックがいくつかありますが、それでも一貫して適切な値が返されません。値(場合によっては「-0.00」を取得します)

sinとcosineを必要とする行は次のとおりです。

x = r*sin(theta);
y = r*cos(theta);

ところで:私の長方形->極はうまく機能しています...それはただ極->長方形です

ありがとう!

編集: 私はsin(Piの倍数)をコンソールに適切な丸め数として出力できるようにするための回避策を探しています(理想的には1000のifステートメントなしで)

4

14 に答える 14

28

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと(編集:コメントにリンクされています)はかなり筋金入りの読書です(私はそれをすべて読んだとは言えません)が、それの核心はこれです:あなたは完全に正確な浮動小数点計算を取得することはできません。記事から:

無限に多くの実数を有限のビット数に圧縮するには、近似表現が必要です。

プログラムが浮動小数点計算の正確な結果に依存しないようにしてください。常に許容範囲を許可してください。参考までに3.58979e-009は約0.0000000036です。これは、選択した妥当な許容範囲内に十分収まります。

于 2010-04-19T21:26:37.580 に答える
15

このように言えば、値3.58979e-009が実際の Pi に近いほど 0 に近くなります。3.14159265あなたが得たものは、技術的には、あなたが求めたものです。:)

ここで、有効数字 9 桁 (小数点以下 8 桁) のみを入力する場合は、出力にそれ以上表示しないように指示します。つまり、次のように使用します。

cout.precision(8);
cout << sin(Pi);
于 2010-04-19T21:31:05.933 に答える
4

これはゼロを表示するはずです:

cout << fixed << sin(Pi);

(何かを丸めようとする必要はないと思います。表示が心配な場合は、値自体ではなく、表示関数を処理してください。)

于 2010-04-19T22:10:09.573 に答える
4

<cmath>ほとんどまたは<math.h>実装で利用可能な M_PI を試しましたか?

それでも、この方法で浮動小数点を使用すると、常にある程度のエラーが発生します。

于 2010-04-19T21:32:26.367 に答える
4

等値演算子に十分な許容誤差がある場合、ゼロに等しい

于 2010-04-19T21:27:49.007 に答える
3

3.58979e-009これは0,0000000358979です

あなたの~~PIのような~~0です。

于 2010-04-19T21:26:13.957 に答える
2

より良い結果を得るために、さらにいくつかの数字を投入することもできます (たとえば、3.1415926535897932384626433832795029L を試してください) が、それでも丸めエラーが発生します。

それでも、既知の Pi 値に対してチェックし、そのような場合に正確にゼロを返す独自のバージョンをsin作成できます。cos

namespace TrigExt
{
    const double PI = 3.14159265358979323846;

    inline double sin(double theta)
    {
        return theta==PI?(0.0):(std::sin(theta));
    }
}

このことを他の三角関数に拡張し、Pi の倍数を処理することもできます。

于 2010-04-19T21:33:39.707 に答える
1

小さなラッパー関数を書くことができます:

double mysin(const double d) {
    double ret = sin(d);
    if(fabs(ret) < 0.0000001) {
        return 0.0;
    } else {
        return ret;
    }
}

他の人が指摘しているように、浮動小数点演算は不正確であることで知られています。何かを正確にゼロに見せたい場合は、ある種の許容範囲が必要です。

于 2010-04-19T21:30:35.387 に答える
1

必要な桁数を強制しないのはなぜですか

 int isin = (int)(sin(val) * 1000);
 cout << (isin/1000.0)
于 2010-04-19T21:31:38.333 に答える
1

sin(PI) は、PI の正確な値に対して 0 に等しくなければなりません。PI の正確な値を入力していません。他の人が指摘しているように、小数点以下 7 桁に丸められた結果は 0 であり、これは概算にはかなり適しています。

別の動作が必要な場合は、独自の正弦関数を作成する必要があります。

于 2010-04-19T21:31:51.823 に答える
0

数学演算で float または double を使用すると、正確な結果が得られません。その理由は、コンピューターではすべてが 2 のべき乗として格納されるためです。これは、正確には 10 進数システムに変換されません。(例として、0.1 の基数 2 での表現はありません)

さらに、float と double は、少なくとも一部のコンパイラとプラットフォームでは 64 ビットです。(私は思う-必要に応じて誰かが私を修正してください)。これにより、非常に大きな値または非常に小さな値 (0.0000000000xxx) の丸め誤差が発生します。

正確な結果を得るには、大きな整数ライブラリが必要になります。

上記の質問へのコメントに書かれているように、サイトを参照してください... http://docs.sun.com/source/806-3568/ncg_goldberg.html

于 2010-04-19T21:32:20.883 に答える
0
double cut(double value, double cutoff=1e-7) {
  return (abs(value) > cutoff)*value;
}

これにより、しきい値を下回る値がゼロになります。次のように使用しますcut(sin(Pi))

于 2010-04-19T21:59:53.983 に答える
-1

もっと重要な数字が役立つかもしれません。私の C コンパイラ (gcc) は、3.14159265358979323846"math.h" で M_PI の定数を使用します。それ以外には、多くのオプションはありません。回答を検証する独自の関数を作成すること (質問に対する別の回答で説明されているように) は、おそらく最良のアイデアです。

于 2010-04-19T21:30:28.323 に答える
-1

ご存知のように、数学的な正確さのために、sin(3.14159265)ゼロではありません。ほぼゼロです。これはまさにプログラムが伝えていることです。計算では、この数値で良い結果が得られるはずです。表示するのは面倒なので、フロートを印刷するときは必ず数値をフォーマットしてください。

ここでの作業にフロートの仕組みがあるとは本当に思いません...単純な計算です。

ただし、コードについては注意してください...表示の前に近似を行うことでコードが間違った結果を出すことはありません。情報を正しい方法で表示するだけです。

于 2010-04-19T21:55:43.910 に答える