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
  • 相关阅读:
    Android 3.0 r1 API中文文档(108) —— ExpandableListAdapter
    Android 3.0 r1 API中文文档(113) ——SlidingDrawer
    Android 3.0 r1 API中文文档(105) —— ViewParent
    Android 中文 API (102)—— CursorAdapter
    Android开发者指南(4) —— Application Fundamentals
    Android开发者指南(1) —— Android Debug Bridge(adb)
    Android中文API(115)——AudioFormat
    Android中文API(116)——TableLayout
    Android开发者指南(3) —— Other Tools
    Android中文API (110) —— CursorTreeAdapter
  • 原文地址:https://www.cnblogs.com/navysummer/p/10524637.html
Copyright © 2011-2022 走看看