quinta-feira, 21 de maio de 2020

Representação numérica em BASIC (III) - virgula flutuante

Os 5 bytes de representação numérica do stack de virgula flutuante em Spectrum/em BASIC, foram criados na realidade, para representar números em virgula flutuante. A representação numérica inteira que vimos até agora, é apenas uma optimização para acelerar o tratamento de inteiros em BASIC.

A representação será de vírgula flutuante, não sendo o primeiro byte 0, que é o sinal de inteiro.

O formato da representação em vírgula flutuante, é a seguinte:


1º byte expoente + 128

2º, 3º, 4º e 5º byte, mantissa de 32 bits, sendo o bit 7 mais à esquerda o sinal.

Temos portanto, uma precisão de 31 bits na representação numérica de um float (8 bits * 4 bytes, menos o bit do sinal). (2^31 = -2147483648  < x > 2147483648)

O expoente vai desde x^-127 até x^127.

Para melhor entendimento do formato, deixamos também 3 rotinas, 2 alternativas de C, e uma em ZX BASIC, que dado uma string dos 5 bytes da representação numérica, devolvem o número que esta representa.

double zx2d(unsigned char *in) {
int e = in[0];           // expoente
unsigned long m[] = {    // mantissa
in[1], in[2], in[3], in[4]
};
return e ?

(pow(2, e - 160)) * (

   // assemblagem dos 32 bits da mantissa
0x80000000
+ ((m[0] & 0x7f) << 24)
+ (m[1] << 16)
+ (m[2] << 8)
+ m[3]
) * ((in[1] & 0x80) ? -1.0 : 1.0)  // sinal
   : 

(in[1] ? -0x10000 : 0 ) + m[1] + (m[2] << 8);
}

double zx2d(unsigned char *in) {
int e = in[0];              // expoente
long m[] = {                // mantissa
in[1], in[2], in[3], in[4]
};

return e ?

pow(2,e - 128) * ( .5
+ ((m[0]&0x7F) / 256.0 )
+ (m[1] / 65536.0 )
+ (m[2] / 16777216.0 )
+ (m[3] / 4294967296.0 )
) * ((in[1] & 0x80) ? -1.0 : 1.0) // sinal
   :

(in[1] ? -0x10000 : 0 ) + m[1] + (m[2] << 8);
}

7926 IF NOT PEEK (n+1) THEN LET c=PEEK (n+3)+256*PEEK (n+4): RETURN
7927 LET c=2*(.5+(PEEK (n+2) AND 127)/256+PEEK (n+3)/65536+PEEK (n+4)/16777216+PEEK (n+5)/4.2949673e9)*2^(PEEK (n+1)-129): IF PEEK(n+2)>127 THEN c=-c:RETURN

ver:

Binary numbers – floating point conversion

PS. Primeira função de  C e rotina de Basic de Daniel A. Nagy e 2a rotina de C, Slavo Labsky.

Sem comentários:

Publicar um comentário