`std :: sin`は最後のビットで間違っています

ホセD。

効率を上げるために、いくつかのプログラムをMatlabからC ++に移植しています。両方のプログラムの出力が完全に同じであることが重要です(**)。

この操作で異なる結果に直面しています。

std::sin(0.497418836818383950)   = 0.477158760259608410 (C++)
sin(0.497418836818383950)        = 0.47715876025960846000 (Matlab)
N[Sin[0.497418836818383950], 20] = 0.477158760259608433 (Mathematica)

したがって、私が知る限り、C ++とMatlabの両方がIEEE754で定義された二重演算を使用しています。IEEE754では最後のビットで異なる結果が許可されていることをどこかで読んだと思います。数学を使って決定するのは、C ++の方が結果に近いようです。結果が同じになるように、Matlabに含まれる最後のビットまで正確にsinを計算させるにはどうすればよいですか?

私のプログラムでは、数値微分方程式ソルバーが最後のビットでこのエラーを増やし続けるため、この動作は大きなエラーにつながります。ただし、C ++で移植されたバージョンが正しいかどうかはわかりません。IEEE754で最後のビットの変更が許可さている場合でも、 IEEE754で定義されたdouble操作の結果を使用したときに、このエラーが大きくならないことが保証されていると思います(そうでない場合、IEEE754標準に従って正しい2つの異なるプログラムが生成される可能性があるため)完全に異なる出力)。だから他の質問はこれについて正しいですか?

両方の太字の質問に対する回答を取得したいと思います。編集:最初の質問はかなり物議を醸していますが、それほど重要ではありません、誰かが2番目の質問についてコメントできますか?

注:これは印刷のエラーではありません。確認したい場合に備えて、次のようにしてこれらの結果を取得しました。

http://i.imgur.com/cy5ToYy.png

注(**):これが意味するのは、小数点以下4桁の実数を示すいくつかの計算の結果である最終出力は、完全に同じである必要があるということです。私が質問で話しているエラーは大きくなります(操作が増えるため、MatlabとC ++ではそれぞれが異なります)ので、最終的な違いは非常に大きくなります)(違いがどのように大きくなり始めるかを知りたい場合は、ここにあります完全な出力です[すぐにリンク]が、これは質問とは関係ありません)

サイモン・バーン

まず、数値計算法が最後のビットまでのsinの精度に依存している場合は、MPFRなどの任意精度のライブラリを使用する必要があります。

IEEE754 2008標準では、関数を正しく丸める必要はありません(ただし、「推奨」しています)。一部のClibmは、正しく丸められた三角関数を提供します。CRlibmと同様に、glibc libmは(通常、ほとんどのLinuxディストリビューションで使用されます)提供すると思います。他のほとんどの最新のlibmsは、1 ulp以内の三角関数(つまり、真の値の両側にある2つの浮動小数点値の1つ)を提供します。これは、忠実に丸められたと呼ばれることが多く、計算がはるかに高速です。

印刷したこれらの値はいずれも、IEEE 64ビット浮動小数点値として実際に発生することはありません(丸められている場合でも)。最も近い3つ(完全な精度で印刷)は次のとおりです。

0.477158760259608 405451814405751065351068973541259765625

0.477158760259608 46096296563700889237225055694580078125

0.477158760259608 516474116868266719393432140350341796875

必要な値は次のとおりです。

  1. 小数の正確な罪.497418836818383950、つまり

0.477158760259608 433132061388630377105954125778369485736356219 .. ..

(これはMathematicaが与えるもののようです)。

  1. .497418836818383950に最も近い64ビット浮動小数点数の正確なsin:

0.477158760259608 430531153841011107415427334794384396325832953 .. ..

どちらの場合も、上記のリストの最初のものが最も近いです(ただし、1の場合はほとんどありません)。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

std :: vectorの最初の要素の値が間違っています

分類Dev

std :: is_trivially_copyableは間違っていますか?

分類Dev

間違った入力の後にstd :: cin.clear()を設定してstd :: cinを使用できないのはなぜですか?

分類Dev

`std :: string str(nullptr)`と `std :: string str = nullptr`が間違っているのはなぜですか?誰かが理由を詳細に説明できますか?

分類Dev

Valgrindを使用したlongdoubleのstd :: fpclassifyの結果が間違っています

分類Dev

std :: includeのバグですか、それとも何か間違ったことをしていますか?

分類Dev

整数配列で、stoulを使用したstd :: stringの出力が間違っています

分類Dev

C ++ std :: tmは、std :: chrono :: time_pointから変換した後、間違った値を返します

分類Dev

Visual C ++とgccの間でstd :: isblankからの一貫性のない戻り値。どちらが間違っていますか?

分類Dev

std :: mapの反復が最初の実行で間違ってしまう

分類Dev

const関数を介してstd :: vector要素のアドレスを返すのが間違っているのはなぜですか?

分類Dev

std :: arrayとstd :: vectorの違いは何ですか?いつ使用しますか?

分類Dev

Windowsでstd :: stringへのファイルの読み取りの長さが間違っているのはなぜですか?

分類Dev

std :: mapは間違った要素を消去します

分類Dev

標準コンテナでstd :: auto_ptr <>を使用するのはなぜ間違っているのですか?

分類Dev

標準コンテナでstd :: auto_ptr <>を使用するのはなぜ間違っているのですか?

分類Dev

std :: transformとstd :: for_eachの違いは何ですか?

分類Dev

std :: moveとstd :: forwardの違いは何ですか

分類Dev

-std = c ++ 11と-std = gnu ++ 11の違いは何ですか?

分類Dev

std :: functionとstd :: mem_fnの違いは何ですか

分類Dev

std :: coutとstd :: wcoutの違いは何ですか?

分類Dev

std :: invokeとstd :: functionの違いは何ですか?

分類Dev

:: std :: stringとstd :: stringの違いは何ですか?

分類Dev

std :: invokeとstd :: applyの違いは何ですか?

分類Dev

std :: tieとstd :: forward_as_tupleの違いは何ですか

分類Dev

std :: codecvtとstd :: codecvt_utf8の違いは何ですか

分類Dev

std :: ranges :: beginとstd :: beginの違いは何ですか?

分類Dev

std :: enable_ifとstd :: enable_if_tの違いは何ですか?

分類Dev

std :: atoi()とstd :: stoiの違いは何ですか?

Related 関連記事

  1. 1

    std :: vectorの最初の要素の値が間違っています

  2. 2

    std :: is_trivially_copyableは間違っていますか?

  3. 3

    間違った入力の後にstd :: cin.clear()を設定してstd :: cinを使用できないのはなぜですか?

  4. 4

    `std :: string str(nullptr)`と `std :: string str = nullptr`が間違っているのはなぜですか?誰かが理由を詳細に説明できますか?

  5. 5

    Valgrindを使用したlongdoubleのstd :: fpclassifyの結果が間違っています

  6. 6

    std :: includeのバグですか、それとも何か間違ったことをしていますか?

  7. 7

    整数配列で、stoulを使用したstd :: stringの出力が間違っています

  8. 8

    C ++ std :: tmは、std :: chrono :: time_pointから変換した後、間違った値を返します

  9. 9

    Visual C ++とgccの間でstd :: isblankからの一貫性のない戻り値。どちらが間違っていますか?

  10. 10

    std :: mapの反復が最初の実行で間違ってしまう

  11. 11

    const関数を介してstd :: vector要素のアドレスを返すのが間違っているのはなぜですか?

  12. 12

    std :: arrayとstd :: vectorの違いは何ですか?いつ使用しますか?

  13. 13

    Windowsでstd :: stringへのファイルの読み取りの長さが間違っているのはなぜですか?

  14. 14

    std :: mapは間違った要素を消去します

  15. 15

    標準コンテナでstd :: auto_ptr <>を使用するのはなぜ間違っているのですか?

  16. 16

    標準コンテナでstd :: auto_ptr <>を使用するのはなぜ間違っているのですか?

  17. 17

    std :: transformとstd :: for_eachの違いは何ですか?

  18. 18

    std :: moveとstd :: forwardの違いは何ですか

  19. 19

    -std = c ++ 11と-std = gnu ++ 11の違いは何ですか?

  20. 20

    std :: functionとstd :: mem_fnの違いは何ですか

  21. 21

    std :: coutとstd :: wcoutの違いは何ですか?

  22. 22

    std :: invokeとstd :: functionの違いは何ですか?

  23. 23

    :: std :: stringとstd :: stringの違いは何ですか?

  24. 24

    std :: invokeとstd :: applyの違いは何ですか?

  25. 25

    std :: tieとstd :: forward_as_tupleの違いは何ですか

  26. 26

    std :: codecvtとstd :: codecvt_utf8の違いは何ですか

  27. 27

    std :: ranges :: beginとstd :: beginの違いは何ですか?

  28. 28

    std :: enable_ifとstd :: enable_if_tの違いは何ですか?

  29. 29

    std :: atoi()とstd :: stoiの違いは何ですか?

ホットタグ

アーカイブ