Page 3 sur 3
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Publié : 18 avr. 2018 08:13
par __sam__
Xavier_AL a écrit : ↑18 avr. 2018 02:19
0x00, 0x00, 0xFF, 0xFF, 0x00, >>> pour 65535
0x00, 0xFF, 0xFF, 0xFF, 0x00, >>> pour -1
0x00, 0xFF, 0xFE, 0xFF, 0x00,>>> pour -2
0x00, 0xFF, 0x00, 0xFF, 0x00, >>> pour -256
L'impression que j'ai c'est que les entiers sont sur 24 bits:
Code : Tout sélectionner
if(fp[0]==0) {
double t = fp[1]*65536 + fp[3]*256 + fp[2];
if(fp[1]&128) t -= 256*65536;
return t;
}
Du coup 65536 vaut 0x00 0x01 0x00 0x00 je pense.
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Publié : 18 avr. 2018 10:15
par hlide
Ajoute 16777216, 65536, -65536, -65535 et -1024, parce que que -256 c'est encore trop petit. 0xFF n'est pas déconnant parce qu'en octet c'est bien -1. D'un manière générale tous les bits du poids fort d'un nombre signé doit être à 1 donc avec un -1, un -2 et un -256, c'est normal.
Par contre l'ordre me parraît très tordu : fp[2] contient l'octet ayant le poids le plus faible, suivi de fp[3], suivi probablement de fp[1], donc quelque chose comme :
Code : Tout sélectionner
return 1. * ( int( fp[1] * 256u*256u*256u + fp[3] *256u*256u + fp[2] * 256u ) >> 8 );
Ce que fait le code, c'est de créer le 24-bit à l'intérieur d'un entier 32-bit non-signé en plaçant les trois octets dans les trois poids forts de l'entier, de passer l'entier en 32-bit signé (passage en 'int') pour que le bit 7 de fp[1] devienne le signe de l'entier, de le décaler de 8 bits pour étendre le signe sur le poid le plus fort de l'entier et enfin de convertir ce dernier en double.
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Publié : 18 avr. 2018 10:20
par hlide
Et je viens de m'appercevoir de l'erreur dans ce code :
Code : Tout sélectionner
//*******************************************************************
// Spectrum/ZX81 Floating point decoder From _SAM_
//*******************************************************************
//IN: 5 Bytes : 1 EXP + 4 Mantissa (sign on the secound byte)
//OUT: DOUBLE
double decode(unsigned char fp[5]) {
double mantisse;
if(fp[0]==0) return (fp[1]&128 ? 1. : -1.)*(fp[2]+fp[3]*256+fp[4]*65536);
mantisse = (((fp[4]/256.0 + fp[3])/256.0 + fp[2])/256.0 + fp[1]))/128.0;
if(mantisse < 1) mantisse += 1; // nombre positif
else mantisse = -mantisse; // nombre negatif
return mantisse*pow(2, fp[0]-129);
}
Ca me chiffonnait qu'au final le bit 7 portait bien le signe au vu des nouveaux résultats alors que celles données avec cette fonction "prouvaient" que ce n'était pas possible. C'était sans compter l'inversion :
. Il fallait inverser les valeurs '1.' et '-1.'.
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Publié : 18 avr. 2018 18:30
par Xavier_AL
Encore Voilà !
Tout fonctionne pour les entiers négatif.
Block 1:
Start line: 32768.
10 DIM a(10)
20 LET a(1)=65535
30 LET a(2)=-1
40 LET a(3)=-2
50 LET a(4)=-256
60 SAVE "datas" DATA a()
Header bloc program [Num. ARRAY]
Name...:'datas '
Block 2:
Array(10) :
65535.000000
-1.000000
-2.000000
-256.000000
Le code C++, final:
Code : Tout sélectionner
//*******************************************************************
// Spectrum/ZX81 Floating point decoder From _SAM_ et hlide
//*******************************************************************
//IN: 5 Bytes : 1 EXP + 4 Mantissa (sign on the secound byte)
//OUT: DOUBLE
double decode(unsigned char fp[5]) {
double mantisse;
if(fp[0]==0) {
double t = fp[1]*65536 + fp[3]*256 + fp[2];
if(fp[1]&128) t -= 256*65536;
return t;
}
mantisse = (((fp[4]/256.0 + fp[3])/256.0 + fp[2])/256.0 + fp[1])/128.0;
if(mantisse < 1) mantisse += 1; // nombre positif
else mantisse = -mantisse; // nombre negatif
return mantisse*pow(2, fp[0]-129);
}
Encore Merci pour votre aide.
L'exercice n'était pas simple, et vous avez réussi!
Bravo!