Я использую Visual Studio 2013.
Недавно я попробовал ~
оператор за 1 дополнение:
int a = 10;
cout << ~a << endl;
Выход -11
Но для
unsigned int a = 10;
cout << ~a << endl;
выход 4294967296
Я не понимаю, почему вывод -11
в случае подписанного int
,
Пожалуйста, помогите мне с этим замешательством.
Когда вы помещаете число 10 в 32-разрядное целое число со знаком или без знака, вы получаете
0000 0000 0000 0000 0000 0000 0000 1010
Когда вы отрицаете это, вы получаете
1111 1111 1111 1111 1111 1111 1111 0101
Эти 32 бита означают 4294967285 как целое число без знака или -11 как целое число со знаком (ваш компьютер представляет отрицательные целые числа как Два дополнения). Они также могут означать 32-разрядное число с плавающей запятой или четыре 8-разрядных символа.
Биты не имеют никакого «абсолютного» значения. Они могут представлять что угодно, в зависимости от того, как вы «смотрите» на них (какой у них тип).
~
Оператор выполняет Те-дополнение на его аргумент, и не имеет значения, является ли аргумент целым числом со знаком или без знака. Это просто переворачивает все биты, так
0000 0000 0000 1010 (bin) / 10 (dec)
становится
1111 1111 1111 0101 (bin)
(где, предположительно, эти числа имеют ширину 32 бита — я опустил еще 16 нулей и 1).
Как будет cout
показать результат? Смотрит на оригинальный тип. Для подписанный целое число, самый значимый бит — его знак. Таким образом, результат всегда будет отрицательный (потому что самый важный бит в 10
является 0
). Чтобы отобразить отрицательное число как положительное, вам нужно дополнить их двумя: инвертировать все биты, а затем добавить 1. Например, -1
двоичный 111..111
, отображается как (инвертирование) 000..000
тогда +1: 000..001
, Результат: -1
,
Применяя это к своему дополнению 10
ты получаешь 111..110101
-> обращаясь к 000...001010
, затем добавьте 1
, Результат: -11.
Для неподписанный число, cout
не делает этого (естественно), и поэтому вы получите большое число: максимально возможное целое число минус Оригинальный номер.
В памяти хранится 4294967285 в обоих случаях (4294967296, соответственно, опечатка, 33 бита?), Значение этого числа зависит от того, какую подпись вы используете:
разные интерпретации одного и того же числа.
Вы можете переинтерпретировать его как неподписанный, приведя его к тому же результату:
int a = 10;
cout << (unsigned int) ~a << endl;
Попробуй это
unsigned int getOnesComplement(unsigned int number){
unsigned onesComplement = 1;
if(number < 1)
return onesComplement;
size_t size = (sizeof(unsigned int) * 8 - 1) ;
unsigned int oneShiftedToMSB = 1 << size;
unsigned int shiftedNumber = number;
for ( size_t bitsToBeShifted = 0; bitsToBeShifted < size; bitsToBeShifted++){
shiftedNumber = number << bitsToBeShifted;
if(shiftedNumber & oneShiftedToMSB){
onesComplement = ~shiftedNumber;
onesComplement = onesComplement >> bitsToBeShifted;
break;
}
}
return onesComplement;
}