[ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Modérateurs : Papy.G, fneck, Carl
Re: [ZX SPECTRUM] Virgule flottante... je nage!
... 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).
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!
Je confirme:
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!
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à!
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à!
Re: [ZX SPECTRUM] Virgule flottante... je nage!
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!
Salut à tous,
Voilà, ça fonctionne.
J'ai pris le code de Samuel (mais en le divisant par 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...)
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...)
-
- Messages : 7970
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
au lieu de diviser par 2 à la fin, tu peux faire fp[0]-129 au lieu de 128.
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
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
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);
}
-
- Messages : 7970
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
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:
Xavier: tu as quoi comme valeurs fp[] pour les entiers 65535, -1, -2, et -256 par exemple.
Code : Tout sélectionner
if(fp[0]==0) return (fp[1]&128 ? 1. : -1.)*(fp[2]+fp[3]*256+fp[4]*65536);
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
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
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++)
Et en big-endian, ça nous donnerait :
j'ai cru lire ici qu'il y aurait une différence de little/big-endian dans la représentation entre Spectrum et Amstrad ?
Code : Tout sélectionner
return 1. * int(fp[1] * 16777216 + fp[2] * 65536 + fp[3] * 256 + fp[4]);
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
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
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);
}
-
- Messages : 7970
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
Je ne pige pas. Le bit 7 de quel octet dans le calcul en cas d'entier ?
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
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: [ZX SPECTRUM] Virgule flottante... je nage! (codes C++)
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).
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++)
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.
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)
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.
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++)
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 Positifs: (Ok en décodage) 0.01 à 1
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 Positifs: (Ok en décodage) 0.01 à 1