#include int main() { int a=32; printf("%d\n", ~a); //line 2 return 0; } o/p = -33
Фактически в исходном fragmentе 2 была
printf("%x\n", ~a); //line 2
Я решил это как
32 in hex is 20. 0000 0000 0010 0000 now tilde operator complements it 1111 1111 1101 1111 = ffdf.
Я смущен, как его решить, когда у меня есть
printf("%d\n", ~a); //line 2 ie %d NOT %x.
В вашей реализации C, как и в большинстве современных реализаций любого языка программирования, целые числа со знаком представлены с двумя дополнениями .
В дополнении два, высокий бит указывает отрицательное число, и значения кодируются так же, как в этих образцах:
Bits Decimal 0…011 +3 0…010 +2 0…001 +1 0…000 0 1…111 -1 1…110 -2 1…101 -3
Таким образом, если обычное (беззнаковое) двоичное значение для бит равно n, а старший бит равен нулю, представленное значение равно + n . Однако, если высокий бит равен единице, то представленное значение равно n -2 w , где w – ширина (количество бит в формате).
Таким образом, в 32-битном формате без знака 32 одного бита обычно составляют 4 294 967 295. В 32-битном формате с двумя дополнениями 32 одного бита составляют 4 294 967 295 – 2 32 = -1.
В вашем случае у вас есть бит 1111 1111 1111 1111 1111 1111 1101 1111. В 32-битном формате без знака это 4 294 967 263. В дополнение к двум, это 4 294 967 263 – 2 32 = -33.
Вы должны распечатать unsigned
целые числа с помощью спецификатора %u
:
unsigned int a = 32; printf("%u\n", ~a);
Распечатывая его, %d
рассматривает его как целое число со знаком.
Вы видите это как отрицательное число, потому что бит знака устанавливается от 0 до 1 через двоичное отрицание.
Распечатка его как шестнадцатеричного номера не интерпретирует бит знака, поэтому вы видите тот же результат в обоих случаях.
Большинство компьютеров используют представление двух дополнений для отрицательных чисел. См. Здесь: http://en.wikibooks.org/wiki/A-level_Computing/AQA/Problem_Solving,_Programming,_Data_Representation_and_Practical_Exercise/Fundamentals_of_Data_Representation/Two%27s_complement