JavaScript 轉換數字爲整數的方法

本文將會列舉並說明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的功能,好比:

參考文檔

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、前端可視化方面有深刻研究。對程序員思惟能力訓練和培訓、程序員職業規劃和程序員理財投資有濃厚興趣。

ITman彪叔公衆號

相關文章
相關標籤/搜索