ホームページ > 記事 > ウェブフロントエンド > JavaScriptの計算精度に関する豆知識(まとめ)
この章では、JavaScript の計算精度に関する小さな知識 (概要) を紹介し、2 進数と 10 進数の間の変換方法、JavaScript が数値を保存する方法、JavaScript が数値を読み取る方法を理解できるようにし、最後に例を示して説明します。 JavaScript は精度の問題による計算エラーを解決しますか?困っている友人は参考にしていただければ幸いです。
1. 前提知識のポイント
1. 10 進数を 2 進数に変換するにはどうすればよいですか?
整数部分を 2 で割って、商が 0 になるまでを求めます。小数部分を 2 倍して、積の小数部分が 0 になるまで順番に並べます。必要な精度が達成されています。
8转为二进制是多少? 8 / 2 = 4...0 取0 4 / 2 = 2...0 取0 2 / 2 = 1...0 取0 1 / 2 = 0...1 取1 二进制结果为:1000 0.25转为二进制是多少? 0.25 * 2 = 0.50 取0 0.50 * 2 = 1.00 取1 二进制结果为:01 于是可得出8.25的二进制表示:1000.01
2. 2 進数を 10 進数に変換するにはどうすればよいですか?
注: 2 進数から 10 進数への変換では、整数部分と小数部分は分離されません。
二进制1000.01转为十进制 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 0 * 2^0 + 0 * 2^-1 + 0 * 2^-2 = 8.25
2. JavaScript は数値をどのように保存しますか?
JavaScript の数値は、 IEEE 754 標準。
sign ビット (符号): 正と負の符号を表すために使用される 1 ビット (0 は正を意味し、1 は負を意味します)
exponent(指数): べき乗を表すために使用され、11 桁
#mantissa (仮数): 精度を表すために使用され、52 桁
#まず、指数部の 2 進数 1000000001 を取得し、それを 10 進数の 1027 に変換します。1027 から 1023 を引いたものが実際の指数 4 です。
仮数部 0000100000000000000000000000000000000000000000000 を取得します。実際の値は 0.00001 (次の 0 は書き込まれません) で、無視した 1 を追加して 1.00001 を取得します。最初の桁は 0 なので、この数値は正の数であるため、2 進数の科学表記法は 1.00001 * 2^4 となり、10 進数に変換すると、##IV. JavaScript の精度の問題を 0.1 0.2 から見てみる
ここで本題に入ります。前の原理の説明を理解すると、この部分は簡単になります。理解する。 。
0.1 は 64 ビットの 2 進浮動小数点数として保存されます。上記の手順は?
まず、0.1 をバイナリに変換します。整数部分は 0、小数部分は次のようになります: 0001100110011001100110011001100110011... おい、ここに無限ループがある。どうすればよいかする?今は無視してください。#得られる無限ループの 2 進数は、科学表記法で 1.100110011001100110011001100110011... * 2^-4;
# と表現されます。 # #指数ビットは -4 1023 = 1019、変換ビットは 11 桁の 2 進数 01111111011;
仮数ビットは無限ループですが、倍精度です。浮動小数点数は仮数部 52 ビットを規定しているため、52 ビットを超える部分は省略され、10011001100110011001100110011001100110011001100110 10
は最終的に 0.1 の 64 ビット 2 進浮動小数点数になります。 100110011001100110 0110011001100110011001100110011010同上,0.2存储为64位二进制浮点数:0-01111111100-1001100110011001100110011001100110011001100110011010
读取到两个浮点数的64为二进制后,再将其转化为可计算的二进制数
0.1转化为1.1001100110011001100110011001100110011001100110011010 * 2^(1019 - 1023)——0.00011001100110011001100110011001100110011001100110011010;
0.2转化为1.1001100110011001100110011001100110011001100110011010 * 2^(1020 - 1023)——0.0011001100110011001100110011001100110011001100110011010;
接着将两个浮点数的二进制数进行加法运算,得出0.0100110011001100110011001100110011001100110011001100111转化为十进制数即为0.30000000000000004
不难看出,精度缺失是在存储这一步就丢失了,后面的计算只是在不精准的值上进行的运算。
五. javascript如何解决精度问题出现的计算错误问题
对于小数或者整数的简单运算可如下解决:
function numAdd(num1, num2) { let baseNum, baseNum1, baseNum2; try { baseNum1 = String(num1).split(".")[1].length; } catch (e) { baseNum1 = 0; } try { baseNum2 = String(num2).split(".")[1].length; } catch (e) { baseNum2 = 0; } baseNum = Math.pow(10, Math.max(baseNum1, baseNum2)); return (num1 * baseNum + num2 * baseNum) / baseNum; };
如:0.1 + 0.2 通过函数处理后,相当于 (0.1 * 10 + 0.2 * 10) / 10
但是如同我们前面所了解的,浮点数在存储的时候就已经丢失精度了,所以浮点数乘以一个基数仍然会存在精度缺失问题,比如2500.01 * 100 = 250001.00000000003, 所以我们可以在以上函数的结果之上使用toFixed(),保留需要的小数位数。
一些复杂的计算,可以引入一些库进行解决
以上がJavaScriptの計算精度に関する豆知識(まとめ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。