Читая ответы на этот вопрос, я наткнулся на этот комментарий [отредактировано].
Дополнение 2 к 0100 (4) будет 1100. Теперь 1100 - это 12, если я скажу нормально. Итак, когда я говорю нормальное 1100, тогда это 12, но когда я говорю, что 2 дополняют 1100, тогда это -4? Кроме того, в Java, когда хранится 1100 (предположим, что на данный момент 4 бита), то как определяется, что это +12 или -4 ?? - Хагравал 2 июля в 16:53
На мой взгляд, вопрос, заданный в этом комментарии, довольно интересен, и поэтому я хотел бы сначала перефразировать его, а затем дать ответ и пример.
ВОПРОС - Как система может установить, как один или несколько смежных байтов должны интерпретироваться? В частности, как система может установить, является ли данная последовательность байтов простым двоичным числом или номером дополнения 2?
ОТВЕТ - Система устанавливает, как интерпретировать последовательность байтов через типы. Типы определяют
- сколько байтов нужно учитывать
- как эти байты должны быть интерпретированы
ПРИМЕР - Ниже мы предполагаем, что
char
длиной 1 байт
short
длиной 2 байта
int
s и float
s длиной 4 байта
Обратите внимание, что эти размеры относятся к моей системе. Хотя они довольно распространены, они могут отличаться от системы к системе. Если вам интересно, что они в вашей системе, используйте оператор sizeof .
Прежде всего, мы определяем массив, содержащий 4 байта, и инициализируем их все двоичным числом 10111101
, соответствующим шестнадцатеричному числу BD
.
// BD(hexadecimal) = 10111101 (binary)
unsigned char l_Just4Bytes[ 4 ] = { 0xBD, 0xBD, 0xBD, 0xBD };
Затем мы читаем содержимое массива, используя разные типы.
unsigned char
и signed char
// 10111101 as a PLAIN BINARY number equals 189
printf( "l_Just4Bytes as unsigned char -> %hi\n", *( ( unsigned char* )l_Just4Bytes ) );
// 10111101 as a 2'S COMPLEMENT number equals -67
printf( "l_Just4Bytes as signed char -> %i\n", *( ( signed char* )l_Just4Bytes ) );
unsigned short
и short
// 1011110110111101 as a PLAIN BINARY number equals 48573
printf( "l_Just4Bytes as unsigned short -> %hu\n", *( ( unsigned short* )l_Just4Bytes ) );
// 1011110110111101 as a 2'S COMPLEMENT number equals -16963
printf( "l_Just4Bytes as short -> %hi\n", *( ( short* )l_Just4Bytes ) );
unsigned int
, int
иfloat
// 10111101101111011011110110111101 as a PLAIN BINARY number equals 3183328701
printf( "l_Just4Bytes as unsigned int -> %u\n", *( ( unsigned int* )l_Just4Bytes ) );
// 10111101101111011011110110111101 as a 2'S COMPLEMENT number equals -1111638595
printf( "l_Just4Bytes as int -> %i\n", *( ( int* )l_Just4Bytes ) );
// 10111101101111011011110110111101 as a IEEE 754 SINGLE-PRECISION number equals -0.092647
printf( "l_Just4Bytes as float -> %f\n", *( ( float* )l_Just4Bytes ) );
4 байта в оперативной памяти (l_Just4Bytes[ 0..3 ]
) всегда остаются одинаковыми. Единственное, что меняется, это то, как мы их интерпретируем.
Опять же, мы говорим системе, как интерпретировать их через типы .
Например, выше мы использовали следующие типы для интерпретации содержимого l_Just4Bytes
массива
unsigned char
: 1 байт в простом двоичном
signed char
: 1 байт в 2-х дополнениях
unsigned short
: 2 байта в простой двоичной записи
short
: 2 байта в дополнении 2
unsigned int
: 4 байта в простой двоичной записи
int
: 4 байта в дополнении 2
float
: 4 байта в нотации IEEE 754 с одинарной точностью
[EDIT] Это сообщение было отредактировано после комментария user4581301. Спасибо, что нашли время, чтобы отбросить эти несколько полезных строк!