Яка різниця між підписаним та безпідписаним int?
Яка різниця між підписаним та безпідписаним int?
Відповіді:
Як вам, мабуть, відомо, int
s зберігаються всередині двійкового файлу. Зазвичай an int
містить 32 біта, але в деяких середовищах може містити 16 або 64 біта (або навіть інше число, як правило, але не обов'язково степеня два).
Але для цього прикладу давайте розглянемо 4-бітові цілі числа. Крихітний, але корисний для ілюстративних цілей.
Оскільки в такому цілому числі є чотири біти, воно може приймати одне з 16 значень; 16 дорівнює двом до четвертого степеня, або 2 рази 2 рази 2 рази 2. Які це значення? Відповідь залежить від того, чи є це ціле число a signed int
або an unsigned int
. При an unsigned int
значення ніколи не є від’ємним; немає знака, пов’язаного зі значенням. Ось 16 можливих значень чотирибітових unsigned int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
... і ось 16 можливих значень чотирибітових signed int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
Як бачите, для signed int
s найбільш значущим бітом є 1
тоді і тільки тоді, коли число від’ємне. Ось чому для signed int
s цей біт відомий як "знаковий біт".
(unsigned)(-1)
потрібно, щоб це було максимально репрезентабельне значення для unsigned
(незалежно від двійкового подання), що тривіально вірно для доповнення 2, але не для інших подань.
int
і unsigned int
є двома різними цілими типами. ( int
може також позначатися як signed int
або просто signed
; unsigned int
також може позначатися як unsigned
.)
Як випливає з назв, int
це цілий тип із підписом і цілий тип unsigned int
без підпису . Це означає, що int
він здатний представляти від’ємні значення і unsigned int
може представляти лише невід’ємні значення.
Мова С накладає деякі вимоги до діапазонів цих типів. Діапазон int
повинен бути принаймні -32767
.. +32767
, а діапазон unsigned int
повинен бути принаймні 0
.. 65535
. Це означає, що обидва типи повинні мати принаймні 16 біт. У багатьох системах вони складають 32 біти, а в деяких - навіть 64 біти. int
як правило, має додаткове негативне значення через представлення доповнення двох, що використовується більшістю сучасних систем.
Мабуть, найважливішою відмінністю є поведінка арифметики зі знаком та без знака. Для підписаного int
переповнення має невизначену поведінку. Бо unsigned int
немає переповнення; будь-яка операція, яка дає значення поза діапазоном типу, обертається, наприклад, наприклад UINT_MAX + 1U == 0U
.
Будь-який цілий тип, підписаний чи беззнаковий, моделює піддіапазон нескінченного набору математичних цілих чисел. Поки ви працюєте зі значеннями в діапазоні типу, все працює. Коли ви наближаєтесь до нижньої або верхньої межі типу, ви стикаєтесь із розривом, і ви можете отримати несподівані результати. Для підписаних цілих типів проблеми виникають лише для дуже великих від'ємних і додатних значень, що перевищують INT_MIN
і INT_MAX
. Для цілих типів без знаку проблеми виникають при дуже великих додатних значеннях і при нулі . Це може бути джерелом помилок. Наприклад, це нескінченний цикл:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
тому що i
це завжди більше або дорівнює нулю; така природа непідписаних типів. (Усередині циклу, коли i
дорівнює нулю, i--
встановлюється його значення UINT_MAX
.)
Іноді ми заздалегідь знаємо, що значення, яке зберігається у даній цілочисельній змінній, завжди буде позитивним - коли воно використовується лише для підрахунку речей, наприклад. У такому випадку ми можемо оголосити змінну , щоб бути без знака, як і в, unsigned int num student;
. При такому оголошенні діапазон допустимих цілочисельних значень (для 32-розрядного компілятора) зміститься від діапазону -2147483648 до +2147483647 до діапазону від 0 до 4294967295. Таким чином, оголошення цілого числа без знаку майже подвоює розмір найбільшого з можливих значення, яке воно може мати в іншому випадку.
Якщо говорити непрофесійно, беззнаковий int - це ціле число, яке не може бути від'ємним і, отже, має вищий діапазон позитивних значень, який він може прийняти. Підписаний int - це ціле число, яке може бути від’ємним, але має нижчий позитивний діапазон в обмін на більше від’ємних значень, які він може прийняти.
На практиці є дві відмінності:
cout
на C ++ або printf
на C): беззнакове ціле бітове подання інтерпретується як невід’ємне ціле число функціями друку.цей код може ідентифікувати ціле число за допомогою критерію упорядкування:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");