Why does bit-wise shift left return different results in Python and Java?

前端 未结 3 1955
遇见更好的自我
遇见更好的自我 2021-02-19 14:05

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

In Java,

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

Returns: -1694498816

3条回答
  •  萌比男神i
    2021-02-19 14:26

    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.

    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.

    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()
    

    output

     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
    

提交回复
热议问题