ホームページ >ウェブフロントエンド >jsチュートリアル >js が 10 進数の演算を正しく処理できないのはなぜですか? _JavaScript スキル
var sum = 0; for(var i = 0; i < 10; i++) { sum += 0.1; } console.log(sum);
上記のプログラムは1を出力しますか?
記事 知っておくべき 25 の JavaScript 面接の質問 の 8 番目の質問では、js が 10 進演算を正しく処理できない理由が簡単に説明されています。今日は古いトピックを再訪し、この問題をより深く分析します。
しかし、まず第一に、10 進演算を正しく処理できないのは JavaScript 言語自体の設計ミスではないことに注意してください。C や Java などの他の高水準プログラミング言語も同様です。小数演算を正しく処理するには:
#include <stdio.h> void main(){ float sum; int i; sum = 0; for(i = 0; i < 100; i++) { sum += 0.1; } printf('%f\n', sum); //10.000002 }
コンピュータ内の数値の表現
高級プログラミング言語で書かれたプログラムは、実行する前に解釈、コンパイル、その他の操作を通じて CPU (中央処理装置) が認識できる機械語に変換する必要があることは誰もが知っています。 CPU は 8 進数や 16 進数などの 10 進数や 10 進数を認識しないため、プログラム内で宣言したこれらの基数は計算のために 2 進数に変換されます。
3進数に変換して計算してみませんか?
コンピューターの内部は、IC (Integrated Circuit: 集積回路) などの多くの電子部品で構成されており、次のようになります。
IC にはさまざまな形状があり、多くのピンが両面または内部に並んでいます (図では片面のみを示しています)。 IC のすべてのピンには DC 電圧 0V または 5V の 2 つの状態しかありません。つまり、1 つの IC ピンは 2 つの状態しか表現できません。この IC の特性により、コンピュータ内のデータは 2 進数でのみ処理できることが決まります。
1 ビット (1 つのピン) は 2 つの状態しか表現できないため、2 進数の計算方法は 0、1、10、11、100... この形式になります:
したがって、数値演算では、すべてのオペランドは演算に参加するために 2 進数に変換されます (例: 39 は 2 進数 00100111 に変換されます)
小数の 2 進数表現
上記のように、プログラム内のデータは 2 進数に変換されます。たとえば、10 進数の 11.1875 は 1101.0010 に変換されます。
2進数の小数点以下4桁で表される数値範囲は0.0000~0.1111なので、4つの10進数0.5、0.25、0.125、0.0625とその後のビット重みの組み合わせ(加算)しか表現できません。小数点:
上の表からわかるように、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…(无限循环)
倍精度浮動小数点数の小数部は最大 52 桁をサポートするため、この 2 つを加算すると、0.0100110011001100110011001100110011001100 という文字列が得られます。小数点以下の制限により切り捨てられる 2 進数です。このとき浮動小数点数を10進数に変換すると、0.30000000000000004となります。
概要js は、他の高級プログラミング言語を含め、10 進数の演算を正しく処理できません。これは言語自体の設計ミスではありませんが、コンピューター自体が 10 進数の演算を正しく処理できないことが多いためです。小数は 2 進数で表現できます。
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。