摘要:另外自己寫代碼測(cè)試了下和的速度,比較結(jié)果如下位操作轉(zhuǎn)換整數(shù)的原理參考上面對(duì)于位操作的說明,點(diǎn)擊下面鏈接有這樣一段話中,數(shù)字存儲(chǔ)是雙進(jìn)度位浮點(diǎn)數(shù)。但是位操作卻會(huì)把要操作的運(yùn)算元當(dāng)做位帶符號(hào)的整數(shù)。因此進(jìn)行位操作時(shí),會(huì)自動(dòng)把數(shù)字先轉(zhuǎn)換為整數(shù)。
本文將會(huì)列舉并說明JavaScript 把一個(gè)number(或者numerical的對(duì)象)轉(zhuǎn)換成一個(gè)整數(shù)相關(guān)方法。
使用parseIntparseInt的語法如下:parseInt(string, radix)
參數(shù)string的表示要解析的字符串,也可以是一個(gè)對(duì)象,會(huì)自動(dòng)調(diào)用對(duì)象的toString函數(shù)得到要解析的字符串。
parseInt的第二個(gè)參數(shù),可以指定要解析的數(shù)字的基數(shù),注意該值介于 2 ~ 36 之間,如果該參數(shù)小于 2 或者大于 36,則 parseInt() 將返回 NaN。比如下面的代碼,結(jié)果為8,這樣可以很方便的把其他的進(jìn)制的數(shù)字轉(zhuǎn)換為10進(jìn)制的數(shù)字:
parseInt(10,8) // 結(jié)果為8
當(dāng)參數(shù) radix 的值為 0,或沒有設(shè)置該參數(shù)時(shí),parseInt() 會(huì)根據(jù) string 來判斷數(shù)字的基數(shù)。
舉例,如果 string 以 "0x" 開頭,parseInt() 會(huì)把 string 的其余部分解析為十六進(jìn)制的整數(shù)。如果 string 以 0 開頭,那么 ECMAScript v3 允許 parseInt() 的一個(gè)實(shí)現(xiàn)把其后的字符解析為八進(jìn)制或十六進(jìn)制的數(shù)字。如果 string 以 1 ~ 9 的數(shù)字開頭,parseInt() 將把它解析為十進(jìn)制的整數(shù)。
注釋
1. 只有字符串中的第一個(gè)數(shù)字會(huì)被返回。 什么意思呢,如果輸入的字符串是"123abc","123,123",那么結(jié)果是123,parseInt方法會(huì)自動(dòng)忽略后面的非數(shù)字部分。 2. 輸入字符串開頭和結(jié)尾的空格是允許的。 3. parseFloat 也具備以上兩條特征,不過本文不重點(diǎn)講述。使用Math.trunc
Math.trunc() 方法會(huì)將數(shù)字的小數(shù)部分去掉,只保留整數(shù)部分。比如以下代碼:
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
當(dāng)傳入的類型不是數(shù)字的時(shí)候,會(huì)自動(dòng)做癮式轉(zhuǎn)換。但是如果是一個(gè)非numerical的參數(shù)的時(shí)候,返回NaN。
IE瀏覽器并不支持這個(gè)方法,所以可以考慮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 }; }二進(jìn)制位運(yùn)算
對(duì)于numerical的對(duì)象n,可以通過如下的方式來轉(zhuǎn)換為整數(shù):
~~n 雙重位取反(Double bitwise NOT)
n | n 位或運(yùn)算(Bitwise OR)
n | 0 和0的位或運(yùn)算(Bitwise OR with 0)
n << 0 位左移運(yùn)算0位(Bitwise left shift)
n >> 0 位右移運(yùn)算0位(Bitwise right shift)
n & n 為與運(yù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
注意,從上面可以看出,位運(yùn)算下字符串會(huì)自動(dòng)轉(zhuǎn)換數(shù)字。性能測(cè)試
下面這個(gè)網(wǎng)址可以測(cè)試以上方法測(cè)性能情況,其中沒有用到Math.trunc方法,用Math.floor方法代替了Math.trunc方法:
https://jsperf.com/rounding-n...
我測(cè)試的結(jié)果如下,可以發(fā)現(xiàn)速度上,parseInt是最慢的,其他方法相對(duì)較快:
從代碼量的角度來說,n | 0 或則 ~~n是字符最少的,寫起來應(yīng)該也是最方便的, 但是可讀性會(huì)變差。
另外自己寫代碼測(cè)試了下Math.trunc和Math.floor的速度,比較結(jié)果如下:
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位操作轉(zhuǎn)換整數(shù)的原理
參考Mozilla上面對(duì)于位操作的說明,點(diǎn)擊下面鏈接:
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中,數(shù)字存儲(chǔ)是雙進(jìn)度64位浮點(diǎn)數(shù)。但是位操作卻會(huì)把要操作的運(yùn)算元當(dāng)做32位帶符號(hào)的整數(shù)。因此進(jìn)行位操作時(shí),會(huì)自動(dòng)把數(shù)字先轉(zhuǎn)換為整數(shù)。對(duì)數(shù)字n做前面提到的位運(yùn)算,相當(dāng)于n & 0xFFFFFFFF
位運(yùn)算優(yōu)缺點(diǎn)用位操作進(jìn)行整數(shù)轉(zhuǎn)換的優(yōu)點(diǎn),大概包括如下:
性能更快
代碼字符可以更少(比如 n | 0或者~~n)
用位操作進(jìn)行整數(shù)轉(zhuǎn)換的缺點(diǎn),大概包括如下:
代碼不易懂
可能不能通過jsLint
只支持32位以內(nèi)的數(shù)據(jù),超過范圍就會(huì)得出錯(cuò)誤的結(jié)果。
對(duì)于“只支持32位以內(nèi)的數(shù)據(jù),超過范圍就會(huì)得出錯(cuò)誤的結(jié)果”這一點(diǎn),因?yàn)槲贿\(yùn)算會(huì)把運(yùn)算元當(dāng)做32位帶符號(hào)的整數(shù),其范圍是-2,147,483,648 到 2147483647 (0x7FFFFFFFF),超過范圍就不奏效了。比如如下代碼
~~2147483648.1//-2147483648
由于2147483648.1超過了范圍,其結(jié)果變成了-2147483648,而不是2147483648。下面列出安全和不安排的轉(zhuǎn)換的更多示例:
// 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
為了能夠提高性能,又保證超過范圍的時(shí)候安全可靠,可以考慮下面的polyfill:
function trunc(n) { if (n > -0x80000000 && n < 0x80000000) { return n & 0xFFFFFFFF; //此處可以用 ~~n,n | 0等等 } return Math.trunc(n); }Math.round 擴(kuò)展
同樣可以用位操作實(shí)現(xiàn)Math.round的功能,比如:
~~ (somenum + (somenum > 0 ? .5 : -.5)) == Math.round(somenum)
下面是相關(guān)的性能測(cè)試,可以參考:
https://jsperf.com/math-round-vs-hack/25.
https://jsperf.com/rounding-n...
https://stackoverflow.com/que...
https://j11y.io/javascript/do...
https://stackoverflow.com/que...
https://developer.mozilla.org...
https://jsperf.com/math-round...
歡迎關(guān)注公眾號(hào)“ITman彪叔”。彪叔,擁有10多年開發(fā)經(jīng)驗(yàn),現(xiàn)任公司系統(tǒng)架構(gòu)師、技術(shù)總監(jiān)、技術(shù)培訓(xùn)師、職業(yè)規(guī)劃師。熟悉Java、JavaScript。在計(jì)算機(jī)圖形學(xué)、WebGL、前端可視化方面有深入研究。對(duì)程序員思維能力訓(xùn)練和培訓(xùn)、程序員職業(yè)規(guī)劃和程序員理財(cái)投資有濃厚興趣。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109458.html
摘要:解釋一行,執(zhí)行一行這也意味著你可以使用同一個(gè)變量保存不同類型的數(shù)據(jù)二數(shù)據(jù)類型最新的標(biāo)準(zhǔn)定義了種數(shù)據(jù)類型種原型數(shù)據(jù)類型布爾值,和一個(gè)表明值的特殊關(guān)鍵字。我們稱這些類型的值為原始值四布爾值布爾值數(shù)據(jù)類型只能有兩個(gè)值,它們是文本和。 一、動(dòng)態(tài)類型 JavaScript 是一種弱類型或者說動(dòng)態(tài)語言。這意味著你不用提前聲明變量的類型,在程序運(yùn)行過程中,類型會(huì)被自動(dòng)確定。(解釋一行,執(zhí)行一行)這也...
摘要:中有五種基本數(shù)據(jù)類型,以及一種復(fù)雜引用類型數(shù)據(jù)類型,中還細(xì)分了很多具體的類型,比如等等中又新增了一種類型。類型的數(shù)值范圍是,超出這個(gè)范圍的值為,可以使用函數(shù)來判斷數(shù)值是否在范圍內(nèi)。 ECMAScript5中有五種基本數(shù)據(jù)類型:Undefined,Null,Boolean,Number,String,以及一種復(fù)雜(引用類型)數(shù)據(jù)類型:Object,Object中還細(xì)分了很多具體的類型,比...
摘要:例如注意字符串中的負(fù)十六進(jìn)制數(shù)字是一個(gè)特殊情況,如果你用解析,結(jié)果是不正確的。轉(zhuǎn)換十六進(jìn)制數(shù)時(shí)要小心,如果你不知道要轉(zhuǎn)換對(duì)象的類型,不要使用。字符串轉(zhuǎn)換為數(shù)字的方式總結(jié)負(fù)十六進(jìn)制數(shù)字符串轉(zhuǎn)換為數(shù)字時(shí)。 摘要 :JavaScript 是一個(gè)神奇的語言,字符串轉(zhuǎn)數(shù)字有 5 種方法,各有各的坑法! 原文: Converting Strings to Number in Javascript...
摘要:字符串轉(zhuǎn)換整數(shù)請(qǐng)你來實(shí)現(xiàn)一個(gè)函數(shù),使其能將字符串轉(zhuǎn)換成整數(shù)。該字符串除了有效的整數(shù)部分之后也可能會(huì)存在多余的字符,這些字符可以被忽略,它們對(duì)于函數(shù)不應(yīng)該造成影響。如果數(shù)值超過這個(gè)范圍,返回或。因此無法執(zhí)行有效的轉(zhuǎn)換。 LeetCode8.字符串轉(zhuǎn)換整數(shù)(atoi) JavaScript 請(qǐng)你來實(shí)現(xiàn)一個(gè) atoi 函數(shù),使其能將字符串轉(zhuǎn)換成整數(shù)。 首先,該函數(shù)會(huì)根據(jù)需要丟棄無用的開頭空格...
摘要:用表示法表示的數(shù)值等于前面的數(shù)值乘以的指數(shù)次冪。下面是一個(gè)使用表示法表示數(shù)值的例子等于注意浮點(diǎn)類型精度控制的兩個(gè)方法是原型上實(shí)現(xiàn)的一個(gè)方法,其作用是對(duì)一個(gè)浮點(diǎn)數(shù)進(jìn)行四舍五入并保留固定小數(shù)位。 進(jìn)制表示 談到Number類型,不得不提進(jìn)制(此處不做過多介紹)八進(jìn)制字面值的第一位必須是零(0),然后是八進(jìn)制數(shù)字序列(0~7)十六進(jìn)制字面值的前兩位必須是 0x,后跟任何十六進(jìn)制數(shù)字(0~9 ...
閱讀 1119·2021-11-16 11:45
閱讀 3136·2021-10-13 09:40
閱讀 727·2019-08-26 13:45
閱讀 1227·2019-08-26 13:32
閱讀 2182·2019-08-26 13:23
閱讀 927·2019-08-26 12:16
閱讀 2835·2019-08-26 11:37
閱讀 1766·2019-08-26 10:32