私の Matlab バージョンは R2012a です
なぜ Matlab で 1.1-0.2 は 0.9 に等しくないのですか!!!!!?
これはひどいです!
>>1.1-0.2 == 0.9
ans =
0
私の Matlab バージョンは R2012a です
なぜ Matlab で 1.1-0.2 は 0.9 に等しくないのですか!!!!!?
これはひどいです!
>>1.1-0.2 == 0.9
ans =
0
これは Matlab の問題ではありません。これは浮動小数点の問題です。C++ (またはIEEE754に準拠する任意のプログラミング言語) でも同じ結果が得られます。
#include <iostream>
int main(int, char **) {
std::cout << (1.1-0.2==0.9) << std::endl;
return 0;
}
出力:
0
これは、1.1 と 0.9を 2 進数で正確に表すことができないためです。1/3 を 10 進数で表すようなものです。次のように書く必要があります。
0.33333333333333333333333333333333333333333333333...
そして無期限に続けます。しかし、いくら続けても、うまくいくことはありません。
浮動小数点では、保存できる桁数が非常に多いため、計算はどこかで停止する必要があります。実際に計算した結果は
>> 1.1-0.2
ans =
9.000000000000001e-01
これはかなり近いですが、正確ではありません。
==
このため、 を使用して 2 つの浮動小数点数を比較する前に、常によく考える必要があります。==
今遭遇したような「奇妙な」結果なしに演算子を適用できることはめったにありません。
次のような丸め固有の許容範囲を使用することをお勧めします。
abs(1.1-0.2 - 0.9) <= eps(0.9)
ここで、特定の double 値の double間の間隔eps
を返す Matlab 関数です。しかし実際には、これは万能のソリューションではありません。浮動小数点を正しく比較するのは難しい作業です。
http://matlab.wikia.com/wiki/FAQ#Why_is_0.3-0.2-0.1_not_equal_to_zero_.28or_similar.29.3F
「0.3 - 0.2 - 0.1 (または同様の値) がゼロに等しくないのはなぜですか?」までスクロールします。
「一部の浮動小数点数は、バイナリ形式で正確に表すことができません....2 つの浮動小数点数を比較しようとしている場合は、== を使用してそうすることに非常に注意してください。別の比較方法は、比較している 2 つの数値は「十分に近い」
何が起こっているかを確認するためにこれらの種類のものに使用するのに適した関数はnum2strexact
、ファイル交換からのものです
num2strexact(1.1-0.2)
0.9000000000000001332267629550187848508358001708984375
num2strexact(0.9)
0.90000000000000002220446049250313080847263336181640625
ほら、彼らは同じではありません。
doubleとsymsを使用する場合の違いを見てください
num2strexact((1.1-0.2)-0.9)
1.1102230246251565404236316680908203125e-16
sym('(1.1-0.2)-0.9')
1.8367099231598242312011508394098e-40