Вот в чем проблема. Ожидаю в результате -100. Из других вопросов о stackoverflow я понял, что Python использует дополнение до 2 для отрицательных чисел. Как мне преобразовать строку в 64-битное число?
Использование Python3 под Windows.
Python 3.10.6 (tags/v3.10.6:9c7b4bd, Aug 1 2022, 21:53:49) [MSC v.1932 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> int('FFFFFFFFFFFFFF9C',16)
18446744073709551516
>>> int('0000000000000064',16)
100
Ваше предположение неверно. Дополнение до 2 означает, что старший бит определяет знак числа. Целые числа Python имеют неограниченный диапазон, т.е. неограниченное количество битов, поэтому старшего бита нет.
См. также int.to_bytes(8), чтобы преобразовать число Python в 8 байт/64 бита (если возможно, вы можете получить OverflowError
)
Предыдущий ответ о том, что у Python нет старшего бита, верен: числа не ограничиваются 64 битами. Но если вы знаете, что ваш ввод 64-битный, есть обходной путь:
def convert_to_64_bits(hex_num):
return (int(hex_num, 16) & 0x7fffffffffffffff) - (int(hex_num, 16) & 0x8000000000000000)
Это явно отделяет 64-й бит от остальной части числа и использует его для корректировки результата. Функция легко настраивается для работы с битами других размеров.
На самом деле, вместо того, чтобы просто говорить, что это просто, я просто дам вам версию функции, которая принимает количество битов в качестве параметра.
def convert_hex(hex_num, num_bits=64):
sign_mask = 1 << (num_bits - 1)
value_mask = sign_mask - 1
return (int(hex_num, 16) & value_mask) - (int(hex_num, 16) & sign_mask)
это хорошо, потому что дает возможность выполнить преобразование с произвольным количеством бит!
Как указано в других ответах: целые числа Python не ограничены по размеру, поэтому при прямом преобразовании в целое число нет «сигнального бита».
Один из способов получить 64-битное целое число из C — использовать встроенный класс bytes
: сначала принять шестнадцатеричную строку, а затем преобразовать ее в объект Python int
, но с учетом битовой информации:
a = 'FFFFFFFFFFFFFF9C'
int.from_bytes(bytes.fromhex(a), "big", signed=True)
Этот метод позволяет Python учитывать информацию о знаках при преобразовании.
Также обратите внимание, что объект промежуточных байтов располагается в памяти в порядке, обратном тому, который используется текущими процессорами — это не проблема, поскольку порядок байтов является обязательным аргументом в .from_bytes
, но будьте осторожны, если вы собираетесь хранить эти байты в двоичном файле для потребление в другом месте.
обязательно, только если вы используете старый Python
Я не знал, что это больше не является обязательным. В любом случае, то, что значение по умолчанию отличается от собственных целых чисел ЦП, немного противоречит здравому смыслу (по умолчанию в архитектуре x86 оно имеет значение «большой»), поэтому, возможно, добавлять его каждый раз явно — неплохая идея.
Не только «на архитектуре x86», а везде.
«Python использует дополнение до двух для отрицательных чисел» — Где вы это видели? Это не правильно, поэтому я думаю, что вы что-то неправильно поняли. Например, Python использует дополнение до двух для инвертирования целого числа (
~k == -k-1
), но не для хранения целого числа.