Ale*_*x L 12 python java bit-shift bitwise-operators
我正在尝试将一些功能从Java应用程序移植到Python.
在Java中
System.out.println(155 << 24);
Run Code Online (Sandbox Code Playgroud)
返回:-1694498816
在Python中:
print(155 << 24)
Run Code Online (Sandbox Code Playgroud)
返回2600468480
许多其他按位操作在两种语言中都以相同的方式工作.为什么这两个操作会有不同的结果?
编辑:我正在尝试在python中创建一个函数来复制左移位运算符在Java中的工作方式.有点像:
def lshift(val, n):
return (int(val) << n) - 0x100000000
Run Code Online (Sandbox Code Playgroud)
然而,这似乎不正确(我认为)它会使所有数字都变为负数?
编辑2:几个小时后,我已经决定使用Python来完成这项工作并不是最好的想法,并且会将Java应用程序的一部分用作现有Python应用程序的微服务.
Ste*_*sop 21
Java具有32位固定宽度的整数,因此155 << 24将符号位(位31)的最高设置位155(位7,计数位从零,因为155大于2 7但小于2 8)移位到符号位(位31)以负数结束.
Python具有任意精度的整数,因此155 << 24在数值上等于正数155×2 24
这里有 3 种不同的方法将 Python 整数转换为其等效的 Java 符号int。请注意,如果参数大于 32 位,这些函数将无法正常工作,因此您可能希望在调用它们之前对参数使用位掩码。
第一种方法是使用struct模块将数字解释为 32 位无符号整数,将其打包成字节(使用本地字节序约定),然后将这些字节解包,将它们解释为 32 位有符号整数。另外两种方法使用没有函数调用的简单算术,所以它们更快,但我想它们有点难以阅读。
这段代码是在运行 Python 2.6.6 的 32 位机器上编写的,但它应该可以在任何架构和版本的 Python 上正确运行(除非它非常古老:))。
from __future__ import print_function
from struct import pack, unpack
def ulong_to_long_pack(u):
''' using pack & unpack '''
ubytes = pack('L', u)
return unpack('l', ubytes)[0]
def ulong_to_long_sub(u):
''' using subtraction '''
return u - (1<<32) if u >= (1<<31) else u
def ulong_to_long2_xor(u):
''' using exclusive OR '''
return u ^ ~((1<<32)-1) if u & (1<<31) else u
funcs = (ulong_to_long_pack, ulong_to_long_sub, ulong_to_long2_xor)
# test
for ulong_to_long in funcs:
print(ulong_to_long.__doc__)
u = 2600468480
print(u, ulong_to_long(u))
big = 1<<31
for u in range(big - 3, big + 3):
print(u, ulong_to_long(u))
print()
Run Code Online (Sandbox Code Playgroud)
using pack & unpack
2600468480 -1694498816
2147483645 2147483645
2147483646 2147483646
2147483647 2147483647
2147483648 -2147483648
2147483649 -2147483647
2147483650 -2147483646
using subtraction
2600468480 -1694498816
2147483645 2147483645
2147483646 2147483646
2147483647 2147483647
2147483648 -2147483648
2147483649 -2147483647
2147483650 -2147483646
using exclusive OR
2600468480 -1694498816
2147483645 2147483645
2147483646 2147483646
2147483647 2147483647
2147483648 -2147483648
2147483649 -2147483647
2147483650 -2147483646
Run Code Online (Sandbox Code Playgroud)