Representação de Inteiros Com n bits, podemos ter 2 n valores distintos Considerando só inteiros não-negativos (unsigned)a faixa de valores é [0, 2 n -1] Considerando inteiros quaisquer (i <0, i >=0), também tem-se apenas 2 n possíveis valores Opção 1: (bit mais significativo como sinal). Por exemplo n=4: 0000... 0111: 0 a 7 decimal 1001... 1111: -1 a -7 decimal 1000: zero negativo? binário Compl- binário Compl- 2 2 Opção 2: (Complemento a dois) 0000 0 1111-1 Faixa de valores: 0001 1 1110-2 [-2 n-1, 2 n-1-1] 0010 2 1101-3..... 1001-7 0111 7 1000-8 1 Considere n=4 Um modelo Circular 1101 1100 1110-2 -4-3 -5 1011-6 1010 Idéia central: Se x>= 0 rep 2 (x) = x Se x<0 então rep 2 (x) = 2 n +x 1111-1 0000 0 1 0001 Valor complemento a 2 (signed) -7 1001-8 1000 0010 2 3 0011 4 0100 5 0101 6 7 0110 0111 Exemplos: rep 2 (-2) = 2 4-2 = 14 = [1110] rep 2 (-8) = 2 4-8 = 8 = [1000] rep 2 (-1) = 2 4-1 = 15 = [1111] 2
Unsigned x Complemento a dois X w-1, X w-2,...x 3, X 2, X 1, X 0 Unsigned Complemento a 2 w 1 B2U(X) = x i 2 i i=0 B2T(X) = x w 1 2 w 1 + x i 2 i Bit de sinal Em complemento-2, o bit mais significativo indica o sinal 0: inteiro não negativo 1: inteiro negativo w 2 i=0 Se (x >= 0), rep n (x) = x 5 = [00000101] Se (x < 0), rep n (x) = 2 n + x -3 = [11111101] 3 Unsigned UMin = 0 000 00 UMax = 2 w 1 111 1 Faixa de Valores Two s complement TMin = 2 w 1 100 00 TMax = 2 w 1 1 011 1 Outro valor -1 Exemplos para W = 16 111 1 Decimal Hex Binary UMax 65535 FF FF 11111111 11111111 TMax 32767 7F FF 01111111 11111111 TMin -32768 80 00 10000000 00000000-1 -1 FF FF 11111111 11111111 0 0 00 00 00000000 00000000 4
Faixa de Valores Maior e menor inteiros que podemos representar com signed/unsigned g W 8 16 32 64 UMax 255 65,535 4,294,967,295 18,446,744,073,709,551,615 TMax 127 32,767 2,147,483,647 9,223,372,036,854,775,807 TMin -128-32,768-2,147,483,648-9,223,372,036,854,775,808 5 Obter a representação binária de um inteiro negativo Seja x um inteiro negativo: 1. Encontrar a representação de (-x) 2. Inverter bit a bit 3. Somar 1 Exemplo: -5 => 0000 0101 => 1111 1010 => 1111 1011 Por que funciona (para x < 0)? 2 n +x = (2 n -1) (-x) + 1 Complemento bit-a-bit 6
Obter a representação decimal de um hexadecimal negativo (compl-2) Oago algoritmo: o: 1. Converter p/ binário a partir do 0 mais significativo: p.ex. 0xfffffe94 = [tudo1.1110.1001.0100] 2. Obter complemento = [tudo0.0001.0110.1011] 3. Calcular o valor do complemento =2 8 +2 6 +2 5 +2 3 +2 1 +2 0 = 363 4. Inverter sinal e subtrair 1-363 -1 = -364 7 Relacionamento Seja w é o número de bits de x e x w é o bit w Signed (compl-2) para unsigned T2U = * w w (x) x w-1 2 + x T2U w (x) = 2 w + x se x < 0 x se x >= 0 Unsigned para signed (compl.-2) U2T w (x) = - x w-1 * 2 w + x U2T w (x) = x se x < 2 w-1 x -2 w-1 se >= 2 w-1 Estas funções definem um relacionamento entre as duas interpretações, baseadas na mesma representação binária. Exemplo: T2U 4 (-1) = 15; T2U 4 (-8) = 8; etc. 8
Conversão: graficamente T2U: Inversão de ordem negativo positivo ii grande TMax UMax UMax 1 TMax + 1 TMax valores unsigned valores aoes Compl.-2 0 1 2 0 TMin 9 Soma complemento a 2 (exemplo para 4 bits) Em complemento a 2 soma e subtração são identicas: 2 + 3 = 0010 + 0011= 0101 = 5 7+ (-1) = 0111 + 1111 = 0110 = 6 (-2) + (-3) = 1110 + 1101 = 1011 = -5 (-3) + 6 = 1101 + 0110 = 0011 = 3 (-1) + (-1) = 1111 + 1111 = 1110 = (-2) 10
Signed e Unsigned em C Quase todas as arquiteturas representam inteiros em complemento a 2 Isto também vale para constantes; caso precise representação unsigned use sufixo U no final. Exemplo: 0xAA2BU = [1010.1010.0010.1011] > 0 Na conversão (explícita/implícita), o padrão de bits não é afetado mas apenas a interpretação muda. O efeito equivale a aplicar as funções T2U w (x) ou U2T w (x). Com printf, use a diretivas de formatação %d, %u para signed e unsigned, respectivamente. 11 Extensão de Representação Como Converter um número em w bits para w+k bits mantendo o mesmo valor? Regra: Faça k cópias do bit de sinal: X = x w 1,, x w 1, x w 1, x w 2,, x 0 X w X k w 12
Conversão em C Em C, extensão de representação ocorre assim mesmo. Exemplo: short int x = 15213; int ix = (int) x; short int y = -15213; int iy = (int) y; Decimal Hex Binary x 15213 3B 6D 00111011 01101101 ix 15213 00 00 3B 6D 00000000 00000000 00111011 01101101 y -15213 C4 93 11000100 10010011 iy -15213 FF FF C4 93 11111111 11111111 11000100 10010011 13 Truncamento de Inteiros Quando truncamos um int x representado em 32 bits para 16 bits, simplesmente removemos os 16 bits mais significativos. Mas o truncamento t geralmente (e naturalmente) t altera o valor do inteiro. Quando x é unsigned, (short) x = x mod 2 16 Quando x é signed (Compl-2), os bits menos significativos são simplesmente interpretados como complemento a dois! Exemplo (truncamento 8 bits para 4 bits): x = [10011001] = -103 (short) x = [1001] = -7 14
Conversões unsigned/signed em C Explícita casting int tx; unsigned ux; tx = (int) ux; ux = (unsigned) tx; Impícita na atribuição & operadores relacionais contendo ambos os tipos se um dos operandos for unsigned, C convente o outro também para unsigned. int tx; unsigned ux; tx = ux; /* signed*/ ux = tx; /* unsigned*/ -1 < 0u /* unsigned -> falso */ 15 Operadores relacionais Operadores de comparação (<, ==, >, etc.) levam em conta se operandos são unsigned ou compl.-2. Exemplo: int a[2] = {-1, 0}; if (a[0] <a[1]) true unsigned int z=0; if (a[0] < z) false Em assembler, existem instruções específicas para cada representação. Compilador C gera as instruções específicas, dependendo da declaração dos operandos. 16
Soma & Subtração Em Compl.-2 todas as somas e subtrações são feitas usandose um mesmo algorítmo de adição O algoritmo: soma bit a bit, com vai-um A aritmética i módulo 2 n garante que o resultado é sempre correto, mesmo que estejamos somando números de sinais opostos O algoritmo é idêntico para unsigned. Exemplo (para n=3): 1-2 (mod 8) = (1 mod 8)+(-2 mod 8) = 1+6 = 7 = -1 mod 8 [001] - [010] = [001] + [110] = [111] Possível problema: overflow! 17 Overflow em Compl.-2 Quando o resultado (x+y) não é representável em n bits Operandos: w bits Soma real: w+1 bits Descarta bit w+1 + u Se x> 0 e y>0 overflow ocorre se houver carry do penúltimo para o último bit (pois senão resultado seria negativo!) Se x,y tem sinais diferentes, nunca ocorre! Se x<0, y<0, overflow ocorre quando não há carry do penúltimo para o último (mas sempre haverá do último para fora) Portanto, quando os dois carries são diferentes, o hardware marca a condição de overflow. v u + v TAdd w (u, v) 18
Exemplos Para 4 bits: Overflow negativo Overflow negativo Sem overflow sem overflow Overflow positivo Obs: para unsigned, overflow é indicado por outra condição: quando houve carry bit para fora 19