Aritmética de Inteiros
Cada uma das operações aritméticas básicas em C tem duas variantes para inteiros: com e sem sinal. A escolha é determinada pelos tipos de dados de seus operandos.
Cada tipo de dado inteiro em C é ou signed (com sinal) ou unsigned (sem sinal). Um tipo com sinal pode conter um intervalo de números positivos e negativos, com o zero próximo ao meio do intervalo. Um tipo sem sinal pode conter apenas números não negativos; seu intervalo começa em zero e vai para cima.
Os tipos inteiros mais básicos são int
, que normalmente pode conter números de -2.147.483.648 a 2.147.483.647, e o unsigned int
, que normalmente pode conter números de 0 a 4.294.967.295. (Isso assume que int
tem 32 bits de largura, o que é sempre verdadeiro para GNU C em computadores reais, mas nem sempre em controladores embarcados.) Veja , para informações completas sobre tipos inteiros.
Quando uma operação aritmética básica recebe dois operandos com sinal, ela realiza aritmética com sinal. Quando recebe dois operandos sem sinal, realiza aritmética sem sinal.
Se um operando for unsigned int
e o outro int
, o operador trata ambos como sem sinal. De maneira mais geral, o tipo comum dos operandos determina se a operação é sinalizada ou não. .
Imprimir os resultados de uma aritmética sem sinal com printf
usando ‘%d’ pode produzir resultados surpreendentes para valores distantes de zero. Mesmo que as regras acima digam que a computação foi feita com aritmética sem sinal, o resultado impresso na tela pode parecer com sinal!
A explicação é que o padrão de bits resultante de uma adição, subtração ou multiplicação é, na verdade, o mesmo para operações com e sem sinal. A diferença está apenas no tipo de dado do resultado, que afeta a interpretação do padrão de bits resultante e se a operação aritmética pode ou não causar um estouro (veja a próxima seção).
Mas ‘%d’ não sabe o tipo de dado de seu argumento. Ele vê apenas o padrão de bits do valor e está definido para interpretá-lo como signed int
. Para imprimi-lo como sem sinal, é necessário usar ‘%u’ em vez de ‘%d’. Veja The GNU C Library no The GNU C Library Reference Manual (disponível somente em inglês).
A aritmética em C nunca opera diretamente em tipos inteiros estreitos (aqueles com menos bits que int
; veja ). Em vez disso, ela os "promove" para int
. Veja .
Atualizado