Page 2 sur 3

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

Posté : 16 avr. 2018 09:28
par Xavier_AL
... 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).

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

Posté : 16 avr. 2018 10:09
par Xavier_AL
:oops:
Je confirme:
Capture.JPG
Capture.JPG (63.61 Kio) Vu 402 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

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

Posté : 16 avr. 2018 10:31
par Xavier_AL
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:

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

Posté : 16 avr. 2018 11:23
par hlide
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.

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

Posté : 17 avr. 2018 00:27
par Xavier_AL
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...)

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

Posté : 17 avr. 2018 08:24
par __sam__
au lieu de diviser par 2 à la fin, tu peux faire fp[0]-129 au lieu de 128.

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

Posté : 17 avr. 2018 11:41
par hlide
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);
}

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

Posté : 17 avr. 2018 11:52
par __sam__
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.

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

Posté : 17 avr. 2018 12:54
par hlide
__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]);

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

Posté : 17 avr. 2018 12:59
par hlide
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 ?

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

Posté : 17 avr. 2018 19:02
par Xavier_AL
: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...

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

Posté : 17 avr. 2018 21:08
par __sam__
Je ne pige pas. Le bit 7 de quel octet dans le calcul en cas d'entier ?

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

Posté : 18 avr. 2018 00:29
par hlide
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).

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

Posté : 18 avr. 2018 02:19
par Xavier_AL
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 319 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)

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

Posté : 18 avr. 2018 03:30
par Xavier_AL
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 312 fois
Positifs: (Ok en décodage) 0.01 à 1
Capture.JPG
Capture.JPG (157.03 Kio) Vu 310 fois