quarta-feira, 16 de janeiro de 2013

Representação do ponto flutuante em binário



Na representação dos números ponto flutuante em binário, os dígitos binários do lado direito do ponto estão associados as potências negativas de 2.



Vamos representar o seguinte número na representação binária:
$(0.75)_10$ = $\frac{75}{100}$ = $\frac{3}{4}$ = $(0.11)_2$

Observe que os números fracionários escritos com denominador sendo uma potência de 2 podem ser facilmente representados na notação ponto flutuante binária:

$(0.625)_10$ = $\frac{625}{1000}$ = $\frac{5}{8}$ = $(0.101)_2$

Infelizmente, nem todos os números podem ser representados como uma fração com um denominador uma potência de 2. Por exemplo, $\frac{1}{3}$ não pode ser escrita como uma fração com denominador sendo uma potência de 2 mas podemos obter uma aproximação.

$\frac{1}{3}$ = $\frac{x}{2}$ $\rightarrow$ x = $\frac{2}{3}$

Vamos considerar a seguinte aproximação:

denominador 2
$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{2}{3} \rfloor }{2}$ $\approx \frac{0}{2}$
$\frac{1}{3} \approx \frac{0}{2} \approx (0.0)_2$

denominador 4

$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{4}{3} \rfloor }{4}$ $\approx \frac{1}{4}$
$\frac{1}{3} \approx \frac{1}{4} \approx (0.01)_2$


denominador 8

$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{8}{3} \rfloor }{8}$ $\approx \frac{2}{8}$
$\frac{1}{3} \approx \frac{2}{8} \approx (0.010)_2$

denominador 16

$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{16}{3} \rfloor }{16}$ $\approx \frac{5}{16}$
$\frac{1}{3} \approx \frac{5}{16} \approx (0.0101)_2$

denominador 32

$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{32}{3} \rfloor }{32}$ $\approx \frac{10}{32}$
$\frac{1}{3} \approx \frac{10}{32} \approx (0.01010)_2$

denominador 64

$\frac{1}{3} \approx $ $\frac{ \lfloor \frac{64}{3} \rfloor }{64}$ $\approx \frac{21}{64}$
$\frac{1}{3} \approx \frac{21}{64} \approx (0.010101)_2$




1/3 $\approx$ 0.0
1/3 $\approx$ 0.010
1/3 $\approx$ 0.0101
1/3 $\approx$0.01010
1/3 $\approx$ 0.010101
1/3 $\approx$ 0.0101[01]....2



Neste caso, o número $\frac{1}{3}$ precisam de representação de uma quantidade infinita de bits  para serem representados fielmente.

A maior parte das linguagens adota o padrão IEEE 754 criado em 1985 como padrão para a representação e aritmética de ponto flutuante. Resumidamente, o float é representado da seguinte maneira:


O bit mais significativo s representa o sinal, o campo exp codifica o expoente e o campo frac codifica a parte fracionário do número float.
O campo bit utiliza 1 bit, O campo exp utiliza 8 bits e o campo frac utiliza 23 bits.
M = $(-1)^{s}$*( $1.(frac)_2$ )* $2^{e-127}$
Vamos representar o número 0.5 no computador.
0.5 = $\frac{1}{2}$ 
Na representação binária,
(0.5)10 = $(0.1)_2$ = ($(-1)^{0}$ *1.0 x 2-1)2
Na representação ponto flutuante,
s = 1
frac = 0
e-127 = -1 => e = 127-1 = 126

#include <stdio.h>
#include <stdlib.h>
int main(){
 float x;
 scanf("%f",&x);
 int y = *((int *)&x);
 int i;
 int frac; //23 bits
 int expoente; //8bits
 int sinal; //1bit
 for(i=31;i>=0;i--)
  if( ( y & (1<<i) )!=0 ) printf("1");
  else printf("0");
 printf("\n"); 
 frac = y % (1<<23);
 y = y / (1<<23);
 printf("frac %d\n", frac);
 expoente = y % (1<<8);
 y = y / (1<<8);
 printf("expoente %d\n", expoente);
 sinal = y;
 printf("sinal %d\n",sinal); 
 system("PAUSE");
}

Entrada
0.5
Saída
00111111000000000000000000000000
frac 0
expoente 126
sinal 0

Leio o artigo
0,999...OU“COMO COLOCAR UM BLOCOQUADRADO EM BURACO REDONDO"
Revista Eureka 29











Nenhum comentário: