/**
* 纯位运算实现二进制加法
* @param {number} a - 整数(二进制本质)
* @param {number} b - 整数(二进制本质)
* @returns {number} 相加结果(十进制数,可通过toString(2)转二进制字符串)
**/
function bitAdd(a, b) {
// 当进位b不为0时,循环计算
while (b !== 0) {
// 1. 异或^:计算无进位的和(相同位为0,不同位为1)
const sumWithoutCarry = a ^ b;
// 2. 与& + 左移<<1:计算进位(只有两位都为1时才会进位,左移1位表示进位到高位)
const carry = (a & b) << 1;
// 3. 更新a为无进位和,b为进位,继续循环直到进位为0
a = sumWithoutCarry;
b = carry;
}
return a;
}
/**
* 纯位运算实现二进制减法(a - b = a + (-b),-b = ~b + 1)
* @param {number} a - 被减数(整数)
* @param {number} b - 减数(整数)
* @returns {number} 相减结果
**/
function bitSubtract(a, b) {
// 计算b的补码(负数):~b是按位取反,+1是补码规则
const negativeB = ~b + 1;
// 减法转加法:a - b = a + (-b)
return bitAdd(a, negativeB);
}
/**
* 纯位运算实现二进制乘法(通过位移+加法,模拟乘法的本质:累加)
* @param {number} a - 乘数 * @param {number} b - 被乘数
* @returns {number} 相乘结果
**/
function bitMultiply(a, b) {
// 处理负数:记录符号,转为正数计算
let sign = 1;
if (a < 0) {
sign = bitSubtract(0, sign); // 符号取反
a = bitSubtract(0, a); // 转为正数
}
if (b < 0) {
sign = bitSubtract(0, sign);
b = bitSubtract(0, b);
}
let result = 0;
// 循环位移b,直到b为0
while (b > 0) {
// 如果b的最低位是1,将a加到结果中
if (b & 1) {
result = bitAdd(result, a);
}
// a左移1位(等价于×2),b右移1位(等价于÷2,去掉最低位)
a <<= 1;
b >>= 1;
}
// 恢复符号
return sign === 1 ? result : bitSubtract(0, result);
}
/**
* 纯位运算实现二进制除法(通过位移+减法,模拟除法的本质:累减)
* @param {number} a - 被除数
* @param {number} b - 除数
* @returns {number} 相除结果(向下取整)
**/
function bitDivide(a, b) {
if (b === 0) {
throw new Error('除数不能为0');
}
// 处理负数:记录符号,转为正数计算
let sign = 1;
if (a < 0) {
sign = bitSubtract(0, sign);
a = bitSubtract(0, a);
}
if (b < 0) {
sign = bitSubtract(0, sign);
b = bitSubtract(0, b);
}
let result = 0;
// 从高位到低位遍历(31位是JS整数的有效高位)
for (let i = 31; i >= 0; i--) {
// 把b左移i位,判断是否小于等于a(避免溢出)
if ((b << i) <= a) {
a = bitSubtract(a, b << i); // 减去b<<i
result = bitAdd(result, 1 << i); // 结果加上1<<i
}
}
// 恢复符号
return sign === 1 ? result : bitSubtract(0, result);
}
// 工具函数:二进制字符串转整数(方便测试)
function binaryToInt(binStr) {
return parseInt(binStr, 2);
}