Почему Python возвращает 64-битное отрицательное число как очень большое положительное число?

Вот в чем проблема. Ожидаю в результате -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

«Python использует дополнение до двух для отрицательных чисел» — Где вы это видели? Это не правильно, поэтому я думаю, что вы что-то неправильно поняли. Например, Python использует дополнение до двух для инвертирования целого числа (~k == -k-1), но не для хранения целого числа.

wjandrea 16.07.2024 18:10
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
72
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ваше предположение неверно. Дополнение до 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)

это хорошо, потому что дает возможность выполнить преобразование с произвольным количеством бит!

jsbueno 17.07.2024 14:49
Ответ принят как подходящий

Как указано в других ответах: целые числа Python не ограничены по размеру, поэтому при прямом преобразовании в целое число нет «сигнального бита».

Один из способов получить 64-битное целое число из C — использовать встроенный класс bytes: сначала принять шестнадцатеричную строку, а затем преобразовать ее в объект Python int, но с учетом битовой информации:

a = 'FFFFFFFFFFFFFF9C' 
int.from_bytes(bytes.fromhex(a), "big", signed=True)

Этот метод позволяет Python учитывать информацию о знаках при преобразовании.

Также обратите внимание, что объект промежуточных байтов располагается в памяти в порядке, обратном тому, который используется текущими процессорами — это не проблема, поскольку порядок байтов является обязательным аргументом в .from_bytes, но будьте осторожны, если вы собираетесь хранить эти байты в двоичном файле для потребление в другом месте.

обязательно, только если вы используете старый Python

no comment 16.07.2024 18:11

Я не знал, что это больше не является обязательным. В любом случае, то, что значение по умолчанию отличается от собственных целых чисел ЦП, немного противоречит здравому смыслу (по умолчанию в архитектуре x86 оно имеет значение «большой»), поэтому, возможно, добавлять его каждый раз явно — неплохая идея.

jsbueno 17.07.2024 14:48

Не только «на архитектуре x86», а везде.

no comment 17.07.2024 14:55

Другие вопросы по теме