Ответ 1
Вот три разных способа преобразования целочисленного Python в эквивалентную Java-подпись int
. Обратите внимание, что эти функции будут работать некорректно, если аргумент шире 32 бита, поэтому вы можете использовать бит-маскирование аргумента перед вызовом.
Первый способ - использовать модуль struct
для интерпретации числа в виде 32-битного беззнакового целого числа, упаковать его в байты (используя соглашение с локальным концом), а затем распаковать эти байты, интерпретируя их как 32-битную подписанную целое число. Другие два метода используют простую арифметику без вызовов функций, поэтому они быстрее, но я думаю, их немного труднее читать.
Этот код был написан на 32-битной машине, на которой запущен 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