由於 JS 採用 IEEE 754 雙精度版本(64位),而且只要採用 IEEE 754 的語言都有該問題。 還有學過計算機組成原理這門課的同窗應該知道,咱們計算機的數據都是由0、1組成的,js的數字最終在計算機也是又0、1組成。咱們先說一下小數怎麼轉換成二進制。git
// 0.125 十進制 -> 二進制
0.125 * 2 = 0.25 取0
0.25 * 2 = 0.5 取0
0.5 * 2 = 1 取1
// 0.001 (0.125 的二進制)
複製代碼
從上面咱們能夠知道經過小數部分不斷乘2來判斷取二進制位 0 仍是 取1,如下是轉換的步驟:github
若是上面還不清楚能夠再下面bash
// 0.1 十進制 -> 二進制
0.1 * 2 = 0.2 取0
0.2 * 2 = 0.4 取0
0.4 * 2 = 0.8 取0
0.8 * 2 = 1.6 取1
0.6 * 2 = 1.2 取1
0.2 * 2 = 0.4 取0
0.4 * 2 = 0.8 取0
0.8 * 2 = 1.6 取1
0.6 * 2 = 1.2 取1
//0.000110011(0011)` 0.1二進制(0011)裏面的數字表示循環
複製代碼
你會發現 0.1 轉二級制會一直無線循環下去,根本算不出一個正確的二進制數。 因此咱們得出 0.1 = 0.000110011(0011)
,那麼 0.2 的演算也基本如上所示,因此得出 0.2 = 0.00110011(0011)
回來繼續說 IEEE 754 雙精度。六十四位中符號位佔一位,整數位佔十一位,其他五十二位都爲小數位。 由於 0.1 和 0.2 都是無限循環的二進制了,因此在小數位末尾處須要判斷是否進位(就和十進制的四捨五入同樣) 那麼把這兩個二進制加起來會得出0.010011....0100
, 這個值算成十進制就是 0.30000000000000004
工具
//下面能夠用原生解決 0.1+0.2 的問題
parseFloat((0.1 + 0.2).toFixed(10))
複製代碼
下面推薦一個小工具專門是用來處理js浮點數相加相減的問題的你們能夠去看一下spa
你們以爲有用的話給個star呀get