[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 : Carl, Papy.G, fneck

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

Re: [ZX SPECTRUM] Virgule flottante... je nage!

Message par Xavier_AL » 16 avr. 2018 09:28

... Archimède ?
Oui, j'ai l'impression... car les variables Basic en entier, sont "pures" et les variables résultantes de calculs sont encodées en exponentielles!
Donc, il y a un décodage en fonction du bit fort sur le 1er octet.
Il faut que je te sorte des valeurs variables autres qu'entières (GOTO xxx).

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

Re: [ZX SPECTRUM] Virgule flottante... je nage!

Message par Xavier_AL » 16 avr. 2018 10:09

:oops:
Je confirme:
Capture.JPG
Capture.JPG (63.61 Kio) Vu 407 fois

Les tableaux DIM x(), ne sont pas traduits en entiers, mais en virgules flottantes.
Et c'est bien cette valeur qui me pose problème.

Ici, deux fichiers... (capture écran)
1 basic
10 DIM a(1)
20 LET a=1/1
30 SAVE"datas"DATA a()

où 1=00;00;01;00;00

1 Fichier data:
a(1)=1
81;00;00;00;00

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

Re: [ZX SPECTRUM] Virgule flottante... je nage!

Message par Xavier_AL » 16 avr. 2018 10:31

Donc, j'ai tout bien vérifié...

Mais, petite question subsidiaire...
j'affiche le résultat avec :
printf("%d :\r\n",DecNumber);
:?:
ça m'affiche les DOUBLE ou les INTEGER en C++ ?
Sinon, ça peut venir de là!
:mrgreen:

hlide
Messages : 388
Enregistré le : 29 nov. 2017 10:23

Re: [ZX SPECTRUM] Virgule flottante... je nage!

Message par hlide » 16 avr. 2018 11:23

Ca dépend comment est déclaré la variable DecNumber. En l'occurence, elle est déclarée ici comme double. Je suppose que tu n'utilises pas gcc ? parce qu'il aurait dû te sortir un warning si tu n'utilises pas le bon code de format : %f et non %d. Là, il te sortira en base décimal la représentation interne binaire du nombre et probablement tronquée à 32-bit.

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

Re: [ZX SPECTRUM] Virgule flottante... je nage!

Message par Xavier_AL » 17 avr. 2018 00:27

Salut à tous,

Voilà, ça fonctionne.
J'ai pris le code de Samuel (mais en le divisant par 2):

Code : Tout sélectionner


//*******************************************************************
// Spectrum/ZX810 Floating point decoder From _SAM_
//*******************************************************************

double resultat = decode(LineData);	
		   fprintf(out,"%f\r\n",resultat);
		   
double decode(unsigned char fp[5]) { 
	double mantisse;
		
	if(fp[0]==0) return 0;	
	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]-128)/2;
}

Le problème venait bien du %d à l'affichage, au lieu du %f. (affichage de la valeur tronquée)
Je suis sur le "TDM-GCC 4.9.2" sous Dev-C++ , et aucun message lors de la compilation.

Donc, Merci à tous pour votre aide, vos conseils et votre expertise!
hlide pour tes conseils (et ton code), Sam pour tes connaissance en routines de décodage...
Et tous les curieux qui ont suivi ce fil.

J'upload le binaire w32/64 sur ce fil, des que le programme sera cohérent.

(Merci Fabien pour le déplacement du message! toujours discret, et toujours efficace...)

__sam__
Messages : 4026
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

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

Message par __sam__ » 17 avr. 2018 08:24

au lieu de diviser par 2 à la fin, tu peux faire fp[0]-129 au lieu de 128.
Samuel.
A500 Vampire V2+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

hlide
Messages : 388
Enregistré le : 29 nov. 2017 10:23

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

Message par hlide » 17 avr. 2018 11:41

Eventuellement, tu peux modifier la routine pour extraire l'entier codé dans le cas où fp[0] == 0 :

Code : Tout sélectionner


//*******************************************************************
// Spectrum/ZX810 Floating point decoder From _SAM_
//*******************************************************************

double resultat = decode(LineData);	
		   fprintf(out,"%f\r\n",resultat);
		   
double decode(unsigned char fp[5]) { 
	double mantisse;
		
	if(fp[0]==0) return 1.*(fp[2]+fp[3]*256+fp[4]*65536);	
	mantisse = (((fp[4]/256. + fp[3])/256. + fp[2])/256. + fp[1])/128.;	
	if(mantisse < 1.) mantisse += 1.;  // nombre positif
	else mantisse = -mantisse; // nombre negatif
	
	return mantisse*pow(2, fp[0]-129);
}

__sam__
Messages : 4026
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

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

Message par __sam__ » 17 avr. 2018 11:52

dans le cas des entiers, comment est-ce que le signe est géré ? Est-ce le bit 7 de fp[1] qui compte comme pour les flottants? Si c'est le cas il faudrait avoir:

Code : Tout sélectionner

if(fp[0]==0) return (fp[1]&128 ? 1. : -1.)*(fp[2]+fp[3]*256+fp[4]*65536);
Xavier: tu as quoi comme valeurs fp[] pour les entiers 65535, -1, -2, et -256 par exemple.
Samuel.
A500 Vampire V2+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

hlide
Messages : 388
Enregistré le : 29 nov. 2017 10:23

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

Message par hlide » 17 avr. 2018 12:54

__sam__ a écrit :
17 avr. 2018 11:52
dans le cas des entiers, comment est-ce que le signe est géré ?
Exact. Soit c'est le bit 7 de fp[4] comme pour une valeur entière habituelle, soit on peut imaginer que c'est le fp[1]. D'ailleurs, est-ce qu'ils auraient pas fait un truc assez tordu pour que ce soit quelque chose de ce genre :

Code : Tout sélectionner

return 1. * int(fp[1] * 16777216 + fp[4] * 65536 + fp[3] * 256 + fp[2]);

hlide
Messages : 388
Enregistré le : 29 nov. 2017 10:23

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

Message par hlide » 17 avr. 2018 12:59

Et en big-endian, ça nous donnerait :

Code : Tout sélectionner

return 1. * int(fp[1] * 16777216 + fp[2] * 65536 + fp[3] * 256 + fp[4]);
j'ai cru lire ici qu'il y aurait une différence de little/big-endian dans la représentation entre Spectrum et Amstrad ?

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

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

Message par Xavier_AL » 17 avr. 2018 19:02

:oops:
Oui Samuel, comme tu le présageais, nous avons un problème de signe/bit7 sur f[1]

Code : Tout sélectionner

Comment : Created with EightyOneTZX

Header bloc program [BASIC]
Name...:'basic     '

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
65535.000000
65534.000000
65280.000000
-0.000000
-0.000000
-0.000000
-0.000000
-0.000000
-0.000000
Sur 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);
}
Il faut retirer le bit 7 avant le calcul...

__sam__
Messages : 4026
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

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

Message par __sam__ » 17 avr. 2018 21:08

Je ne pige pas. Le bit 7 de quel octet dans le calcul en cas d'entier ?
Samuel.
A500 Vampire V2+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

hlide
Messages : 388
Enregistré le : 29 nov. 2017 10:23

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

Message par hlide » 18 avr. 2018 00:29

Donne plutôt le résultat en représentation interne en hexa comme tu avais fait auparavant. Ca n'a aucun intérêt de le faire faire sur la fonction que t'a donné __sam__ (ou la mienne) car on cherche justement à voir cette représentation pour en déduire la bonne formule.

Ces résultats :
65535 -> -65535.000000
-1 -> 65535.000000
-2 -> 65534.000000
-4 -> 65280.000000

montrent juste que la formule proposée n'est pas bonne.

Cela montre que le bit 7 de fp[1] ne porte pas le signe à cause de 65535, sinon aurait pas -65535.0.
Les autres montrent que le bit de signe existe mais qu'il est ailleurs.

Voyons :
-1 -> 65535 == 00h 0???????b FFh FFh 00h
-2 -> 65534 == 00h 0???????b FEh FFh 00h
-4 -> 65280 == 00h 0???????b 00h FFh 00h

Le -4 donne un résultat encore plus bizarre. On en saura davantage avec les représentations internes (image des codes hexadécimaux).

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

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

Message par Xavier_AL » 18 avr. 2018 02:19

Oui, pardon...
Donc les valeurs en Basic, premier fichier, sont toujours en positif.
La parie à la fin, c'est l'enregistrement du tableau a(10), avec les 10 valeurs.
Capture.JPG
Capture.JPG (95.24 Kio) Vu 324 fois
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

0x00, 0x00, 0x00,0x00,0x00,>>> pour 0
0x00, 0x00, 0x00, 0x00,0x00,>>> pour 0
0x00, 0x00, 0x00, 0x00,0x00,>>> pour 0
....
Et c'est plus clair comme ça!
Enfin, non... il y a une part d'incohérence sur le f[1] du signe(bit poids fort).. à 0x0FF et non à 0x080
Il nous fait un saque en 0x7FFFFF (XOR FF) sur la valeur négative? (sauf les 0)

Avatar du membre
Xavier_AL
Messages : 261
Enregistré le : 06 déc. 2017 20:30

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

Message par Xavier_AL » 18 avr. 2018 03:30

10 DIM a(100)
20 For i=1 TO 100
40 LET a(i)=-i/100
50 NEXT a
60 SAVE "datas" DATA a()

(commence en offset 70, dernier octet est à exclure '53')
Négatifs: (Ok en décodage) -0.01 à -1
Capture.JPG
Capture.JPG (166.58 Kio) Vu 317 fois
Positifs: (Ok en décodage) 0.01 à 1
Capture.JPG
Capture.JPG (157.03 Kio) Vu 315 fois

Répondre