Member 14586345 Ответов: 3

В чем разница между unsigned int и int?


всем привет. у меня есть некоторые проблемы с использованием неподписанных ints на языке Си.
когда приведенный ниже код запускается, он выводит 1, Что означает, что это правда. разве -2 больше, чем 5?

Что я уже пробовал:

#include <stdio.h>
#include <math.h>

int main() {

int a=-3 ;

unsigned int b=5 ;

printf("%d",a>b) ;

return 0;
}

Richard MacCutchan

Вы не должны сравнивать подписанные и неподписанные значения, так как они (логически) являются разными типами. Это все равно что сравнивать овец с козами.

3 Ответов

Рейтинг:
16

OriginalGriff

Хотя Jeron1 и F-ES Sitcore (почти) правы, я подумал, что, возможно, какой-то фон поможет вам понять, почему они отличаются.
Целые числа бывают нескольких "размеров", которые обычно связаны с размером машинного слова: в языке Си это обычно означает 8 бит, 16 бит (старый, но все еще используемый), 24 бита (иногда), 32 бита (обычный), 64 бита (часто называемый "длинным") и 128 бит(специалист). Есть, наверное, и покрупнее, но я их не встречал.
Количество битов в целочисленном числе определяет, сколько различных значений оно может содержать:

Bits   Number of different values
  8                                                    256
 16                                                 65,536
 32                                          4,294,967,296
 64                             18,446,744,073,709,551,616
128    340,282,366,920,938,463,463,374,607,431,768,211,456

Проблема в том, что если вам нужны целые числа, вы обычно хотите также положительные и отрицательные числа - это необычно ограничивать себя только положительными значениями.
Таким образом, вы, как правило, получаете два разных "вкуса" целого числа: знаковое и беззнаковое, и количество битов в этом числе не меняется, поэтому количество различных значений не меняется. а это значит, что целые числа без знака могут содержать "большее число" положительных значений, чем целые числа со знаком, но целые числа со знаком могут содержать одинаковое число положительных и отрицательных чисел*, в то время как целые числа без знака вообще не могут содержать никаких отрицательных чисел.

Они делают это, говоря: "если верхний (самый значительный) бит числа равен единице, то число отрицательно."

Например, давайте рассмотрим 4-битные целые числа, чтобы сделать это проще.
      signed                        unsigned
0000  0                              0
0001  1                              1
0010  2                              2
0011  3                              3
0100  4                              4
0101  5                              5
0110  6                              6
0111  7                              7
1000 -8 (or "negative zero")         8
1001 -7                              9
1010 -6                             10
1011 -5                             11
1100 -4                             12
1101 -3                             13
1110 -2                             14
1111 -1                             15
Таким образом, если у вас есть ноль в знаковом 4-битном целочисленном числе, и вы вычитаете единицу, вы получите 1111 (что вы ожидаете в двоичной математике, единственном, с которым играют компьютеры), представляющем -1.
Вычтите еще один и вы получите 1110 или -2
Добавьте 6, и вы получите 0100 или 4.

Важно отметить, что в двоичном коде это одно и то же для знаковых и беззнаковых значений: беззнаковое 0000 меньше единицы по - прежнему 1111, беззнаковое 1111 меньше единицы по-прежнему 1110, беззнаковое 1110 плюс шесть по-прежнему 0100-это просто представление меняется, когда значение используется и "преобразуется" в удобочитаемую форму для представления на дисплее. Внутренняя математика по-прежнему двоична, внутренние значения по-прежнему всего 4 бита (или 8, 16, 32, ...)


- Ну, вроде того. Технически ноль не является ни положительным, ни отрицательным, поэтому вы можете рассматривать его как еще одно отрицательное число, чем положительное. Если только ваша машина / язык не примет концепцию "отрицательный нуль[^]" как отдельная сущность, но это довольно редко в наши дни.


CPallini

5.

CodeWraith

Нет, только 4 за то, что не упомянул в лекции "дополнение одного" или "дополнение двух" и только намекнул на разницу между этими двумя.

OriginalGriff

:скалить зубы:

Рейтинг:
1

jeron1

Он преобразует int в unsigned int, а затем выполняет сравнение. Это int = -3, который является 0xfffffffd (32 бит), который при просмотре без знака равен 4294967293, что больше 5, и, следовательно, сравнение истинно.


CPallini

5.

jeron1

Спасибо :-)

Рейтинг:
0

CPallini

Implicit type promotion rules (это то, что происходит в вашем a>b выражение) - это один из самых хитрых уголков мира. C алгоритмический язык. Например, читать c - неявные правила продвижения типов - переполнение стека[^].