10

C++ および Matlab で記述されたアルゴリズムで同等性テストを作成しようとしています。このアルゴリズムにはある種の時間ループが含まれており、1000 回以上実行されます。算術演算といくつかの数学関数があります。

初期入力を両方のプラットフォームに手動で供給します (a=1.767、b=6.65 など)。これらの入力の 16 進表現を確認すると、それらは同じです。したがって、入力には問題ありません。そして、10 進数 16 桁のテキスト ファイルで c++ の出力を matlab に取得します。(私は「setprecision(32)」ステートメントを使用します)

しかし、ここで問題が発生します。両方のコードの 614 番目のステップの後、すべての結果はまったく同じですが、615 のステップでは 2.xxx..xxe-19 について違いがありますか? そして、このステップの後、誤差はますます大きくなり、実行の最後には約 5.xx..xxe-14 になります。

0x3ff1 3e42 a211 6cca--->[C++ 関数]--->0x3ff4 7619 7005 5a42

0x3ff1 3e42 a211 6cca--->[MATLAB 関数]--->ans

ans - 0x3ff4 7619 7005 5a42

= 2.xxx..xxe-19

matlab が数値をどのように扱うかを調べたところ、「非正規化仮数」のような非常に興味深いものが見つかりました。realmin は約 e-308 ですが、仮数部を非正規化することにより、matlab は e-324 について最小の実数になります。さらに、matlab は "pi" または "exp(1)" の桁数を c++ よりも多く保持します。

一方、matlab のヘルプには、表示される形式が何であれ、matlab は内部で倍精度を使用すると書かれています。

だから、誰かがこれらの違いの正確な理由を説明してくれたら本当にありがたいです? matlab と c++ で同等性テストを行うにはどうすればよいですか?

4

3 に答える 3

11

x86 CPU には、浮動小数点数に関して 1 つのことがあります。内部的には、浮動小数点ユニットは 10 バイト、つまり 80 ビットのレジスタを使用します。さらに、CPU には、浮動小数点計算を 32 ビット ( float)、64 ビット ( double)、または 80 ビットの精度で行うかどうかを示す設定があります。精度が低いということは、実行される浮動小数点演算が高速であることを意味します。(32 ビット モードは、以前は速度が精度を優先するビデオ ゲームで一般的でした)。

このことから、テスト C++ 実行可能ファイルから開始された場合でも、MatLab から開始された場合でも、同じ入力が与えられた場合に同じ結果が得られないという計算ライブラリ (dll) のバグを追跡したことを覚えています。さらに、これはデバッグ モードでは発生しませんでした。 、リリースのみ!

最終的な結論は、MatLab が CPU 浮動小数点精度を 80 ビットに設定したのに対し、テスト実行可能ファイルはそうしなかった (そしてデフォルトの 64 ビット精度のままにした) というものでした。さらに、この計算の不一致はデバッグ モードでは発生しませんでした。これは、すべての変数がメモリに 64 ビット変数に書き込まれdouble、その後そこから再ロードされ、追加の 16 ビットが無効になるためです。リリース モードでは、一部の変数が最適化され (メモリに書き込まれず)、すべての計算が浮動小数点レジスタのみを使用して 80 ビットで実行され、追加の 16 ビットはゼロ以外の値が維持されました。

これが役立つかどうかはわかりませんが、知っておく価値があるかもしれません。

于 2012-06-22T07:47:23.210 に答える
4

以前にも同様の議論があり、 IEEE 754は超越関数(cos、sin、expなど)の最後のビットのエラーを許容するという結論に達しました。したがって、MATLABとCの間でまったく同じ結果を期待することはできません(異なるコンパイラでコンパイルされた同じCコードでさえも)。

于 2012-06-23T05:18:35.070 に答える
0

私はここで軌道に乗っていない可能性があり、すでにこの可能性を調査している可能性がありますが、言及した数学ライブラリ関数 (sin() cos() および exp() の方法で C++ と Matlab の間に違いがある可能性があります。 ) は内部的に実装されています。最終的に、何らかの関数近似を使用して関数値を生成する必要があり、これらの方法に何らかの違いがある場合、おそらく、これが多数の反復で数値の丸め誤差の形で現れる可能性があります。

この質問は基本的に私が提案しようとしていることをカバーしています

于 2012-06-22T21:12:53.053 に答える