[备忘录]二进制位计算(加减乘除)函数

0 阅读2分钟

/** 
 * 纯位运算实现二进制加法 
 * @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); 
}