【JavaScript】进制转换&位运算,了解一下? (2)

相比之下, -9 >> 2 得到 -3,因为符号被保留了。

-9 (base 10): 11111111111111111111111111110111 (base 2) -------------------------------- -9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)

与左移相反,右移一位在原数字基础上除以2

64 >> 1 // 32 无符号右移

将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。

用法: a >>> b

在非负数来说, 9 >>>2 和 9 >> 2 都是一样的结果

9 (base 10): 00000000000000000000000000001001 (base 2) -------------------------------- 9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)

而对于负数来说,结果就大有不同了,因为 >>> 不保留符号,当负数无符号右移时,会使用0填充

-9 (base 10): 11111111111111111111111111110111 (base 2) -------------------------------- -9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)

可以使用无符号右移来判断一个数的正负

function isPos(n) { return (n === (n >>> 0)) ? true : false; } isPos(-1); // false isPos(1); // true

虽然 -1 >>> 0 不会发生右移,但 -1 的二进制码已经变成了正数的二进制码, -1 >>> 0 结果为4294967295

Javascript进制转换 toString

toString 常用于将一个变量转为字符串,或是判断一个变量的类型,例如:

let arr = [] Object.prototype.toString.call(arr) // [object Array]

你应该没想过 toString 可以用于进制转换,请看下面例子:

(18).toString(2) // 10010(base 2) (18).toString(8) // 22 (base 8) (18).toString(16) // 12 (base 16)

参数规定表示数字的基数,是 2 ~ 36 之间的整数,若省略该参数,则使用基数 10。该参数可以理解为转换后的进制表示。

parseInt

parseInt 常用于数字取整,它同样可以传入参数用于进制转换,请看下面例子:

parseInt(10010, 2) // 18 (base 10) parseInt(22, 8) // 18 (base 10) parseInt(12, 16) // 18 (base 10)

第二个参数表示要解析的数字的基数,该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果该参数小于 2 或者大于 36,则 parseInt 将返回 NaN。

记得有道面试题是这样的:

// 问:返回的结果 [1, 2, 3].map(paseInt)

接下来,我们来一步一步的看下过程发生了什么?

parseInt(1, 0) // 基数为 0 时,以 10 为基数进行解析,结果为 1 parseInt(2, 1) // 基数不符合 2 ~ 36 的范围,结果为 NaN parseInt(3, 2) // 这里以 2 为基数进行解析,但 3 很明显不是一个二进制表示,故结果为 NaN //题目结果为 [1, NaN, NaN] 手动实现进制转换

虽然 JavaScript 为我们内置了进制转换的函数,但手动实现进制转换有利于我们理解过程,提高逻辑能力。对于初学者来说也是一个很不错的练习例子。以下只简单实现非负整数的转换。

十进制转二进制

基于 “除二取余” 思路实现

function toBinary(value) { if (isNaN(Number(value))) { throw `${value} is not a number` } let bits = [] while (value >= 1) { bits.unshift(value % 2) value = Math.floor(value / 2) } return bits.join('') }

使用

toBinary(36) // 100100 toBinary(12) // 1100 二进制转十进制

基于 “按权相加” 思路实现

function toDecimal(value) { let bits = value.toString().split('') let res = 0 while (bits.length) { let bit = bits.shift() if (bit == 1) { // ** 为幂运算符,如:2**3 为 8 res += 2 ** bits.length } } return res }

使用

toDecimal(10011) // 19 toDecimal(11111) // 33 写在最后

本文为大家介绍了进制和位运算的相关知识,旨在温故知新。我们只需要大概了解就好,因为在开发中真的用得少,至少我只用过 ~~ 来取整。而类似于~~这种取整操作还是尽量少用为好,对于其他开发者来说,可能会影响到代码可读性。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzygj.html