本文將會列舉並說明JavaScript 把一個number(或者numerical的對象)轉換成一個整數相關方法。javascript
使用parseInt
parseInt的語法以下:parseInt(string, radix) 參數string的表示要解析的字符串,也能夠是一個對象,會自動調用對象的toString函數獲得要解析的字符串。前端
parseInt的第二個參數,能夠指定要解析的數字的基數,注意該值介於 2 ~ 36 之間,若是該參數小於 2 或者大於 36,則 parseInt() 將返回 NaN。好比下面的代碼,結果爲8,這樣能夠很方便的把其餘的進制的數字轉換爲10進制的數字:java
parseInt(10,8) // 結果爲8
當參數 radix 的值爲 0,或沒有設置該參數時,parseInt() 會根據 string 來判斷數字的基數。 舉例,若是 string 以 "0x" 開頭,parseInt() 會把 string 的其他部分解析爲十六進制的整數。若是 string 以 0 開頭,那麼 ECMAScript v3 容許 parseInt() 的一個實現把其後的字符解析爲八進制或十六進制的數字。若是 string 以 1 ~ 9 的數字開頭,parseInt() 將把它解析爲十進制的整數。程序員
註釋 1. 只有字符串中的第一個數字會被返回。 什麼意思呢,若是輸入的字符串是"123abc","123,123",那麼結果是123,parseInt方法會自動忽略後面的非數字部分。 2. 輸入字符串開頭和結尾的空格是容許的。 3. parseFloat 也具有以上兩條特徵,不過本文不重點講述。瀏覽器
使用Math.trunc
Math.trunc() 方法會將數字的小數部分去掉,只保留整數部分。好比如下代碼:安全
Math.trunc(13.37) // 13 Math.trunc(42.84) // 42 Math.trunc(0.123) // 0 Math.trunc(-0.123) // -0 Math.trunc("-1.123") // -1 Math.trunc(NaN) // NaN Math.trunc("foo") // NaN Math.trunc() // NaN
當傳入的類型不是數字的時候,會自動作癮式轉換。可是若是是一個非numerical的參數的時候,返回NaN。 IE瀏覽器並不支持這個方法,因此能夠考慮polyfill:架構
Math.trunc || (Math.trunc = function(v){ return v < 0 ? Math.ceil(v) : Math.floor(v); // 使用Math.floor和Math.ceil方法 }) // 或者 if (!Math.trunc) { Math.trunc = function(v) { v = +v; if (!isFinite(v)) return v; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); // 返回: // 0 -> 0 // -0 -> -0 // 0.2 -> 0 // -0.2 -> -0 // 0.7 -> 0 // -0.7 -> -0 // Infinity -> Infinity // -Infinity -> -Infinity // NaN -> NaN // null -> 0 }; }
二進制位運算
對於numerical的對象n,能夠經過以下的方式來轉換爲整數:jsp
- ~~n 雙重位取反(Double bitwise NOT)
- n | n 位或運算(Bitwise OR)
- n | 0 和0的位或運算(Bitwise OR with 0)
- n << 0 位左移運算0位(Bitwise left shift)
- n >> 0 位右移運算0位(Bitwise right shift)
- n & n 爲與運算(Bitwise AND) 好比代碼以下:
~~1.23 // 1 -1.2 | -1.2 // - 1 -1.2 | 0 // - 1 3.4 >> 0 // 3 3.2 << 0 // 3 5.5 & 5.5 // 5 ~~"1.2" // 1.2
注意,從上面能夠看出,位運算下字符串會自動轉換數字。函數
##性能測試 下面這個網址能夠測試以上方法測性能狀況,其中沒有用到Math.trunc方法,用Math.floor方法代替了Math.trunc方法: https://jsperf.com/rounding-numbers-down性能
我測試的結果以下,能夠發現速度上,parseInt是最慢的,其餘方法相對較快:
從代碼量的角度來講,n | 0 或則 ~~n是字符最少的,寫起來應該也是最方便的, 可是可讀性會變差。
另外本身寫代碼測試了下Math.trunc和Math.floor的速度,比較結果以下:
console.time('Math.trunc'); for(var i = 0;i < 1000000000;i ++){ Math.trunc(3.3); } console.timeEnd('Math.trunc'); console.time('Math.floor'); for(var i = 0;i < 1000000000;i ++){ Math.floor(3.3); } console.timeEnd('Math.floor'); // Math.trunc: 8658.009033203125ms // Math.floor: 7916.7890625ms
#位操做轉換整數的原理 參考Mozilla上面對於位操做的說明,點擊下面連接: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators 有這樣一段話:
Bitwise operators treat their operands as a sequence of 32 bits (zeroes and ones), rather than as decimal, hexadecimal, or octal [numbers]
JavaScript中,數字存儲是雙進度64位浮點數。可是位操做卻會把要操做的運算元當作32位帶符號的整數。所以進行位操做時,會自動把數字先轉換爲整數。對數字n作前面提到的位運算,至關於n & 0xFFFFFFFF
位運算優缺點
用位操做進行整數轉換的優勢,大概包括以下:
- 性能更快
- 代碼字符能夠更少(好比 n | 0或者~~n)
用位操做進行整數轉換的缺點,大概包括以下:
- 代碼不易懂
- 可能不能經過jsLint
- 只支持32位之內的數據,超過範圍就會得出錯誤的結果。
對於「只支持32位之內的數據,超過範圍就會得出錯誤的結果」這一點,由於位運算會把運算元當作32位帶符號的整數,其範圍是-2,147,483,648 到 2147483647 (0x7FFFFFFFF),超過範圍就不奏效了。好比以下代碼
~~2147483648.1//-2147483648
因爲2147483648.1超過了範圍,其結果變成了-2147483648,而不是2147483648。下面列出安全和不安排的轉換的更多示例:
// Safe (2147483647.5918 & 0xFFFFFFFF) === 2147483647 (2147483647 & 0xFFFFFFFF) === 2147483647 (200.59082098 & 0xFFFFFFFF) === 200 (0X7FFFFFFF & 0xFFFFFFFF) === 0X7FFFFFFF // Unsafe (2147483648 & 0xFFFFFFFF) === -2147483648 (-2147483649 & 0xFFFFFFFF) === 2147483647 (0x80000000 & 0xFFFFFFFF) === -2147483648 (3000000000.5 & 0xFFFFFFFF) === -1294967296
爲了可以提升性能,又保證超過範圍的時候安全可靠,能夠考慮下面的polyfill:
function trunc(n) { if (n > -0x80000000 && n < 0x80000000) { return n & 0xFFFFFFFF; //此處能夠用 ~~n,n | 0等等 } return Math.trunc(n); }
Math.round 擴展
一樣能夠用位操做實現Math.round的功能,好比:
- ~~ (somenum + (somenum > 0 ? .5 : -.5)) == Math.round(somenum) 下面是相關的性能測試,能夠參考: https://jsperf.com/math-round-vs-hack/25.
參考文檔
https://jsperf.com/rounding-numbers-down https://stackoverflow.com/questions/131406/what-is-the-best-method-to-convert-floating-point-to-an-integer-in-javascript https://j11y.io/javascript/double-bitwise-not/ https://stackoverflow.com/questions/7487977/using-bitwise-or-0-to-floor-a-number https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators https://jsperf.com/math-round-vs-hack/25
歡迎關注公衆號「ITman彪叔」。彪叔,擁有10多年開發經驗,現任公司系統架構師、技術總監、技術培訓師、職業規劃師。熟悉Java、JavaScript。在計算機圖形學、WebGL、前端可視化方面有深刻研究。對程序員思惟能力訓練和培訓、程序員職業規劃和程序員理財投資有濃厚興趣。