jsはなぜ小数を正確に処理できないですか?

3845 ワード

まず次の手順を見てください。
var sum = 0;
for(var i = 0; i < 10; i++) {
  sum += 0.1;
}

console.log(sum);
上のプログラムは1を出力しますか?
あなたが知る必要がある25のJavaScriptの面接問題の中で、8番目の問題は簡単にJsがなぜ小数点以下の計算を正確に処理できないのかと言いました。今日は古い問題を拾って、もっと深いレベルでこの問題を分析します。
先に説明するのは、小数点以下の演算を正しく処理できないのはJavaScript言語自体の設計ミスではなく、他の高級プログラミング言語、例えばC、Javaなども、小数点以下の演算を正確に処理することができません。
#include 

void main(){
    float sum;
    int i;

    sum = 0;

    for(i = 0;  i < 100; i++) {
        sum += 0.1;
    }

    printf('%f
'
, sum); //10.000002 }
コンピューター内部の表示
高度なプログラミング言語で作成したプログラムは、解釈、コンパイルなどの操作を経てCPU(Central Processing Unit)で認識できるマシン言語に変換して実行する必要がありますが、CPUにとっては10進数、8進数、16進数などは認識されていません。
なぜ三進数に変換して計算しないですか?
コンピュータ内部は多くのIC(Integrated Circurit:集積回路)という電子部品で構成されています。
ICにはいくつかの形状があり、その両側や内部には多くのピンが並べられています。ICのすべてのピンは、直流電圧0 Vまたは5 Vの2つの状態、つまりICピンは2つの状態しか表しません。ICのこの特性はコンピュータ内部のデータはバイナリでしか処理できないことを決定しました。
1ビットは2つの状態しか表現できないので、バイナリの計算方式は0、1、10、11、100…となります。
したがって、数の演算では、すべての動作数は、39のようにバイナリ数参加演算に変換されます。バイナリ0011に変換されます。
小数のバイナリ表現
前に述べたように、プログラム中のデータはいずれもバイナリ数に変換され、小数で演算に参加する場合は、10進数の11.1875のように、2進数に変換されます。1101.0010に変換されます。
小数点以下の4桁をバイナリで表した数値範囲は0.0000~0.1111です。したがって、0.5、0.25、0.25、0.0625の4つの10進数と小数点以下のビット権の組み合わせ(加算)を表している小数点のみです。
バイナリ数
対応する十進数
0.0000
0
0.0001
0.0625
0.0010
0.25
0.0011
0.1855
0.0100
0.25
0.1,000
0.5
0.1001
0.625
0.010
0.65
0.1011
0.6865
0.111
0.9375
上の表からは、10進数0の次の桁は0.0625であることが分かります。したがって、0から0.0625の間の小数は、小数点以下の4桁の2進数では表現できません。二進数小数点以下の桁数を増やすと、それに対応する十進数の個数も増加しますが、何桁を増やしても0.1は得られません。実際には、0.1をバイナリに変換することは0.00110011001100110011……であり、0011は無限の反復である。
console.log(0.2+0.1);

//         
0.1 => 0.0001 1001 1001 1001…(    )
0.2 => 0.0011 0011 0011 0011…(    )
jsのNumberタイプは、C/Javaのように整型、単精度、二重精度などではなく、二重精度浮動小数点型として統一的に表現されています。IEEEの規定により、シングル精度浮動小数点数は32ビットで全体小数を表し、ダブル精度浮動小数点は64ビットで全体小数を表し、浮動小数点は符号、端数、指数、基数からなるので、すべての桁数が小数を表すのではなく、符号、指数なども桁数を占め、基数は桁を占めない:
ダブル精度浮動小数部は最大52桁まで対応していますので、このように0.010011001100110011001001100の一列を加算します。浮動小数点数位の制限で切り捨てられたバイナリ数です。この時、10進数に変換すると、0.3000万0004になります。
締め括りをつける
jsは小数点以下の演算を正確に処理できません。他の高級プログラミング言語を含むように、言語自体の設計ミスではなく、コンピュータ内部自体が小数点以下の演算を正確に処理することができません。
参照
『プログラムはどうやって走りますか?』
原文の出所:http://www.ido321.com/1661.html