[ZX SPECTRUM] Virgule flottante... je nage! (codes C++)

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)

Message 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.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)

Message 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.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)

Message 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 :

Code : Tout sélectionner

fp[1]&128 ? 1. : -1
. Il fallait inverser les valeurs '1.' et '-1.'.
Xavier_AL

Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)

Message 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!
Répondre