Путаница с бинарным представлением комплимента 1

Я пытался изучить двоичное представление отрицательных чисел. Я попытался вывести 12 и ~ 12 в двоичном формате.

print(~12)

Выход:

-13

Это было дополнением 1 к 12.

Но я сомневаюсь, что двоичное число 12 равно 1100 и -13 (дополнение 1 до 1) равно 0011, но 3 также равно 0011 в двоичном формате. Это было очень запутанным для меня.

Как -13 и 3 могут иметь одинаковые двоичные значения?


person Gaurav    schedule 14.09.2020    source источник
comment
comment
12 в двоичном формате — это все нули, кроме 4-битного и 8-битного. -13 в двоичном формате - это все единицы, кроме этих битов. Это не 0011. Это 11...110011.   -  person khelwood    schedule 14.09.2020
comment
Вы игнорируете подписанные/беззнаковые и ширину. 12 равно 1100 в четырехбитном двоичном формате без знака. В этом представлении нет дополнения до двух, и 0011 однозначно равно 3. Вам нужен двоичный пятибитный знак со знаком для представления как 12, так и его дополнения до двух, то есть 01100 и 10011 соответственно. В этом представлении 00011 однозначно равно 3.   -  person MisterMiyagi    schedule 14.09.2020
comment
@MisterMiyagi - извините за глупый вопрос. Существует ли эмпирическое правило (само по себе) вне данного контекста для идентификации 10011 как пятибитного двоичного кода со знаком для ~ 12, а не 19?   -  person S3DEV    schedule 14.09.2020
comment
Обратите внимание, что ~ не является дополнением до 1. Он определяется как ~x == -(x+1), что соответствует дополнению 2 произвольной точности.   -  person MisterMiyagi    schedule 14.09.2020
comment
@ S3DEV Нет. Двоичный код — как последовательность битов — может означать буквально что угодно. Нет никакой гарантии, что 10011 является даже числом, это также может быть глиф ASCII CR или первая половина глифа UTF-8 . Идя дальше, вы технически должны знать порядок следования байтов и битов — 10011 может быть 25 в целочисленном беззнаковом порядке следования байтов.   -  person MisterMiyagi    schedule 14.09.2020
comment
Имеет смысл, спасибо.   -  person S3DEV    schedule 14.09.2020


Ответы (1)


TLDR: -13 и 3 не имеют одинаковых двоичных значений. Путаница возникает из-за игнорирования явного знака и заполнения/ширины.


Целые числа Python ведут себя как беззнаковые двоичные числа произвольной ширины с отдельным битом знака. Не существует общего однозначного двоичного представления для чисел со знаком.

Например, 12 — это число ...1100 и знак +, а -12 — это то же число ...1100, но со знаком -. Примечательно, что ... может состоять из произвольного количества начальных цифр — 1100, 01100, 001100 и так далее — это одно и то же число. Это 0-заполнение позволяет обрабатывать как маленькие, так и большие числа, например. по крайней мере 4-значный 12 ...1100 может быть выровнен по крайней мере с 5-значным 16 ...10000.

Это означает, что не может быть определенного бита начального знака, поскольку каждой позиции может предшествовать другой 0. Вместо этого бит знака произвольно предшествует числу: 0...1100 или +...1100 равно 12, а 1...1100 или -...1100 равно -12. Это видно в каноническом побитовом представлении чисел, разделяющих знак и абсолютное значение.

>>> bin(12)
0b1100
>>> bin(-12)
-0b1100

Таким образом, 4-значное побитовое дополнение 12 равно -0011, а 3 равно +0011.

person MisterMiyagi    schedule 14.09.2020