JS 數字類型只有number類型,number類型至關於其餘強類型語言中的double類型(雙精度浮點型
),不區分浮點型和整數型。javascript
number 有四種進製表示方法,十進制,二進制,八進制和十六進制java
表示方法es6
數字0和字母B或者小寫字母b
) ,後接1或者0表示二進制數0o
,後接小於8的數字表示八進制0x
或者0X
開頭,後接0-9數字和a-e五個英文字母parseInt
和 toString
編程
// toString轉換,輸入爲Number,返回爲String var n = 120; n.toString(); // "120" n.toString(2); // "1111000" n.toString(8); // "170" n.toString(16); // "78" n.toString(20); // "60" 0x11.toString(); // "17" 0b111.toString(); // "7" 0x11.toString(12);// "15" // parseInt轉換,輸入爲String,返回爲Number parseInt('110'); // 110 parseInt('110', 2); // 6 parseInt('110', 8); // 72 parseInt('110', 16); // 272 parseInt('110', 26); // 702 // toString和parseInt結合使用能夠在兩兩進制之間轉換 // 將 a 從36進制轉爲12進制 var a = 'ra'; // 36進製表示的數 parseInt(a, 36).toString(12); // "960"
因爲Js的全部數字類型都是雙精度浮點型(64位
)採用 IEEE754 標準數組
64位二進制數表示一個number數字
編程語言
其中 64位 = 1位符號位 + 11位指數位 + 52位小數位編碼
符號位:用來表示數字的正負,-1^符號位數值,0爲正數,1爲負數es5
指數位:通常都用科學計數法表示數值大小,可是這裏通常都是2進制的科學計數法,表示2的多少次方code
小數位:科學計數法前面的數值,IEEE745標準,默認全部的該數值都轉爲1.xxxxx這種格式,優勢是能夠省略一位小數位,能夠存儲更多的數字內容,缺點是丟失精度對象
大概能夠理解爲這張圖
整數轉二進制
好理解,除二取餘法,7表示爲 111 = 1x2^3 + 1x2^2 + 1x2^1
問題來了,小數轉二進制!!
因爲也須要轉化爲指數形式,例如 1/2 = 1 * 2^-1, 1/4 = 1 * 2^-2,因此小數的轉化二進制過程是經過判斷小數是否是滿 1/2,1/4,8/1以此類推,換成數學公式就是 乘二取整法
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.2*2=0.4======取出整數部分0 0.4*2=0.8======取出整數部分0 0.8*2=1.6======取出整數部分1 0.6*2=1.2======取出整數部分1 因此0.1轉化成二進制是:0.0001 1001 1001 1001…(無限循環) 0.1 => 0.0001 1001 1001 1001…(無限循環) 同理0.2的二進制是0.0011 0011 0011 0011…(無限循環)
計算機中的數字都是以二進制存儲的,二進制浮點數表示法並不能精確的表示相似0.1這樣 的簡單的數字
若是要計算 0.1 + 0.2 的結果,計算機會先把 0.1 和 0.2 分別轉化成二進制,而後相加,最後再把相加獲得的結果轉爲十進制
但有一些浮點數在轉化爲二進制時,會出現無限循環 。好比, 十進制的 0.1 轉化爲二進制,會獲得以下結果:
0.1 => 0.0001 1001 1001 1001…(無限循環)
0.2 => 0.0011 0011 0011 0011…(無限循環)
而存儲結構中的尾數部分最多隻能表示 53 位。爲了能表示 0.1,只能模仿十進制進行四捨五入了,但二進制只有 0 和 1 , 因而變爲 0 舍 1 入 。 所以,0.1 在計算機裏的二進制表示形式以下:
0.1 => 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 101
0.2 => 0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 001
用標準計數法表示以下:
0.1 => (−1)0 × 2^4 × (1.1001100110011001100110011001100110011001100110011010)2
0.2 => (−1)0 × 2^3 × (1.1001100110011001100110011001100110011001100110011010)2
在計算浮點數相加時,須要先進行 「對位」,將較小的指數化爲較大的指數,並將小數部分相應右移:
最終,「0.1 + 0.2」 在計算機裏的計算過程以下:
通過上面的計算過程,0.1 + 0.2 獲得的結果也能夠表示爲:
(−1)0 × 2−2 × (1.0011001100110011001100110011001100110011001100110100)2=>.0.30000000000000004
經過 JS 將這個二進制結果轉化爲十進制表示:
(-1)0 * 2-2 * (0b10011001100110011001100110011001100110011001100110100 * 2**-52); //0.30000000000000004
console.log(0.1 + 0.2) ; // 0.30000000000000004
這是一個典型的精度丟失案例,從上面的計算過程能夠看出,0.1 和 0.2 在轉換爲二進制時就發生了一次精度丟失,而對於計算後的二進制又有一次精度丟失 。所以,獲得的結果是不許確的。
原生方法類
console.log((0.1 + 0.2).toFixed(12) == 0.3) > true console.log((0.1 + 0.2).toFixed(12)) > 0.300000000000 console.log((2.4/0.8).toFixed(12)) > 3.000000000000
parseFloat((a+b).toFixed(2))
第三方封裝類庫
math庫
//統一配置math.js math.config({ number: 'BigNumber', // 'number' (default), precision: 20 }); // 轉換數字類型 var temp = math.bignumber(a) * math.bignumber(b) // 提取數字類型,否則會是一個math對象 var result = math.number(temp)
bignumber,big,decimal等