Нет, не спрашивайте меня, является ли endian сети большим или little endian ...

hon длинные целые числа имеют неограниченную точность. Я хотел бы написать 16-байтовое (128-битное) целое число в файл.struct из стандартной библиотеки поддерживает только до 8 байтов целых чисел.array имеет такое же ограничение. Есть ли способ сделать это без маскировки и сдвига каждого целого числа?

Вот некоторые пояснения: я пишу в файл, который будет читаться из не-Python-программ, так что pickle отсутствует. Все 128 бит используются.

 Mark Byers12 янв. 2011 г., 16:19
Похоже, он уже сделал это -Структура из стандартной библиотеки поддерживает только до 8 байтовых чисел.
 ulrichb12 янв. 2011 г., 16:21
Вам нужен весь 128-битный диапазон или только младшие 64 бита, вам нужны целые числа со знаком?

Ответы на вопрос(8)

int.to_bytes а такжеint.from_bytes: https://docs.python.org/3/library/stdtypes.html#int.to_bytes

но я не понимаю, почему вы не можете использовать struct:

bigint = 0xFEDCBA9876543210FEDCBA9876543210L
print bigint,hex(bigint).upper()

cbi = struct.pack("!QQ",bigint&0xFFFFFFFFFFFFFFFF,(bigint>>64)&0xFFFFFFFFFFFFFFFF)

print len(cbi)

Bigint сам по себе отклоняется, но если вы замаскируете его с помощью & 0xFFFFFFFFFFFFFFFF, вы можете уменьшить его до 8-байтового int вместо 16. Затем верхняя часть также смещается и маскируется. Возможно, вам придется немного поиграть с порядком байтов. Я использовал! Отметьте, чтобы сообщить, что для создания порядкового байтового порядка в сети. Кроме того, msb и lsb (верхний и нижний байты), возможно, придется поменять местами. Я оставлю это как упражнение для определения пользователем. Я бы сказал, что сохранять вещи как сетевой порядок будет безопаснее, чтобы вы всегда знали, что такое ваши данные.

Нет, не спрашивайте меня, является ли endian сети большим или little endian ...

Почему бы не использовать структуру сбез знака длинный длинный типа дважды?

import struct
some_file.write(struct.pack("QQ", var/(2**64), var%(2**64)))

Это задокументировано здесь (прокрутите вниз, чтобы получить таблицу с Q):http://docs.python.org/library/struct.html

число». Я не уверен, что избегать маски и смещения означает в контексте длинных значений Python.

Байты такие:

def bytes( long_int ):
    bytes = []
    while long_int != 0:
        b = long_int%256
        bytes.insert( 0, b )
        long_int //= 256
    return bytes

Затем вы можете упаковать этот список байтов, используяstruct.pack( '16b', bytes )

 mlvljr25 мая 2011 г., 15:48
Это может выглядеть даже лучше сlong_int, b = divmod(long_int, 256) :)
 Apalala12 янв. 2011 г., 16:47
Идея более или менее в порядке, но код неверен.
 S.Lott12 янв. 2011 г., 17:50
@ Апалала, @ Свен Марнах. Благодарю.
 S.Lott12 янв. 2011 г., 17:08
"инвалид"? Не могли бы вы быть более конкретным, чтобы я мог это исправить?
 Sven Marnach12 янв. 2011 г., 17:27
Существует некоторая путаница с именами переменных (n противlong_int). Кроме того, вы, вероятно, должны использоватьn //= 256 или жеn >>= 8 или жеn, b = divmod(n, 256) вместоn /= 256 чтобы предотвратить (почти) бесконечный цикл в Python 3 (или когда передается число с плавающей точкой).

использовать буферы протокола (хотя я не знаю, позволяют ли они сериализовать целые числа с неограниченной точностью) или BSON, если вы не хотите писать код.

Но написание функции, которая выводит 16-байтовые целые числа путем сдвига, не должно быть таким трудным, если это не критично ко времени.

PyPi bitarray модуль в сочетании со встроеннымbin() Функция кажется хорошей комбинацией для простого и гибкого решения.

Порядковый номер можно контролировать с помощью нескольких строк кода. Вам придется оценить эффективность.

 Bailey Parker30 июн. 2018 г., 20:57
Быть осторожен!bin() производит что-то вроде0b0101110так что вам нужно обрезать0b префикс.
 Bailey Parker30 июн. 2018 г., 20:58
Вы также хотитеtobytes() неtostring().

что для целых чисел без знака (и игнорируя порядковый номер) что-то вроде

import binascii

def binify(x):
    h = hex(x)[2:].rstrip('L')
    return binascii.unhexlify('0'*(32-len(h))+h)

>>> for i in 0, 1, 2**128-1:
...     print i, repr(binify(i))
... 
0 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
340282366920938463463374607431768211455 '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'

может технически удовлетворить требования наличия не-специфичного для Python вывода, не использовать явную маску и (я предполагаю) не использовать какие-либо нестандартные модули. Хотя не особенно элегантно.

 Score_Under27 июл. 2013 г., 14:27
Это не удается для отрицательного ввода:hex(x) возвращается-0x123 например.
 DSM27 июл. 2013 г., 22:07
@Score_Under: в самом первом предложении написано "для целых чисел без знака".
Решение Вопроса

Только чтосоленый огурец ваше длинное целое число Это запишет целое число в специальном формате, который позволяет читать его снова, если это все, что вы хотите.

Используйте второй фрагмент кода вэтот ответ преобразовать long int в строку с прямым порядком байтов (которую можно легко изменить на little-endian, если вы предпочитаете) и записать эту строку в свой файл.

Проблема в том, что внутреннее представление bigints напрямую не включает запрашиваемые вами двоичные данные.

Ваш ответ на вопрос