2016-03-18 1 views
0

等しくない場合、それははMATLAB内の2つの等しい浮動小数点数を減算すると、我々は2つの異なる方法で(A + B)を計算したいと0 ​​

  1. (A + B)*(ありますここでA + B)

  2. + 2 AB + B

a = 1.4b = -2.7とします。

a = 1.4; 
b = -2.7; 

format long 

r = (a + b) * (a + b) 

r2 = a^2 + 2*a*b + b^2 

abs_diff = abs(r - r2) 

私は

r = 1.690000000000001 

r2 = 1.690000000000001 

abs_diff = 6.661338147750939e-16 

はここで何が起こっているの入手:我々はformat longと数式でこれら2つの数値を差し込む場合は、私たちは、私は次のスクリプトを実行した場合、つまり、どちらの場合1.690000000000001で入手しますか? rまたはr2(Matlabは異なる浮動小数点演算を実行するため)異なる結果をプレビューできますが、その差の絶対値はプレビューできません。

また、私は

rel_err1 = abs(1.69 - r)/1.69 
rel_err2 = abs(1.69 - r2)/1.69 

をすれば、私は

rel_err1 = 3.941620205769786e-16 

rel_err2 = 7.883240411539573e-16 

これは私だけがrが実際にはないと思いますが入手rr2の相対誤差は、つまり、異なっていることに気づきました同じr2。彼らが本当に違うならば、完全に見える方法はありますか?そうでない場合、何が起こっていますか?

また、両方の相対エラーがeps/2より小さくない場合、これはオーバーフローが発生したことを意味しますか?はいの場合、どこですか?


注:これは特定のケースです。私は浮動小数点数と丸め誤差を扱っていることを理解しました。しかし、私は、この例を辿ることによって、より良いことを理解したいと思います。

+1

のためにそれは可能性があります浮動小数点エラーが発生するという事実操作の* order *、* type *、* number *にdsを指定します。あなたの2つのメソッドは異なる数と種類の操作を持っています。理論的には、浮動小数点エラーの数が増えています(http://floating-point-gui.de/errors/propagation/)。また、より多くの操作がエラーのより多くの伝播を引き起こします。 – Suever

+0

@Suever私の直感は、両方のメソッドが実際には異なる浮動小数点演算を使用して実装されているため、異なる結果が得られ、その差が0(とにかく)であることを説明します。しかし、Matlabは同様に 'r'と' r2'を同じように表現するので、それらの違いは0でなければなりません... – nbro

+0

MATLABが 'r'と' r2'を同じように表現していることをあなたのポストで示していますか? – Suever

答えて

1

Floating point arithmetic is not associative

数学的にはこれらの2つは等しいものの、浮動小数点演算ではありません。

r = (a + b) * (a + b) 

r2 = a^2 + 2*a*b + b^2 

順序演算は浮動小数点演算で実行され、非常に関係します。だから、浮動小数点演算を行うときには、乗算/除算の順序を非常に慎重にする必要があります。

+0

'r'と' r2'が明らかに同じ数でメモリに表現されていれば、それらの絶対値差異はゼロに等しくなります... – nbro

3

format longの出力を参考にして、2つの数値が等しいことを確認しないでください。

a = 1.4; 
b = -2.7 
r1 = (a + b) * (a + b); 
r2 = a^2 + 2*a*b + b^2; 
r3 = (a+b)^2; 

代わりに、使用して16進数表現を確認することができます。

>> num2hex([r1 r2 r3]) 
ans = 
3ffb0a3d70a3d70d 
3ffb0a3d70a3d710 
3ffb0a3d70a3d70d 

や機能のprintf家族:

>> fprintf('%bx\n', r1, r2, r3) 
3ffb0a3d70a3d70d 
3ffb0a3d70a3d710 
3ffb0a3d70a3d70d 

かさえ:

>> format hex 
>> disp([r1; r2; r3]) 
    3ffb0a3d70a3d70d 
    3ffb0a3d70a3d710 
    3ffb0a3d70a3d70d 
+0

fprintf( '%.60f'、my_float);のように、 'fprintf'を使って浮動小数点数を10進数で表示することはどうでしょうか? ? – nbro

+0

これは、実際の1と0が格納されているので、16進表記をより信頼しています。丸めには関係ありません。例えば、 'my_float = realmin'の場合、' fprintf'でどの位でしょうか? – Amro

関連する問題