为什么按位左移在Python和Java中返回不同的结果? [英] Why does bit-wise shift left return different results in Python and Java?

查看:242
本文介绍了为什么按位左移在Python和Java中返回不同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将某些功能从Java应用程序移植到Python.

I'm trying to port some functionality from a Java app to Python.

在Java中,

System.out.println(155 << 24);

返回:-1694498816

Returns: -1694498816

在Python中:

print(155 << 24)

返回2600468480

Returns 2600468480

在这两种语言中,许多其他按位运算也以相同的方式工作.为什么这两个操作会有不同的结果?

Many other bitwise operations have worked in the same way in both languages. Why is there a different result in these two operations?

我正在尝试在python中创建一个函数来复制左移运算符在Java中的工作方式.类似于:

I'm trying to create a function in python to replicate how the left shift operator works in Java. Something along the lines of:

def lshift(val, n):
    return (int(val) << n) - 0x100000000

但是,这似乎不正确,因为(我认为)所有数字都变为负数?

However this doesn't seem right as (I think) it turns all numbers negatives?

几个小时后,我认为使用Python来完成这项工作可能不是最好的主意,并将加入Java应用程序并将其用作现有Python应用程序的微服务.

Several hours later, I've decided it is probably not the best idea to use Python for this job and will take part of the Java application and use it as a micro service for the existing Python app.

推荐答案

以下是将Python整数转换为等效的Java符号int的3种不同方法.请注意,如果参数的宽度大于32位,这些函数将不能正常工作,因此您可能希望在调用它们之前对参数使用位掩码.

Here are 3 different ways to convert a Python integer to its equivalent Java signed int. Note that these functions will not work correctly if the argument is wider than 32 bits, so you may wish to use bit masking on the argument before calling them.

第一种方法是使用struct模块将数字解释为32位无符号整数,将其打包为字节(使用本地字节序约定),然后解压缩这些字节,将其解释为32位有符号整数整数.另外两种方法使用简单的算术,没有函数调用,因此它们更快,但是我想它们更难阅读.

The first way is to use the struct module to interpret the number as a 32 bit unsigned integer, pack it into bytes (using the local endian convention), and then unpack those bytes, interpreting them as a 32 bit signed integer. The other two methods use simple arithmetic with no function calls, so they are faster, but I guess they are a little harder to read.

这段代码是在运行Python 2.6.6的32位计算机上编写的,但是它应该可以在任何体系结构和版本的Python上正确运行(除非它是 extremely Ancient :)).

This code was written on a 32 bit machine running Python 2.6.6, but it should run correctly on any architecture and version of Python (unless it's extremely ancient :) ).

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

这篇关于为什么按位左移在Python和Java中返回不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆