Est ce que quelqu'un sait quel est le format de la variable real en Pascal (la signification de chacun de ses 6 octets). Je crois savoir que le prmier octet ou le dernier représente l'exposant, le deuxième ou l'avant dernier le signe.
Est ce que quelqu'un sait quel est le format de la variable real en Pascal (la signification de chacun de ses 6 octets). Je crois savoir que le prmier octet ou le dernier représente l'exposant, le deuxième ou l'avant dernier le signe.
Bonjour !
Un réel est bien stocké sur 6 octets, mais il faut le diviser en 3 séries de bits :
- Le bit 47 représente le signe,
- Les bits 8 à 46 représentent la mantisse,
- Les bits 0 à 7 représentent l'exposant.
(étant entendu que le bit 0 est celui de poids le plus faible)
La valeur du réel est calculée comme suit :
Valeur = +/- Mantisse * 2^exposant
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
Merci beaucoup pour ces précisions.
J'ai ici un petit programme qui permet d'effectuer la conversion d'un real à un double:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 double conversion_real_to_double(BYTE a1,BYTE a2,BYTE a3,BYTE a4,BYTE a5,BYTE a6) { double d = 0.0; // tout dépend de l'exposant pris entre -128 et 127 if (a1 != 0) { char expo = a1 - 129; // le signe int signe = (a2 <= 127) ? 1 : -1; // la mantisse d += a6&127; // donne le premier bit de a6 à 0 et ne change pas les 7 autres d *= 256; d += a5; d *= 256; d += a4; d *= 256; d += a3; d *= 256; d += a2; d /= pow(256,5); d *= 2.0; // donne 0,... d += 1.0; // 1,... d *= pow(2,expo); d *= signe; } return d; }
Ca confirme le fait que l'exposant est sur l'octet de poids faible, mais par contre, on dirait que le signe est sur le second octet. Est ce que c'est faux?
Attention qu'en C, le format interne des données est différent !
Si je ne me trompe pas (mais tu pourrais utilement faire une recherche sur le forum C), le type Double du C est défini comme suit :
- Le bit 64 représente le signe,
- Les bits 53 à 63 représentent l'exposant,
- Les bits 0 à 52 représentent la mantisse.
Si cela est juste, cela éclaire ton petit programme de conversion sous un autre jour ! Donc, prudence.
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
J'ai trouvé une discussion sur le sujet sur le forum C :
http://www.developpez.net/forums/vie...ghlight=double
A bientôt !
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
C'est juste, à un bit près:- Le bit 64 représente le signe,
- Les bits 53 à 63 représentent l'exposant,
- Les bits 0 à 52 représentent la mantisse.
- Le bit 63 représente le signe,
- Les bits 52 à 62 représentent l'exposant,
- Les bits 0 à 51 représentent la mantisse.
Maintenant, il faut que je réussisse à effectuer la conversion, et ça, c'est pas une mince affaire, comme le confirment certains participants de la discussion que t'as trouvé sur le forum C.
A bientôt
Apparemment, il suffit de traduire en Pascal le petit programme C de conversion que tu as présenté ci-dessus !
Pour t'aider :
http://pascal.developpez.com/tutorie...tion_pascal_c/
Bon courage !
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
je me suis mal explique, ce que je veux faire, c'est un programme qui convertit les real en double et vice versa mais en C++. La difficulté est de convertir les double en real, car il y a des cas ou c'est impossible. Mais j'ai trouvé un programme sur internet dont je pourrait fortement m'inspiré, donc je pense que ça ira.
je crois que j'ai oublié quelque chose...
Merci Alcatiz pour ton aide.
Mais il n'y a pas de quoi !
Bon courage pour la suite.
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
Le type Real est un type bâtard, qui change de format en fonction de la version du compilateur.
Pour les types réels standards, en simple, double et quadruple précision, ce doit être le format IEEE qui est suivi.
Mais pour le Real, il faut se méfier. Sous Delphi par exemple, le Real est en fait un Double, bien que le type Real48 existe pour la compatibilité ascendante.
Pour éviter tout ennui, il est préférable de se limiter à des types standards. Je ne suis même pas sûr que les compilateurs Microsoft connaissent ce type là.
A+
Le type real est spécifique à Pascal. Son avantage était qu'il est traité plus rapidement qu'un format simple ou double précision sur une machine sans coprocesseur. Mais n'étant pas un format standard, il est incapable d'être traité par un coprocesseur, en sa présence single et double reprennent l'avantage.Envoyé par Hdd34
Maintenant que tous les CPUs actuels possèdent leur coprocesseur, le type Real est une antiquité à éviter, d'autant plus qu'il est absolument pas portable en dehors de TurboPascal/Delphi. Delphi, depuis la v4, traite les Real comme des Double en effet, pourquoi donc ? Car le type "real" est le mot clé "standard" du pascal réservé aux nombres réels, mais son format exact n'était pas précisé. Un programme qui désire des nombres réels ne cherche pas forcément un format particulier mais juste stocker un réel. Le traitement des double est le plus rapide actuellement donc real a été assigné à double (tout comme l'int en C qui change de taille, d'ailleurs l'integer de pascal aussi). Le type Real48 est réservé aux programmes portés sous Delphi 4+ qui dépendent encore de ce format et uniquement pour ça.
Dans Delphi c'est même pire : Real correspond au format Real48 jusqu'a Delphi 3. Maintenant Real est équivalent à Double depuis Delphi 4, C'est d'ailleurs à ce moment que la définition de Real48 a été créé.
Sous TP, Real est effectivement un type à éviter. Car ce n'est pas un type natif des processeurs Intel. Les calculs Real sont donc interprétés et non gérés par le coprocesseur.
je suis bien d'accord. En fait, mon boulot consiste à faire marcher sous Visual C++ une routine qui a été programmée il y a plus de 10 ans sous TP. Et l'une des plus grosses difficulté de ce boulot, ce fut la conversion de ces real qui font 6 octets alors qu'aucune variable en C/C++ n'a cette taille. Si un autre type avait été utilisé, j'aurai certainement économisé plusieurs journées de boulot. J'imagine que ce doit être un problème classique chez les programmateurs, néanmoins, j'ai été assez surpris du peu d'exemples présents sur le net à ce sujet.Sous TP, Real est effectivement un type à éviter
Tu nous dis que ton programme initial utilise des Real. Je suppose donc que cette routine utilise ces Real dans un code machine, car sinon, je ne vois pas trop où se situe le problème... Il suffit de changer la déclaration.
A+
Le problème, c'est que l'on veut pouvoir réutiliser des fichiers qui ont été écris avec la routine TP, et qui comportent donc des real. La conversion est donc inévitable.
Evidemment, vu sous cet angle là...![]()
En tout cas, une fois que tu auras converti tout ça, évite de reproduire la même erreur. Ca pourrait éviter de futur désagréments.
A+
De plus, les resultats d'operations sur des reels sont toujours aproximatifs.
Vous pourrez par exemple faire 5.356000000000000E+1 - 53 et obtenir 5.600000000000002E-1
Bref, cela peut etre tres desagreable lorsque la variable doit atteindre une valeur precise dans le programme.
Une solution existe-elle? Par exemple ignorer les derniers chiffres de la partie fractionnaire?
Mai,
Non, c'est irréductible dès qu'on travaille avec des réels, augmenter le nombre d'octets pour les représenter ne fait que déplacer légèrement le problème.
Les seuls calculs exacts sont ceux effectués sur des entiers, tant qu'on ne dépasse pas la capacité du type utilisé (en faisant attention aux calculs intermédiaires, qui peuvent dépasser cette limite sans prévenir).
S'il n'y a pas de type entier de base permettant d'atteindre les valeurs visées, il faut utiliser du calcul multi-précision.![]()
Partager