zoukankan      html  css  js  c++  java
  • ppython的移位操作

    因为要将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 一样。

    附赠sdbm hash算法的python实现

    import ctypes
    
    # equ <<
    def int_overflow(val):
        maxint = 2147483647
        if not -maxint-1 <= val <= maxint:
            val = (val + (maxint + 1)) % (2 * (maxint + 1)) - maxint - 1
        return val
    
    # equ >>>
    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)
    
    
    def hash_sdbm(string):
        hash = 0
        for i in range(len(string)):
            hash = ord(string[i]) + (int_overflow(hash << 6)) + (int_overflow(hash << 16)) -hash
        val = unsigned_right_shitf(hash,0)
        return val
    
    a = hash_sdbm('hello')
    print(a)
    
    # result:684824882
  • 相关阅读:
    Java分层经验
    appium自动化测试之H5页面测试
    appium自动化测试日志收集-logging
    mysql查询实践题
    python每日一练之单元测试
    python每日一练之I/O实现读写csv文件
    python每日一练之读写txt文件
    selenium定位元素后,click不生效的问题。
    selenium自动化测试之浏览器滚动条
    selenium自动化测试之单选、下拉列表、alert弹窗处理、页面刷新
  • 原文地址:https://www.cnblogs.com/navysummer/p/10524637.html
Copyright © 2011-2022 走看看