Qual é a diferença entre assinado e não assinado int?
Qual é a diferença entre assinado e não assinado int?
Respostas:
Como você provavelmente sabe, os ints são armazenados internamente em binário. Normalmente, um intcontém 32 bits, mas em alguns ambientes pode conter 16 ou 64 bits (ou até mesmo um número diferente, geralmente, mas não necessariamente, uma potência de dois).
Mas para este exemplo, vamos olhar para inteiros de 4 bits. Minúsculo, mas útil para fins ilustrativos.
Como há quatro bits nesse número inteiro, ele pode assumir um de 16 valores; 16 é dois à quarta potência, ou 2 vezes 2 vezes 2 vezes 2. Quais são esses valores? A resposta depende se este inteiro é a signed intou an unsigned int. Com um unsigned int, o valor nunca é negativo; não há nenhum sinal associado ao valor. Aqui estão os 16 valores possíveis de um quatro bits 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
... e aqui estão os 16 valores possíveis de um quatro bits 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
Como você pode ver, para signed ints o bit mais significativo é 1se e somente se o número for negativo. É por isso que, para signed ints, esse bit é conhecido como "bit de sinal".
(unsigned)(-1)é necessário que seja o valor máximo representável para unsigned(independente da representação binária), o que é trivialmente verdadeiro para o complemento de 2, mas não para outras representações.
inte unsigned intsão dois tipos inteiros distintos. ( inttambém pode ser referido como signed int, ou apenas signed; unsigned inttambém pode ser referido como unsigned.)
Como o nome implica, inté um assinado tipo inteiro, e unsigned inté um sem assinatura tipo inteiro. Isso significa que inté capaz de representar valores negativos e unsigned intpode representar apenas valores não negativos.
A linguagem C impõe alguns requisitos aos intervalos desses tipos. A faixa de inttem de ser, pelo menos, -32767.. +32767, e o intervalo de unsigned inttem de ser, pelo menos, 0.. 65535. Isso significa que ambos os tipos devem ter pelo menos 16 bits. Eles têm 32 bits em muitos sistemas, ou mesmo 64 bits em alguns. intnormalmente tem um valor negativo extra devido à representação de complemento de dois usada pela maioria dos sistemas modernos.
Talvez a diferença mais importante seja o comportamento da aritmética com sinal vs. sem sinal. Para assinados int, o estouro tem comportamento indefinido. Pois unsigned int, não há transbordamento; qualquer operação que produza um valor fora do intervalo do tipo envolve, por exemplo UINT_MAX + 1U == 0U.
Qualquer tipo de inteiro, com ou sem sinal, modela uma subfaixa do conjunto infinito de inteiros matemáticos. Desde que você trabalhe com valores dentro da faixa de um tipo, tudo funciona. Ao se aproximar do limite inferior ou superior de um tipo, você encontra uma descontinuidade e pode obter resultados inesperados. Para tipos inteiros com sinal, os problemas ocorrem apenas para valores negativos e positivos muito grandes, excedendo INT_MINe INT_MAX. Para tipos inteiros sem sinal, ocorrem problemas para valores positivos muito grandes e em zero . Isso pode ser uma fonte de bugs. Por exemplo, este é um loop infinito:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
porque ié sempre maior ou igual a zero; essa é a natureza dos tipos sem sinal. (Dentro do loop, quando ié zero, i--define seu valor como UINT_MAX.)
Às vezes sabemos de antemão que o valor armazenado em uma determinada variável inteira será sempre positivo - quando está sendo usado apenas para contar coisas, por exemplo. Nesse caso, podemos declarar a variável sem sinal, como em unsigned int num student;,. Com tal declaração, o intervalo de valores inteiros permitidos (para um compilador de 32 bits) mudará do intervalo -2147483648 a +2147483647 para o intervalo 0 a 4294967295. Assim, declarar um número inteiro como não assinado quase duplica o tamanho do maior possível valor que ele pode conter.
Em termos leigos, um int sem sinal é um número inteiro que não pode ser negativo e, portanto, tem um intervalo maior de valores positivos que pode assumir. Um int com sinal é um inteiro que pode ser negativo, mas tem um intervalo positivo inferior em troca de valores mais negativos que pode assumir.
Na prática, existem duas diferenças:
coutem C ++ ou printfem C): a representação do bit inteiro sem sinal é interpretada como um inteiro não negativo pelas funções de impressão.este código pode identificar o inteiro usando o critério de pedido:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");