JavaScript位运算实战:奇偶判断、取整与数值交换技巧

作者:代码拾荒时间:2026-10-22 19:36:27浏览:473

本文深入解析JavaScript中的位运算机制,涵盖按位与(&)、或(|)、非(~)、异或(^)及左移、右移操作。通过具体实例展示如何利用位运算高效判断奇偶数、对浮点数向下取整、交换变量值以及计算2的n次方,同时辨析有符号与无符号右移在正负数处理上的差异,帮助开发者理解底层二进制操作以提升代码执行效率。

位运算基础与效率优势

在常规编程实践中,开发者较少直接使用位运算,若未深入研习,其原理往往难以直观理解。日常数值计算通常需先将数据转换为二进制形式再执行操作,而位运算则直接作用于二进制位,因此其执行效率通常更高。下文将通过具体实例剖析位运算的实际应用,以加深理解。

按位与(&):奇偶判断

按位与(&)

对于&&运算符,其逻辑为仅当两个操作数均为真时结果才为真。按位与(&)遵循相同逻辑:仅当两个对应二进制位均为1时,结果位才为1。例如,对数值1和3执行按位与操作的过程如下:

0001 & 0011 --------- 0001

只有当对应位均为1时结果位才为1,其余情况均为0。判断整数奇偶性时,常规做法是求余数:


function assert(n) {
  if (n % 2 === 1) {
 console.log("n是奇数");
 } else {
 console.log("n是偶数");
 }
}

assert(3); // "n是奇数"

我们亦可利用数值与1进行按位与(&)操作来判断奇偶,该方法执行速度更快:


function assert(n) {
if (n & 1) {
 console.log("n是奇数");
} else {
 console.log("n是偶数");
}
}

assert(3); // "n是奇数"

具体位运算过程如下:

1 = 0001 3 = 0011 -------- & = 0001

奇数的二进制表示中,最低位(最后一位)必定为1;而数值1的二进制仅最低位为1,其余为0。因此,奇数与1进行按位与操作后,结果最低位仍为1,其他位为0。相反,偶数的二进制最低位为0,与1进行按位与操作后,所有位结果均为0。

按位或(|):浮点数取整

按位或(|)

按位或(|)与逻辑或(||)原理相似:只要两个操作数中有一个对应位为1,结果位即为1,否则为0。

0001 | 0011 --------- 0011

对浮点数执行向下取整时,常规方法如下:

var num = Math.floor(1.1); // 1

利用位运算同样可实现向下取整:

var num = 1.1 | 0; // 1

JavaScript中的位运算不支持浮点数,因此执行1.1 | 0时,系统会先将1.1转换为整数1,再执行位运算,效果等同于向下取整。故1 | 0的结果为1。

按位非(~):符号位与负数转换

按位非(~)

按位非(~)用于求二进制的反码:

var num = 1; // 二进制 00000000000000000000000000000001 var num1 = ~num; // 二进制 11111111111111111111111111111110

JavaScript中的数字默认采用有符号32位二进制表示,最高位(第32位)为符号位,1代表负数,0代表正数。那么二进制11111111111111111111111111111110对应的十进制值是多少?由于最高位为1,该数为负数。负数二进制转十进制的规则为:符号位保持不变,其余位取反后加1。对上述二进制码取反得到10000000000000000000000000000001,加1后得到10000000000000000000000000000010,其十进制值为-2。

按位异或(^):变量交换技巧

按位异或(^)

按位异或(^)的规则是:仅当两个对应位中有一个为1时,结果位才为1;若两个位相同(均为0或均为1),则结果位为0。

0001 ^ 0011 --------- 0010

任意数值与自身进行按位异或操作,结果必为0。这是因为每一位都与自身相同,根据异或规则,相同位运算结果为0。

在实际开发中,常需交换两个变量的值:


var num1 = 1, num2 = 2, temp;
temp = num1;
num1 = num2; // 2
num2 = temp; // 1

若追求代码简洁,可采用数组解构方式:


var num1 = 1, num2 = 2;
num1 = [num2, num2 = num1][0];
console.log(num1); // 2
console.log(num2); // 1

若希望进一步精简代码,可利用按位异或特性实现:


var num1 = 1, num2 = 2;
num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3
num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = 2 ^ (1 ^ 2) = 1
num1 ^= num2; // num1 = num1 ^ num2 = 3 ^ 1 = 2
console.log(num1); // 2
console.log(num2); // 1

位移运算:左移与右移应用

有符号左移(<<)

有符号左移操作会将32位二进制数的所有位向左移动指定的位数,右侧空出的位补0。示例如下:

var num = 2; // 二进制10 num = num << 5; // 二进制1000000,十进制64

若需计算2的n次方,可利用左移运算:


function power(n) {
 return 1 << n;
}

power(5); // 32

数值1的二进制表示为01(高位补零后),将其左移5位得到0100000,即十进制的32,这正是2的5次方。

有符号右移(>>)

有符号右移操作会将32位二进制数的所有位向右移动指定的位数,左侧空出的位由符号位填充。示例如下:

var num = 64; // 二进制1000000 num = num >> 5; // 二进制10,十进制2

利用右移运算可快速计算一个数的二分之一:

var num = 64 >> 1; // 32

有符号左移与右移操作均不会改变数值的符号位。

无符号右移:正负判断与边界处理

无符号右移(>>>)

对于正数,无符号右移与有符号右移的结果一致。但对于负数,无符号右移会将符号位一同右移,且系统会将负数的二进制码视为无符号正数处理:

var num = -64; // 11111111111111111111111111000000 num = num >>> 5; // 134217726

基于上述特性,可利用无符号右移判断数值的正负:


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

isPos(-1); // false
isPos(1); // true

表达式-1 >>> 0虽未实际右移,但-1的二进制码(全1)被解释为正数二进制码:

11111111111111111111111111111111

因此,-1 >>> 0的结果为4294967295(即32位全1的无符号整数值)。

总结

上述实例在日常开发中较为常见且易于理解。对于复杂或晦涩的位运算,建议谨慎使用,以免增加代码阅读难度和维护成本。

作者最新文章