代码之家  ›  专栏  ›  技术社区  ›  Alex L

为什么在Python和Java中按位左移返回不同的结果?

  •  13
  • Alex L  · 技术社区  · 10 年前

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

    在Java中,

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

    返回:-1694498816

    在Python中:

    print(155 << 24)
    

    退货2600468480

    在这两种语言中,许多其他按位操作都以相同的方式工作。为什么这两种操作的结果不同?


    编辑:我试图在python中创建一个函数,以复制左移位运算符在Java中的工作方式。大致如下:

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

    然而,这似乎并不正确,因为(我认为)它会让所有数字都变成负数?


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

    3 回复  |  直到 10 年前
        1
  •  21
  •   Steve Jessop    10 年前

    Java有32位固定宽度整数,因此 155 << 24 移位的最高设置位 155 (这是位7,从零开始计数位,因为155大于2 7. 但小于2 8. )输入符号位(第31位),结果是负数。

    Python具有任意精度整数,因此 155<&书信电报;24 数值等于正数1552 24

        2
  •  5
  •   PM 2Ring    10 年前

    以下是将Python整数转换为等效Java签名的3种不同方法 int 。请注意,这些功能将 如果参数大于32位,则可以正常工作,因此您可能希望在调用参数之前对其使用位掩码。

    第一种方法是使用 struct 模块将数字解释为32位无符号整数,将其打包为字节(使用本地endian约定),然后解压缩这些字节,将其解释为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()
    

    输出

     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
    
        3
  •  1
  •   Davide Lorenzo MARINO    10 年前

    在java中使用long可以得到相同的结果

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

    而不是

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

    Long的长度为4字节,因此此上下文的精度与python整数相同。