Читая ответы на этот вопрос, я наткнулся на этот комментарий [отредактировано].
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
и float
имеют длину 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. Спасибо, что нашли время отбросить эти несколько полезных строк!