Laboratório 3 - Representação de Informação
Ponto Flutuante no RISC-V (Extensão F)
A arquitetura base RISC-V de 32 bits (RV32I) nativamente contém apenas operações com valores inteiros. Para realizar operações matemáticas com números reais (valores fracionários) diretamente em hardware, o processador precisa implementar a Extensão F (Single-Precision Floating-Point).
A Extensão F adiciona 32 registradores de ponto flutuante (f0 a f31) que adotam o padrão internacional IEEE 754 de Precisão Simples para representar valores fracionários.
Entendendo e Decodificando o Padrão IEEE 754 (32 bits)
O padrão IEEE 754 divide os 32 bits de um número em 3 partes: Sinal, Expoente e Mantissa (ou Fração).
- Bit 31 (1 bit): Sinal (\(S\))
- Bits 30 a 23 (8 bits): Expoente (\(E\))
- Bits 22 a 0 (23 bits): Mantissa (\(M\))
A fórmula matemática que define o valor do número decimal a partir desses bits é:
Decodificação com Truncmento
Para entender na prática, vamos decodificar o binário 11000001011100000000000000000000, extraindo apenas a parte inteira do valor.
1. Sinal (\(S\)): Primeiro bit (bit 31).
- Se for
0, o número é positivo. Se for1, é negativo. - No exemplo:
1(negativo).
2. Expoente (\(E\)): Próximos 8 bits.
- Calculamos o valor decimal desses 8 bits e subtraímos o "viés" (bias) que no caso do IEEE 754 32-bits é sempre \(127\).
- No exemplo:
10000010. Convertendo para decimal: \((128 + 2) - 127 = 130 - 127 = 3\).
3. Mantissa (\(M\)): Últimos 23 bits.
- Se o expoente for um número negativo, significa que a parte inteira é zero.
- Se for positivo, pegamos dos 23 bit finais, adicionamos um
1na frente e aplicamos potências seguindo o valor do expoente. - No exemplo:
1.11100000000000000000000vira1111.00000000000000000000 - $ 2^3 + 2^2 + 2^1 + 2^0 = 15$.
4. Resultado Final: -15
Objetivo
Escreva um programa em C que lê uma string coposta por 0's e 1's da entrada padrão, interprete-a como sendo os bits de um número de ponto flutuante (float) de 32 bits no padrão IEEE 754, e imprima as representações da parte inteira especificadas a continução.
Código Base
#define STDIN_FD 0
#define STDOUT_FD 1
int read(int __fd, const void *__buf, int __n){
int ret_val;
__asm__ __volatile__(
"mv a0, %1 # file descriptor\n"
"mv a1, %2 # buffer \n"
"mv a2, %3 # size \n"
"li a7, 63 # syscall write code (63) \n"
"ecall # invoke syscall \n"
"mv %0, a0 # move return value to ret_val\n"
: "=r"(ret_val) // Output list
: "r"(__fd), "r"(__buf), "r"(__n) // Input list
: "a0", "a1", "a2", "a7"
);
return ret_val;
}
void write(int __fd, const void *__buf, int __n)
{
__asm__ __volatile__(
"mv a0, %0 # file descriptor\n"
"mv a1, %1 # buffer \n"
"mv a2, %2 # size \n"
"li a7, 64 # syscall write (64) \n"
"ecall"
: // Output list
:"r"(__fd), "r"(__buf), "r"(__n) // Input list
: "a0", "a1", "a2", "a7"
);
}
void exit(int code)
{
__asm__ __volatile__(
"mv a0, %0 # return code\n"
"li a7, 93 # syscall exit (64) \n"
"ecall"
: // Output list
:"r"(code) // Input list
: "a0", "a7"
);
}
int main()
{
/* your logic */
/* IEEE 754 -> integer */
/* integer -> decimal */
/* integer -> binary */
/* binary -> hexadecimal */
return 0;
}
void _start()
{
int ret_code = main();
exit(ret_code);
}
Entrada do Programa
Uma string com 32 caracteres (composta apenas por 0's e 1's), seguida por um caractere de nova linha ("\n").
Saída do Programa
Após a leitura, e interpretada a entrada como um valor representado no padrão IEEE 754, o programa deve extrair a parte inteira (truncando a parte fraccionária) e imprimir as seguintes representações:
- a parte inteira do número, representado na base decimal, é precedida pelo sinal se o mesmo for negativo;
- a representação binária (complemento de 2) após a conversão para inteiro, precedida por "0b" em Big-endian;
- a representação binária (complemento de 2) após a conversão para inteiro, precedida por "0b" em Little-endian;
- a representação hexadecimal (complemento de 2) após a conversão para inteiro, precedida por "0x" em Big-endian;
- a representação hexadecimal (complemento de 2) após a conversão para inteiro, precedida por "0x" em Little-endian.
Exemplos
Entrada | 01000100000111001010000000000000
--------|----------------------------------
Saída | 626
| 0b00000000000000000000001001110010
| 0b01110010000000100000000000000000
| 0x00000272
| 0x72020000
Entrada | 11000001011100000000000000000000
--------|----------------------------------
Saída | -15
| 0b11111111111111111111111111110001
| 0b11110001111111111111111111111111
| 0xfffffff1
| 0xf1ffffff
Entrega
Utilize o assistente disponível neste link para avaliar seu código e gerar o relatório de execução.
- Renomeie o arquivo de relatório para
lab3_ra.reportantes de submeter no Classroom
Warning
- Qualquer alteração no arquivo de report será considerado fraude
- O uso de ferramentas de IA deve ser reportado, indicando como foi utilizado e em quais partes do código.
- Está é uma atividade individual, o qual deve ser desenvolvido individualmente, qualquer forma de cópia ou plágio será penalizada. Portanto, atividades que apresentarem semelhanças injustificadas serão atribuídas nota zero para todos os envolvidos