Читаючи відповіді на це запитання, я натрапив на цей коментар [ред.].
Доповненням 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] Це повідомлення було відредаговано після коментаря користувача4581301. Дякуємо, що знайшли час, щоб скинути ці кілька корисних рядків!