1

まず、以下のコードが表示されます。

result = 0.1 + 0.2;     
alert(result===0.3);// false
result=100.1+100.2;
alert(result===200.3);//true

0.1100.1(100 + 0.1)は両方に小数が含まれているため、同様にメモリに格納されると思い.1ます。

では、なぜ加算の結果が異なるのでしょうか。

4

3 に答える 3

6

それらはメモリに同じように保存されません:http ://steve.hollasch.net/cgindex/coding/ieeefloat.html

バイナリで0.1:

0.1 * 2 = 0 + 0.2
0.2 * 2 = 0 + 0.4
0.4 * 2 = 0 + 0.8
0.8 * 2 = 1 + 0.6
0.6 * 2 = 1 + 0.2
0.2 * 2 = 0 + 0.4
0.4 * 2 = 0 + 0.8
0.8 * 2 = 1 + 0.6
0.6 * 2 = 1 + 0.2

ご覧のとおり、0.2が繰り返された後、パターン全体(0011)は繰り返され続け0.1ます0.0001100110011001100110011..。永遠に繰り返す

これを表すには、23ビットの仮数で、小数点の前に1が来るまで左にシフトし(ビットを左に4桁シフトし、小数点の前の1を削除した100110011...後)、23番目のビットで丸める必要があります。取得します:10011001100110011001101

4桁シフトしたので、指数は127-4(127は32ビットバイアスです)です。バイナリの8ビットの123は01111011、残りは符号ビットだけです。0.1は正の数であるため、これは0であることがわかります。したがって、32ビットの2進数の各コンポーネントは次のとおりです。

符号:0
指数:01111011
仮数:10011001100110011001101

0.1は00111101110011001100110011001101浮動小数点数で表されます。

逆変換すると、それを分解してから、指数を10進整数(123)に変換し直す必要があります。仮数(前に1を想定)を右(127-123 = 4)回シフトし、次の値を取得します。0.00011001100110011001101101次に、これを10進数に変換し直します。

0*1/2 + 0*1/4 + 0*1/8 + 1/16 + 1/32 + 0*1/64 + 0*1/128 + 1/256 + 1/512 + 
0 + 1/4096 + 1/8192 + 0 + 1/65536 + 1/131072 + 0 + 1/1048576 + 1/2097152 + 
0 + 1/16777216 + 1/33554432 + 0 + 1/134217728

これを計算すると、0.1よりも0.100000001に近いものが得られます。これは、23ビットで丸めたためです。0.1は永久に繰り返されるため、バイナリで保存することはできません。そのため、23ビット目以降は不正確になります。数値に対して算術演算を行うと、これらの不正確さが実行され、エラーがはるかに大きくなる可能性があります。

100.1で同じことを行うと、次のようになります。

1100100.0001100110011001100 ...永遠に繰り返す:

右に6回シフトし、小数点の前の1を23ビットに削除します:10010000011001100110011

指数は127+6 = 133(1000 0101)

符号は再び0なので、次のようになります。

01000010110010000011001100110011
于 2012-04-10T05:02:36.653 に答える
0

ポールPROの答えに加えて

これは、JavaScriptだけでは問題になりません。C#では、doubleは同じ動作を示します

double a = 0.1, b = 0.2;
Console.WriteLine((a + b)==0.3); //Prints False

したがって、精度を上げるために、c#では10進数を使用することをお勧めします。javascriptの場合、通貨操作を操作するには.toFixedを使用する必要があります。javascriptの数値の詳細については、 http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference#quickIDX0をご覧ください。

于 2012-04-10T05:20:42.227 に答える
0

これは、IEEE754ウィキペディアの実装結果です。すべての浮動小数点数を表示する方法はありません。IEEE754標準に準拠したすべての言語で表示されます。このコードスニペットは、どの言語でも同じ結果になります。

var sum = 0.0;
for (var i = 0; i < 10; i++ )
{
    sum += 0.1;
}
// sum = 0.9999999999999999

0.1は、ウィキペディアを正確に表していない数値の1つです。

C#には、内部的に構造である財務および金銭の計算に適した特別なタイプのDecimalMSDNがあります

于 2012-04-10T05:59:16.407 に答える