INF1018 - Software Básico

Representação de Números com Ponto Flutuante

O objetivo deste laboratório é implementar operações sobre números de ponto flutuante sem usar operações de ponto flutuante, isto é, operando diretamente sobre a representação binária desses números.

Como, em C, operações de manipulação de bits só são permitidas para valores do tipo inteiro, você pode utilizar uma union como a definida abaixo para obter a representação de bits de um float como um unsigned int e vice-versa (isto é, obter um valor float a partir de sua representação binária).

typedef union { 
  float f;
  unsigned int i;
 } U;
...
U u;
float f1 = ...;
unsigned int u1;

u.f = f1;  /* armazena o float na union */
u1 = u.i;  /* obtem a representação "manipulavel" do float */

...
u.i = u1;  /* armazena a representação binária na union */
f1 = u.f;  /* obtem o float correspondente a essa representação */

Algumas macros úteis:

Exercícios:

  1. Escreva uma função C float2 que, sem usar operações de ponto flutuante, multiplique o valor de seu parâmetro por 2:
    float float2(float f);
    

    DICA: se você tem a representação de um valor na forma x * 2y, qual é o novo valor de y se você multiplicar esse valor por 2?

  2. Escreva uma função C int2float que converta um número no formato int para o formato float.

    ATENÇÃO: Uma conversão direta, como f = (float)i, não vale, pois o C irá converter o formato, e a proposta do laboratório é você fazer a conversão...

    O protótipo da sua função é

    float int2float(int i);
    

    DICAS:

    • Para converter o inteiro para o formato float, precisamos encontrar os valores de s, M e E que correspondem à representação do valor do inteiro no formato float, isto é, na forma (-1)s M 2E. A partir dos valores de M e E você pode determinar os valores das "partes" frac e exp.
    • Trate o 0 como um caso especial (sua conversão é imediata).
    • Verifique se o valor inteiro é positivo ou negativo, e guarde essa informação para preencher o bit de sinal da representação IEEE. Trabalhe então com o valor absoluto do inteiro a ser convertido para encontrar os valores do expoente e mantissa.
    • Considere a representação do valor absoluto do inteiro em binário (representação sem sinal). Esse valor é uma soma 2i + 2j + 2k + ..., onde i é a posição do bit "1" mais significativo dessa representação (isto é, o bit "1" com a "maior" posição). Você vê alguma relação entre i e E?
    • Lembre-se que M é um valor na forma 1.frac. A sequência de bits de frac deve iniciar na posição 22 da representação IEEE do valor float.

    Uma sugestão de main para testar suas funções de conversão está aqui (essa main contém testes também para o próximo exercício).

  3. Escreva uma função float2int para converter um número no formato float para o formato int. Novamente, a função deve fazer a conversão sem usar operações de ponto flutuante.

    O protótipo da função é:

    int float2int(float f);