sábado, 18 de fevereiro de 2012

Números inteiros

Entender a representação dos números inteiros no computador é extremamente importante para evitar certos problemas de precisão e que podem fazer uma solução “certa” ficar errada. Saber o que acontece quando ocorre um overflow/underflow e os limites de cada tipo de dados é bastante valioso durante a codificação de uma solução.
Os números inteiros com sinal são armazenados no computador utilizando a notação binária complemento de 2 mais 1. Nesta notação, o bit mais significativo indica o sinal se o dígito for zero então o número é positivo, caso contrário, o número é negativo. No caso do número negativo, a magnitude, ou seja, o valor absoluto do número é obtido fazendo o complemento do número mais 1.

Tabela dos números representados com 3 bit na notação complemento de 2 mais 1
Binário
Complemento
Complemento +1
Decimal
000


0
001


1
010


2
011


3
100
011
100
-4
101
010
011
-3
110
001
010
-2
111
000
001
-1


Problema 1: Maior Inteiro com sinal positivo
O maior inteiro com sinal pode ser obtido fazendo o bit mais significativo igual a 1 e depois fazendo o complemento.
Problema 2: Menor Inteiro com sinal positivo
O menor inteiro com sinal pode ser obtido fazendo o bit mais significativo igual a 1.

#include <stdio.h>
#include <stdlib.h>
int main(){
  char a,b;
  a = (1<<7);
  b = ~(1<<7);
  printf("CHAR      %2d BIT MIN %20d MAX %d\n",sizeof(a)*8,a,b);
  short c,d;
  c = (1<<15);
  d = ~(1<<15);
  printf("SHORT     %2d BIT MIN %20d MAX %d\n",sizeof(c)*8,c,d);
  int e,f;
  e = (1<<31);
  f = ~(1<<31);
  printf("INT       %2d BIT MIN %20d MAX %d\n",sizeof(e)*8,e,f);
  long long int g,h;
  g = (1LL<<63);
  h = ~(1LL<<63);
  printf("LONG LONG %2d BIT MIN %20lld MAX %lld\n",sizeof(g)*8,g,h);
     
}

Saída
CHAR       8 BIT MIN                 -128 MAX 127
SHORT     16 BIT MIN               -32768 MAX 32767
INT       32 BIT MIN          -2147483648 MAX 2147483647
LONG LONG 64 BIT MIN -9223372036854775808 MAX 9223372036854775807


No caso do long long int, para encontrar o maior e o menor número representado, nós utilizamos a constante 1LL e depois deslocamos para a esquerda 63 bit. Se não for utilizada essa constante, o compilador vai dar o seguinte aviso:
 [Warning] left shift count >= width of type

Problema  4: Maior Inteiro sem sinal
O maior inteiro sem sinal pode ser obtido apenas fazendo o complemento de zero, ou seja, colocando todos os bits setados.

#include <stdio.h>
#include <stdlib.h>
int main(){
  unsigned char a;
  a = ~0;
  printf("CHAR      MAX %u\n",a);
  unsigned short b;
  b = ~0;
  printf("SHORT     MAX %u\n",b);
  unsigned int c;
  c = ~0L;
  printf("INT       MAX %u\n",c);
  unsigned long long int d;
  d = ~0LL;
  printf("LONG LONG MAX %llu\n",d);
     
}

Saída

CHAR      MAX 255
SHORT     MAX 65535
INT       MAX 4294967295
LONG LONG MAX 18446744073709551615

Problema 5: Inicializando um vetor inteiro com memset

int B[100];
memset(B,1,sizeof(B));

O código acima não inicializa o vetor B com 1. A função memset() preenche a memória por chars não por ints.

#include <stdio.h>
#include <stdlib.h>
int main(){
    int INF1 = 0x7FFFFFFF; //constante hexadecimal
    // valor = 2147483647   
    //maior valor inteiro da máquina
   
    int INF2 = ~(1<<31);
    // valor = 2147483647
    //maior valor inteiro da máquina usando operações bit-a-bit
   
    int INF3 = INF2/2;
    // valor = 1073741823
    //maior valor inteiro que pode ser multiplicado por 2 sem dar overflow
    //Por exemplo, no algoritmo do floyd-warshall tem o seguinte condicao
    // if( d[i][j] > d[i][k] + d[k][j]) 
    // este comando pode dar overflow por que d[i][k] e d[k][j] são inicializados com INF
    // ou seja, você está somando dois valores INF.
   
    int INF4 = 0x3FFFFFFF;
    // valor 1073741823
    //maior valor inteiro que pode ser multiplicado por 2 sem dar overflow
   
    int INF5 = 0x3F3F3F3F;
  // valor 1061109567
  //maior valor inteiro que pode ser multiplicado por 2 sem dar overflow
  //que pode ser utilizado para inicializar um vetor com memset
  //memset(m,0x3f,sizeof(m));

}




Nenhum comentário: