python的移位操作实现详解
因为要将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作为参数继续参与运算 defint_overflow(val): maxint=2147483647 ifnot-maxint-1<=val<=maxint: val=(val+(maxint+1))%(2*(maxint+1))-maxint-1 returnval ret=int_overflow(123456789<<20) print(ret) print(bin(ret)) 现在得到结果是-783286272 二进制:-101110101100000000000000000000
负数使用无符号右移>>>
在JS中,可以使用a>>>b来实现无符号位移,python中没有这个运算符,只能自己实现了
无符号右移>>>,就是将有符号inta和b转为无符号uint后,再进行普通右移>>运算
比如-1的有符号int就是-1,无符号int就是4294967295
我们自己实现>>>可以这样
#无符号右移 importctypes defunsigned_right_shitf(n,i): #数字小于0,则转为32位无符号uint ifn<0: n=ctypes.c_uint32(n).value #正常位移位数是为正数,但是为了兼容js之类的,负数就右移变成左移好了 ifi<0: return-int_overflow(n<>i) ret=unsigned_right_shitf(-1,20) print(ret)
结果等于4095
和JS上执行-1>>>20一样。
附赠sdbmhash算法的python实现
importctypes #equ<< defint_overflow(val): maxint=2147483647 ifnot-maxint-1<=val<=maxint: val=(val+(maxint+1))%(2*(maxint+1))-maxint-1 returnval #equ>>> defunsigned_right_shitf(n,i): #数字小于0,则转为32位无符号uint ifn<0: n=ctypes.c_uint32(n).value #正常位移位数是为正数,但是为了兼容js之类的,负数就右移变成左移好了 ifi<0: return-int_overflow(n<>i) defhash_sdbm(string): hash=0 foriinrange(len(string)): hash=ord(string[i])+(int_overflow(hash<<6))+(int_overflow(hash<<16))-hash val=unsigned_right_shitf(hash,0) returnval a=hash_sdbm('hello') print(a) #result:684824882
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。