В чем разница между подписанным и неподписанным int - PullRequest
66 голосов
/ 21 апреля 2011

В чем разница между подписанным и беззнаковым целым?

Ответы [ 5 ]

88 голосов
/ 26 апреля 2011

Как вы, наверное, знаете, int хранятся внутри в двоичном виде.Как правило, int содержит 32 бита, но в некоторых средах может содержать 16 или 64 бита (или даже другое число, обычно, но не обязательно степень двойки).

Но для этого примера давайте посмотрим на4-битные целые числа.Крошечный, но полезный для иллюстрации.

Поскольку в таком целом числе четыре бита, он может принимать одно из 16 значений;16 от двух до четвертой степени или 2 раза 2 раза 2 раза 2. Что это за значения?Ответ зависит от того, является ли это целое число signed int или unsigned int.При 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 с этот бит известен как «знаковый бит».

13 голосов
/ 30 июня 2015

int и unsigned int - два разных целочисленных типа.(int может также упоминаться как signed int, или просто signed; unsigned int также может упоминаться как unsigned.)

Как следует из названия, int является знаковый целочисленный тип, а unsigned int - целое число без знака .Это означает, что int может представлять отрицательные значения, а unsigned int может представлять только неотрицательные значения.

Язык C предъявляет некоторые требования к диапазонам этих типов.Диапазон 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.)

10 голосов
/ 23 ноября 2011

Иногда мы заранее знаем, что значение, хранящееся в данной целочисленной переменной, всегда будет положительным, например, когда оно используется только для подсчета вещей. В таком случае мы можем объявить переменную без знака, как, например, unsigned int num student;. При таком объявлении диапазон допустимых целочисленных значений (для 32-разрядного компилятора) сместится от диапазона -2147483648 до +2147483647 до диапазона от 0 до 4294967295. Таким образом, объявление целого числа как беззнакового почти удваивает размер максимально возможного значение, которое он может хранить в противном случае.

8 голосов
/ 29 июня 2015

В терминах непрофессионалов беззнаковое целое число - это целое число, которое не может быть отрицательным и, следовательно, имеет более высокий диапазон положительных значений, которые оно может принять. Целое число со знаком - это целое число, которое может быть отрицательным, но имеет более низкий положительный диапазон в обмен на более отрицательные значения, которые оно может принимать.

1 голос
/ 11 февраля 2019

На практике есть два различия:

  1. печать (например, с cout в C ++ или printf в C): представление целого разряда без знака интерпретируется какнеотрицательное целое число для функций печати. ​​
  2. упорядочение : упорядочение зависит от подписанной или неподписанной спецификации.

этот код может идентифицировать целое число с использованием критерия упорядочения:

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");
...