Объединение двух 32-битных int для получения 64-битной длины в Python - PullRequest
6 голосов
/ 24 августа 2010

Я хочу создать int длиной 64 бита, который будет служить уникальным идентификатором для документов.

Одна идея состоит в том, чтобы объединить идентификатор пользователя, который является 32-битным целым, с меткой времени Unix, который является еще 32-битным целым, для образования уникального 64-битного целого числа.

Уменьшенный пример будет:

Объедините два 4-битных числа 0010 и 0101, чтобы сформировать 8-битное число 00100101.

  1. Имеет ли эта схема смысл?
  2. Если да, как мне выполнить «объединение» чисел в Python?

Ответы [ 5 ]

16 голосов
/ 24 августа 2010

Сдвиньте влево первое число на количество бит во втором номере, затем добавьте (или побитовое ИЛИ - замените + на | в следующих примерах) второе число.

result = (user_id << 32) + timestamp

Что касается вашего уменьшенного примера,

>>> x = 0b0010
>>> y = 0b0101
>>> (x << 4) + y
37
>>> 0b00100101
37
>>>
5 голосов
/ 24 августа 2010
foo = <some int>
bar = <some int>

foobar = (foo << 32) + bar
4 голосов
/ 24 августа 2010

Это должно сделать это:

(x << 32) + y
2 голосов
/ 18 декабря 2012

Для следующего парня (который был мной в этом случае был я). Вот один из способов сделать это в целом (для уменьшенного примера):

def combineBytes(*args):
    """
    given the bytes of a multi byte number combine into one
    pass them in least to most significant 
    """
    ans = 0
    for i, val in enumerate(args):
        ans += (val << i*4)
    return ans

для других размеров замените 4 на 32 или что-то еще.

>>> bin(combineBytes(0b0101, 0b0010))
'0b100101'
0 голосов
/ 11 января 2019

Ни один из ответов до этого не охватывает слияние и разбиение чисел. Разделение может быть такой же необходимостью, как и слияние.

NUM_BITS_PER_INT = 4  # Replace with 32, 48, 64, etc. as needed.
MAXINT = (1 << NUM_BITS_PER_INT) - 1

def merge(a, b):
    c = (a << NUM_BITS_PER_INT) | b
    return c

def split(c):
    a = (c >> NUM_BITS_PER_INT) & MAXINT
    b = c & MAXINT
    return a, b

# Test
EXPECTED_MAX_NUM_BITS = NUM_BITS_PER_INT * 2
for a in range(MAXINT + 1):
    for b in range(MAXINT + 1):
        c = merge(a, b)
        assert c.bit_length() <= EXPECTED_MAX_NUM_BITS
        assert (a, b) == split(c)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...