Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
25 oct. 2007 à 10:36
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 2018
-
27 oct. 2007 à 16:36
salut tout le monde, je viens de rencontrer un probleme assez ... problematique.
j'ai voulu faire le type TRect en utilisant des extended:
type
TExtPt = record
X: Extended;
Y: Extended;
end;
TExtRect = record
case Integer of
0: (Left, Top, Right, Bottom: Extended);
1: (TopLeft, BottomRight: TExtPt);
end;
var
e1, e2: TExtPt;
exts: TExtRect;
begin
e1.X := 1;
e1.y := 2;
e2.X := 3;
e2.Y := 4;
exts.TopLeft := e1;
exts.BottomRight := e2;
//ici, exts.TopLeft = (1,2); TopRight=(3,4); mais Left=1; Top=1e-4932; Right=-3.6e-4925; Bottom=-36.85
end;
j'ai essaye de remplacer les ext par des doubles, ca marche nickel. Le
seul probleme, c'est que ma structure TExtPt est trop presente dans mon
projet pour pouvoir etre changée comme ca simplement.
Quelqu'un aurait il une idee pour me sortir de ce petrin?
Pourquoi utilise-t'on des extended (ou suis-je le seul a le faire)?
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 25 oct. 2007 à 15:19
INTERFACE
Type
TPointF = record
X,Y: single;
end;
pPointF = ^TPointF;
function PointF(const X, Y: Single): TPointF; overload;
function PointF(const Pnt: TPoint): TPointF; overload;
function PointToPointF(const Pnt: TPoint): TPointF;
function PointFToPoint(const PntF: TPointF): TPoint;
type
TRectF = record
case Integer of
0: (Left, Top, Right, Bottom: Single);
1: (TopLeft, BottomRight: TPointF);
end;
pRectF = ^TRectF;
function RectF(const TL, BR: TPointF): TRectF; overload;
function RectF(const TL, BR: TPointF): TRectF; overload;
function RectToRectF(const Rct: TRect): TRectF;
function RectFToRect(const RctF: TRectF): TRect;
IMPLEMENTATION
function PointF(const X, Y: Single): TPointF;
begin
result.X := X;
result.Y := Y;
end;
function PointF(const Pnt: TPoint): TPointF;
begin
result.X := Pnt.X;
result.Y := Pnt.Y;
end;
function PointToPointF(const Pnt: TPoint): TPointF;
begin
result.X := Pnt.X;
result.Y := Pnt.Y;
end;
function PointFToPoint(const PntF: TPointF): TPoint;
begin
result.X := Round(PntF.X);
result.Y := Round(PntF.Y);
end;
function RectF(const L,T,R,B: Single): TRectF;
begin
result.Left := L;
result.Top := T;
result.Right:= R;
result.Bottom:= B;
end;
function RectF(const TL, BR: TPointF): TRectF;
begin
result.TopLeft := TL;
result.BottomRight := BR;
end;
function RectToRectF(const Rct: TRect): TRectF;
begin
result.Left := Rct.Left;
result.Top := Rct.Top;
result.Right := Rct.Right;
result.Bottom:= Rct.Bottom;
end;
function RectFToRect(const RctF: TRectF): TRect;
begin
result.Left := round(RctF.Left);
result.Top := round(RctF.Top);
result.Right := round(RctF.Right);
result.Bottom:= round(RctF.Bottom);
end;
ça sert a rien de faire un TPoint ou TRect avec Extended, en utilisant uniquement Single tu reste avec une trés bonne precision, et de plus ça rend le code compatible avec OpenGL, DirectX et GDI+.
Packed record c'est bien pour les gros record quand la rapiditée n'est pas le soucis majeurs. l'instruction Packed ralentit fortement l'accés a ce genre de données.
de plus, extended n'est pas portable, il n'est pas dans la norme des flottants IEEE FLOAT 32 (single) ou IEEE FLOAT 64 (double)
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 26 oct. 2007 à 10:05
C'est bien un problème d'alignement. Tout est expliqué dans l'aide de Delphi.
L'extended fait 80bits <=> 10 octets.
Genre il met left en +0, top en +10, right en +20, bottom en +30... Comme s'ils étaient packed.
Mais un TExtPt fait 32 octets car il aligne sur des multiples de 8 pour
les extended (Encore une fois, tout est indiqué dans l'aide). Donc X
est en +0 et Y en +16.
Ce qui fait dans TExtRect :
TopLeft.X +0
TopLeft.Y + 16
BottomRight.X + 32
BottomRight.Y + 48
On peut obtenir ce genre de chiffre en faisant des truc du style :
ShowMessage(IntToStr(Integer(@monRectange.BottomRight.X) -
Integer(@monRectangle)));
Faire des packed record corrige le problème.
Mais c'est clair que les Single sont bien mieux en terme de vitesse, et
que l'on doit se reporter sur les Double si on les trouve trops
imprécis.
<hr size="2" width="100%" />3ème année en ecole d'ingé d'info cherche stage de 4 mois à partir du 01/04/08
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 26 oct. 2007 à 11:44
merci pour toutes ces explications claires et tres precises (sauf toi cari, qui ne m'a rien apporté de plus )
Maintenant je comprend beaucoup mieux, et je vais utilise des single je pense.
Pensez vous qu'il soit mieux d'utiliser des doubles pour des calculs geometriques ou le single sera t'il suffisant? (je dois garder une precision suffisante pour qu'apres de multiples calculs intermediaires, le resultat final soit proche de la valeur reelle)
Ca confirme bien ce que je voulais, je vais supprimer la touche "x" de mon clavier comme ca je pourrai plus faire d'extended
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 26 oct. 2007 à 13:01
Salut Guillemouze
Je m'imisse dans ton post car votre échange m'est très instructif. Je travaille également sur du graphique. Moi j'avais simplifié le problème en me disant que c'était un problème de résolution m'évitant ainsi de me prendre la tête.
C'est vrai que l'on met souvent des extended à tord. Les reals ou les doubles sont suffisants dans la pluspart des cas.
Personnellement j'ai pris cette mauvaise habitude lorsque j'avais besoin d'un maximum de précision pour des calculs de positions de planètes en astronomie. Certaines équations ont beaucoup de termes et il faut éliminer les résidus au maximum.
Cari ne t'a peut-être pas apporté de solution à ton problème mais il m'a fait découvrir ces normes IEEE et il peut te vendre du cacao pour pas cher d'après ce que j'ai compris!
Jean_Jean
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 26 oct. 2007 à 13:57
@jean_jean : la norme IEEE a ete enoncée en premier par foxi et non pas par cari ;) mais je disais ca en rigolant, les remarques de cari sont toujours tres interessantes ... sauf dans ce thread
@cari : t'a une adresse ou on peut commander des kinder suicide?
@rt15: bah je sais pas reellement la precision qu'il me faut, j'ai un paquet de calculs basés sur un paquet de calculs basés sur un pa.... et je ne sais pas trop a quel point ca peut engendrer des variations dans les resultats (par exemple un point d'un cercle calculé depuis un centre, un rayon et un angle me sert de base pour d'autre calculs, etc ...)
Mais bon, si c'est comme ca dans les jeux, les imprecisions ne doivent pas etre enormes ...
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 26 oct. 2007 à 15:30
Quand j'avais mis au point mes fonctions de calculs astronomiques, pour savoir jusqu'où Delphi était fidèles aux données des observatoires, j'avais utilisé quelques astuces de programmeur, du temps où j'étais encore Bon:
Je me souviens d'une (peut-être ça te donnera des idées) :
Si tu hésite entre deux types, tu créé artificiellement une petite variation à la limite des types et tu compares les résultats.
Par exemple :
real : 11 chif.signif. : 2,9x10(-39) … 1,7x10(+38) : 6 octects (48 bits) => PI = 3,141 592 653 6
single : 7 chif.signif. : 1,5x10(-45) … 3,4x10(+38) : 4 octets (32 bits) => PI = 3,141 593
double : 15 chif.signif. : 5,0x10(-324) … 1,7x10(+308) : 8 octets (64 bits) => PI = 3,141 592 653 589 79
extended :19 chif.signif. : 3,4x10(-4932) … 1,1x10(+4932) :10 octets(80 bits) =>PI = 3,141 592 653 589 793 238 5
Donc si tu fais des calculs avec des variables de différents type, tu vas voir ou est ta tolérance. Ce qui est à noté, c'est que le type single a moins de chiffres de mantisse que le type real qui a un domaine d'étendu moins grand.
Bien à vous!
Jean_Jean
cs_Jean_Jean
Messages postés615Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 27 oct. 2007 à 16:36
@ Cari,
j'avais repéré ton code que j'avais téléchargé. Je le garde en réserve pour plus tard.
Je n'ai plus en tête la méthode mais je ne pense pas soit adaptée aux calculs de position.
J'utilise deux algorythmes professionels que j'avais bidouillé. J'étais parvenu à une précision de une à 3 secondes d'arc pour la position de la Lune, ce qui est pas mal.
Ton code me sera utile sur un autre type de recherche. Si le Dieu le veux et si les journées s'allongent à 48h.
tu serais pas un peu chercheur dans l'âme Cari pour t'intéresser à ce type de calculs transcndants ne servant à rien???
Jean_Jean