Ordre de sommation des flottants (exemple par simulation)

Soyez le premier à donner votre avis sur cette source.

Vue 3 803 fois - Téléchargée 306 fois

Description

Qui a dit que l'ordre de sommation est flottant n'importait pas ??
Voici un petit simulation vous devrait vous convaincre du contraire !

La simulation est la suivante : il y a des masses dans une "arene",
delimitee par un petit cercle, la dedans les masses ne subissent
aucune force exterieures, mais interagissent entre elles suivant
des forces repulsives en 1/r^2 (types gravitationnelles) et des forces
attractives en r^1 (types elastiques), et en dehors de ce cercle
interieur, une force qui derive d'un potentiel et qui a tendance
a ramener toute particule qui sort du cercle dans celui-ci
c'est en gros un "mur" circulaire, pour plus d'information voir
ma source precedente (simulation d'un rebond sur un mur)

Bref tout ceci pour simuler une "bouillie" de forces...

La subtilite de cette source est que je presente deux simulations :
il y a plein de forces, et je dois calculer leur somme
(puisque le principe fondamental de la dynamique stipule de masse fois
acceleration egale somme des forces)
Mais la sommation ne se fait pas de la meme maniere dans les deux
simulations... certains diront que ca n'a pas d'importance... que nenni !
il y a une bonne et une mauvaise maniere de sommer des flottants, la preuve :
les deux situations pourtant initialement identiques dans leur description
divergent au bout de quelques secondes (cf capture d'ecran, les boules rouges
sont censees toujours etre exactement sous les vertes)

La bonne methode pour sommer est de toujours sommer les deux quantitees
qui ont la plus petite valeur absolue...

Ne chipotez pas !! un jour si vous voulez faire une simulation d'une galaxie,
alors vous aurez besoin de sommer des forces et vous aurez ce probleme de
stabilite numerique...

De plus la simulation en soi est tres amusante non ? elle correspond a rien du tout
mais ca fait jolie a voir evoluer...

Convaincu(e) ?

Source / Exemple :


//-------------------------------------------------
double funcSumStupid(double *p,int n)
{
double  sum;
int     k;

sum = 0.;
// algorithme stupide, on somme dans l'ordre que l'on nous a donne les valeurs
for(k=0;k<n;k++)
  {
  sum += p[k];
  }

return sum;
}

//----------------------------------------------------------
int cmpDouble(void *key1,void *key2,void *param)
{
double a,b;

UNUSED_PARAMETER(param);

a = fabs(*(double*)key1);
b = fabs(*(double*)key2);

if(a > b)       return CMP_MORE;
else if(a < b)  return CMP_LESS;
else            return CMP_EQUAL;
} // cmpDouble()

//-------------------------------------------------
double funcSumNotStupid(double *p,int n)
{
int     k;

// on trie les nombres par ordre croissant de leur valeur absolue
QuickSortArray(double,p,n,cmpDouble,NULL);

for(k=0;k<n-1;k++)
  {
  int i;
  p[k+1] += p[k]; // on somme les deux plus petits ...
  i = k+1;
  // ... puis on fait remonter cette somme a sa bonne place
  // pour que les valeurs soient toujours triees selon
  // leur valeur absolue
  while(i < n-1 && fabs(p[i]) > fabs(p[i+1]))
    {
    SwapDouble(p+i,p+i+1);
    i ++;
    }
  }
// la somme calculee telle que l'on a minimise les erreurs d'arrondis
return p[n-1];
}

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

metanil
Messages postés
51
Date d'inscription
mercredi 27 avril 2005
Statut
Membre
Dernière intervention
13 novembre 2007

ahahahahah !

Mon discours n'attaquait nullement les "fous" du clavier....

(j'ai preque terminé mon TPaintBox 3D !)
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
18
"quantième de seconde que permet d'économiser tel ou tel code"
il convient d'en parler, au contraire.
Il y a donc du monde pour croire que code optimisé ne sert à rien, qu'aucune boite n'investit plus dedans et qu'il n'y a plus d'application à ce genre de code ?
Je connais pourtant du monde qui en vit (devinez qui) et qui n'a pas l'impression que son carnet de commandes est rempli par des entrepreneurs délirants.
metanil
Messages postés
51
Date d'inscription
mercredi 27 avril 2005
Statut
Membre
Dernière intervention
13 novembre 2007

Disons que le terme même de "précision" signifie bien ce qu'il veut dire !

C'est dans "sans précision" que l'intéret de l'objet réside, sinon, tu es forcément tributaire de sa signification...
cs_JCDjcd
Messages postés
1138
Date d'inscription
mardi 10 juin 2003
Statut
Membre
Dernière intervention
25 janvier 2009
2
oui mais tu ne resouds pas le probleme de (pi+e)+phi different de pi+(e+phi) quelque soit la precision voulue
(phi=nombre d'or,e=nombre d'euler,pi=pi)

ALGORITHME avec un I
metanil
Messages postés
51
Date d'inscription
mercredi 27 avril 2005
Statut
Membre
Dernière intervention
13 novembre 2007

En fait, ce TSolverObjet travaille par réduction d'expression...
Il est écrit en Delphi, ce qui ne nous avance guère pour la surcharge, et nous rabaisse donc au niveau du C, mais son plus réside dans l'interprétation des variables... Elles sont codées sous forme de AnsiString (par définition : type ouvert) et non sous forme de float, integer ou autres extended (types fermés)...

Pour vous embrouiller un peu plus, 1/3 et PI doivent-ils être exclus de tout algorythme de somme ?

Ainsi A "devient "1/3', alors que 1/3 "devient" 0,33333[3]... (avec la précision voulue, et non celle imposée pour le codage des floats...); cette précision, elle n'est indiquée que lors de la "sortie", par l'opérande qui reçoit le résultat... Durant tout le transport de l'information A, A reste 1/3, et conserve ainsi son intégrité textuelle, permettant la réduction ou non des fractions...

En C++, A + B, c'est +(A,B), mais c'est surtout dépendant du type du résultat ! si tu veux un float en sortie, tu auras la précision annoncée d'un float en sortie... Si tu veux un BigFloat, et bien, c'est cette précision que tu auras...

Il nous faut, dans le corps du template operator+(A,B), définir, pour la précision voulue, la bonne de sommation de deux objets.

Dans le cadre de math++, c'est bien la sommation de deux objets "Grands Nombres" qui serait invoquée... Ainsi tout dépendra de son implémentation... En C, je ne vous garantis pas la possibilité de surcharger pour obtenir la sommation de deux AnsiString... Quand à revoir tout un programme après le changement de tous "float" par "bigfloat"...et le linkage de la nouvelle librarie...Heureusement que MSC 2.0 n'est plus en lice...

En fait, en C++, ce qui importe ce sont les objets vivants après le C (utile dans l'implémentation des fonctions)...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.