EdwardZZZ / articles

工作点滴记录
2 stars 0 forks source link

简单位运算 #54

Open EdwardZZZ opened 5 years ago

EdwardZZZ commented 5 years ago

工作几年就早就忘记了位运算,最近用的比较多,写一下基本的加减乘除位运算

注意: Javascript 进行位运算时采用的是 int32 大小,如过值超过 int32 范围必须采用 BigInt 进行位运算

function add(a, b) {
    return b ? add(a ^ b, (a & b) << 1) : a;
}

function add_while(a, b) {
    let result;
    while (b) {
        result = a ^ b;
        b = a & b << 1;
        a = result;
    }
    return result;
}

function minus(a, b) {
    return add(a, negative(b));
}

function negative(n) {
    return add(~n, 1);
}

function multi(a, b) {
    let result;
    while (b) {
        if (b & 1) result = add(result, a);
        a = a << 1;
        b = b >> 1;
    }
    return result;
}

function divide(a, b) {
    let result = 0;
    while (a >= b) {
        a = minus(a, b);
        result = add(result, 1);
    }
    return result;
}

console.log(add(1, 2));
console.log(add_while(1, 2));
console.log(negative(3));
console.log(multi(3, 4));
console.log(divide(12, 4));
EdwardZZZ commented 5 years ago
[...Array(32)].map((_, i) => `${i}, ${Math.pow(2, i)}, ${1<<i}`).join('\n');
EdwardZZZ commented 4 years ago

    toBytes64LE(value: number | string): number[] {
        if (value >= 0 && value < 128) return [+value];

        const buf = [];
        const longValue = Long.fromValue(value);
        let r = longValue;
        while (buf.length < 9) {
            r = longValue.shiftRightUnsigned(7 * buf.length);

            if ((r.gt(0x7f) || longValue.isNegative()) && buf.length < 8) {
                buf.push(r.and(0x7f).or(0x80).toInt());
            } else {
                buf.push(r.toInt());
                break;
            }
        }
        return buf;
    }

    readVarInt64(): string {
        const [, , len] = Range[64];
        let i = 0;
        let b = this.buffer[this.pos + i++];
        let result = Long.fromValue(b & 0x7f);

        while (i < len + 1) {
            if ((b & 0x80) !== 0) {
                b = this.buffer[this.pos + i++];
                if (i === 9) {
                    result = result.or(Long.fromValue(b).shiftLeft(56));
                } else {
                    result = result.or(Long.fromValue(b & 0x7f).shiftLeft(7 * (i - 1)));
                }
            } else {
                break;
            }
        }
        this.pos += i;
        return result.toString();
    }