美文网首页
python3的位移操作

python3的位移操作

作者: 晓函 | 来源:发表于2016-11-18 15:18 被阅读2561次

    因为要将js的一个签名算法移植到python上,遇到一些麻烦。

    int无限宽度,不会溢出

    算法中需要用到了32位int的溢出来参与运算,但是python的int是不会溢出的,达到界限后会自己转为long,所以很麻烦。

    #使用-342686650:
    ret = 123456789 << 20
    print(ret)
    得到结果129453825982464
    print(bin(ret))
    这个二进制是11101011011110011010001010100000000000000000000
    明显已经超出32位了
    
    在JS上
    document.writeln(123456789 << 20);
    得到结果是-783286272
    这就是溢出后截取的,
    
    在python上想实现溢出效果,找到一个函数
    #这个函数可以得到32位int溢出结果,因为python的int一旦超过宽度就会自动转为long,永远不会溢出,有的结果却需要溢出的int作为参数继续参与运算
    def int_overflow(val):
        maxint = 2147483647
        if not -maxint-1 <= val <= maxint:
            val = (val + (maxint + 1)) % (2 * (maxint + 1)) - maxint - 1
        return val
    
    
    ret = int_overflow(123456789 << 20)
    print(ret)
    print(bin(ret))
    现在得到结果是-783286272
    二进制:-101110101100000000000000000000
    

    负数使用无符号右移>>>

    在JS中,可以使用 a>>>b来实现无符号位移,python中没有这个运算符,只能自己实现了
    无符号右移>>>,就是将有符号int a和b转为无符号uint后,再进行普通右移>>运算
    比如-1的有符号int就是-1,无符号int就是4294967295
    我们自己实现>>>可以这样

    #无符号右移
    import ctypes
    def unsigned_right_shitf(n,i):
        # 数字小于0,则转为32位无符号uint
        if n<0:
            n = ctypes.c_uint32(n).value
        # 正常位移位数是为正数,但是为了兼容js之类的,负数就右移变成左移好了
        if i<0:
            return -int_overflow(n << abs(i))
        #print(n)
        return int_overflow(n >> i)
    
    ret = unsigned_right_shitf(-1,20)
    print(ret)
    
    结果等于4095
    和JS上执行 -1 >>> 20 一样。
    

    相关文章

      网友评论

          本文标题:python3的位移操作

          本文链接:https://www.haomeiwen.com/subject/oftspttx.html