---
--- Date         : 2020-07-08 16:57:51
--- Author       : HUAFEI2
--- LastEditors  : LICHAO7
--- LastEditTime : 2020-07-13 12:45:00
--- Description  : bit operations
---

-- 与   同为1，则为1
-- 或   有一个为1，则为1
-- 非   true为 false，其余为true
-- 异或 相同为0，不同为1
bit = {}
function bit.__andBit(left, right) -- 与  
    return (left == 1 and right == 1) and 1 or 0
end

function bit.__orBit(left, right) -- 或  
    return (left == 1 or right == 1) and 1 or 0
end

function bit.__xorBit(left, right) -- 异或  
    return (left + right) == 1 and 1 or 0
end

function bit.__base(left, right, op) -- 对每一位进行op运算，然后将值返回  
    if left < right then
        left, right = right, left
    end
    local res = 0
    local shift = 1
    while left ~= 0 do
        local ra = left % 2 -- 取得每一位(最右边)  
        local rb = right % 2
        res = shift * op(ra, rb) + res
        shift = shift * 2
        left = math.modf(left / 2) -- 右移  
        right = math.modf(right / 2)
    end
    return res
end

function bit.andOp(left, right)
    return bit.__base(left, right, bit.__andBit)
end

function bit.xorOp(left, right)
    return bit.__base(left, right, bit.__xorBit)
end

function bit.orOp(left, right)
    return bit.__base(left, right, bit.__orBit)
end

function bit.notOp(left)
    return left > 0 and -(left + 1) or -left - 1
end

function bit.lShiftOp(left, num) -- left左移num位  
    return left * (2 ^ num)
end

function bit.rShiftOp(left, num) -- right右移num位  
    return math.floor(left / (2 ^ num))
end

---
--- Continuous "or" bit operations
---
--- @param one number
--- @param two number
--- @return number
---
function bit.ors(one, two, ...)
    local params = {...};
    local result = bit.orOp(one, two);
    for key, value in ipairs(params) do
        result = bit.orOp(result, value);
    end
    return result;
end

---
--- Continuous "and" bit operations
---
--- @param one number
--- @param two number
--- @return number
---
function bit.ands(one, two, ...)
    local params = {...};
    local result = bit.andOp(one, two);
    for key, value in ipairs(params) do
        result = bit.andOp(result, value);
    end
    return result;
end

---
--- Continuous "xor" bit operations
---
--- @param one number
--- @param two number
--- @return number
---
function bit.xors(one, two, ...)
    local params = {...};
    local result = bit.xorOp(one, two);
    for key, value in ipairs(params) do
        result = bit.xorOp(result, value);
    end
    return result;
end


---
--- *@example
---
function bit.test()
    print(bit.andOp(65, 0x3f)) -- 65 1000001    63 111111  
    print(65 % 64)
    print(bit.orOp(5678, 6789))
    print(bit.xorOp(13579, 2468))
    print(bit.rShiftOp(16, 3))
    print(bit.notOp(-4))

    print(string.byte("abc", 1))
end
-- cclog("aaaaaaa:")  
-- bit.test()
