为什么按位左移 return 在 Python 和 Java 中得到不同的结果?
Why does bit-wise shift left return different results in Python and Java?
我正在尝试将某些功能从 Java 应用移植到 Python。
在Java,
System.out.println(155 << 24);
Returns:-1694498816
在Python中:
print(155 << 24)
Returns 2600468480
许多其他按位运算在这两种语言中的工作方式相同。为什么这两个操作会有不同的结果?
编辑:我正在尝试在 python 中创建一个函数来复制左移运算符在 Java 中的工作方式。大致如下:
def lshift(val, n):
return (int(val) << n) - 0x100000000
但这似乎不对,因为(我认为)它将所有数字都变成负数?
EDIT2:几个小时后,我决定将 Python 用于这项工作可能不是最好的主意,并将参与 Java 应用程序并将其用作微型现有 Python 应用程序的服务。
Java 具有 32 位固定宽度整数,因此 155 << 24
移动 155
的最高设置位(即第 7 位,从零开始计数,因为 155 更大比 27 但小于 28) 进入符号位(第 31 位),你最终得到一个负数。
Python 具有任意精度整数,因此 155 << 24
在数值上等于正数 155 × 224
在java中使用long得到相同的结果
System.out.println(155L << 24);
而不是
System.out.println(155 << 24);
Long 是 4 字节长度,因此此上下文的精度与 python 整数相同。
这里有 3 种不同的方法可以将 Python 整数转换为其等效的 Java 有符号 int
。请注意,如果参数的宽度超过 32 位,这些函数将 not 正常工作,因此您可能希望在调用它们之前对参数使用位掩码。
第一种方法是使用struct
模块将数字解释为32位无符号整数,将其打包成字节(使用本地字节序约定),然后解包这些字节,将它们解释为一个 32 位有符号整数。其他两种方法使用没有函数调用的简单算术,所以它们更快,但我想它们更难阅读。
此代码是在 32 位机器 运行ning Python 2.6.6 上编写的,但它应该 运行 在 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()
输出
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
我正在尝试将某些功能从 Java 应用移植到 Python。
在Java,
System.out.println(155 << 24);
Returns:-1694498816
在Python中:
print(155 << 24)
Returns 2600468480
许多其他按位运算在这两种语言中的工作方式相同。为什么这两个操作会有不同的结果?
编辑:我正在尝试在 python 中创建一个函数来复制左移运算符在 Java 中的工作方式。大致如下:
def lshift(val, n):
return (int(val) << n) - 0x100000000
但这似乎不对,因为(我认为)它将所有数字都变成负数?
EDIT2:几个小时后,我决定将 Python 用于这项工作可能不是最好的主意,并将参与 Java 应用程序并将其用作微型现有 Python 应用程序的服务。
Java 具有 32 位固定宽度整数,因此 155 << 24
移动 155
的最高设置位(即第 7 位,从零开始计数,因为 155 更大比 27 但小于 28) 进入符号位(第 31 位),你最终得到一个负数。
Python 具有任意精度整数,因此 155 << 24
在数值上等于正数 155 × 224
在java中使用long得到相同的结果
System.out.println(155L << 24);
而不是
System.out.println(155 << 24);
Long 是 4 字节长度,因此此上下文的精度与 python 整数相同。
这里有 3 种不同的方法可以将 Python 整数转换为其等效的 Java 有符号 int
。请注意,如果参数的宽度超过 32 位,这些函数将 not 正常工作,因此您可能希望在调用它们之前对参数使用位掩码。
第一种方法是使用struct
模块将数字解释为32位无符号整数,将其打包成字节(使用本地字节序约定),然后解包这些字节,将它们解释为一个 32 位有符号整数。其他两种方法使用没有函数调用的简单算术,所以它们更快,但我想它们更难阅读。
此代码是在 32 位机器 运行ning Python 2.6.6 上编写的,但它应该 运行 在 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()
输出
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