QQ'un peut m'expliquer ???

Résolu
Signaler
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
-
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
-
Dans ce code j'ai un probleme que je ne comprends pas. J'ai beau modifier les differents affectations de type le resultat est toujour le meme :

Quand i=0 : dans la partie de code :
else if(dblTempo != 0)
{
TriTime[i] = (int)(dblTempo * intTempo);
}

TriTime[i]=49;

Je suis obligé de faire :
TriTime[i] = (int)(dblTempo * intTempo +0.01);
pour avoir :
TriTime[i]=50;

Quelqu'un peut me donner une explication ????

/***************************************/
/***************************************/
/***************************************/
/***************************************/

int TriTime[6] , intTempo;
double dblTempo,Tempo,ValueTempo;

/* Parametres envoyés */
/* Temps1=1; */
/* nMesure=2050; */
/* BaseTemps2=1; */

ValueTempo = (double)Temps1 * nMesure/nbre;
for(i=(byte)BaseTemps2;i<6;i++)
{
switch(i)
{
case 0: intTempo = 1000; break;
case 1: intTempo = 1000; break;
case 2: intTempo = 60; break;
case 3: intTempo = 60; break;
case 4: intTempo = 24; break;
case 5: intTempo = 24; break;
}

if(i!=5) ValueTempo /= intTempo;
dblTempo = ValueTempo - (int)ValueTempo;

if(i==5)
{
TriTime[i] = (int)ValueTempo;
TriTime[i-1] = (int)(dblTempo * intTempo);
}
else if(dblTempo != 0)
{
TriTime[i] = (int)(dblTempo * intTempo +0.01);
}
}

10 réponses

Messages postés
117
Date d'inscription
samedi 12 janvier 2002
Statut
Membre
Dernière intervention
14 janvier 2003
3
salut,

en fait si tu augmentes la precision de ton printf, tu verras que dblTampon ne vaut pas 50.000 mais 49.999999999999822. (essaye avec printf("%.15f", dblTampon).
Ensuite pourquoi tu as une fois 50.000 et une fois 49, c'est tout simple :
-printf lui arrondi a la precision demande (par defaut 6 chiffre apres la virgule) ce qui te donne 49.999999. Le septieme chiffre etant 9 il rajoute 0.0000001 pour arrondir ce qui te donne 50.000000.
-Lorsque tu ecris TriTime[i] = dblTampon la il n'y a pas d'arrondi, ton programme supprime purement et simplement tout ce qui est apres la virgule, tu obtiens donc TriTime[i] = 49.

voila
Messages postés
12
Date d'inscription
mardi 16 avril 2002
Statut
Membre
Dernière intervention
21 juillet 2006

Salut,
Je comprends rien a ton code mais a mon avis tu te fais des noeuds dans les types de variables, par exemple dans :
ValueTempo = (double)Temps1 * nMesure/nbre;

Si nMesure ou nbre sont de type entier, ta variable ValueTempo sera calcule comme un entier,
il faut que tu fasses :
ValueTempo = double(Temps1 )* double(nMesure/nbre);

Je ne sais pas si j'ai ete tres clair.
Brozman.
Messages postés
455
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
18 décembre 2003

salut,
tu déclares des INT(s) et tu ecris
TriTime[i] = (int)(dblTempo * intTempo +0.01);
le + 0.01 est un float
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
1
Je sais que je suis con mais là c'est Xfile :
Voici un exemple exploitable qui met le pb en évidence :
faites copier/coller , Compilez le en VC++ ou autre en mettant les bonnes biblio... j'y comprend rien. pour moi int(50.0000) ca fait 50 et pas 49 ou alors c'est ce qu'on appelle les maths très modernes. Je dois faire une connerie. J'ai fait en sorte de convertir comme vous me l'avez dit mais ca change apparament rien.

// tempo2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <conio.h>

typedef unsigned char byte;

void Calcul(long Temps1,long nMesure,long BaseTemps2,int nbre)
{
byte TriTime[6]={0,0,0,0,0,0};
int i, intTempo;
double dblTempo,ValueTempo;
double dblTampon;

ValueTempo = double(Temps1) * double(nMesure/nbre);
for(i=(byte)BaseTemps2;i<6;i++)
{
switch(i)
{
case 0: intTempo = 1000; break;
case 1: intTempo = 1000; break;
case 2: intTempo = 60; break;
case 3: intTempo = 60; break;
case 4: intTempo = 24; break;
case 5: intTempo = 24; break;
}

if(i!=5) ValueTempo /= intTempo;
dblTempo = ValueTempo - (int)ValueTempo;

if(i==5)
{
TriTime[i] = (int)ValueTempo;
TriTime[i-1] = (int)(dblTempo * intTempo);
}
else if(dblTempo != 0)
{
dblTampon = (dblTempo * intTempo);
printf("int(%f) -> ",dblTampon); // ici j'ai 50.00000
TriTime[i] = (byte)dblTampon;
printf("%d\n",TriTime[i]); // ici j'ai int(50.00000)=49
getch();
}
}
}

int main(int argc, char* argv[])
{
printf("Ca fonctionne pas :\n\n");
Calcul(1,2050,1,1); // Ca fonctionne pas
printf("\nCa fonctionne :\n\n");
Calcul(1,2060,1,1); // Ca fonctionne ...
printf("\nExplain me please !!!!!");
getch();
return 0;
}
Messages postés
455
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
18 décembre 2003

salut,

Lorsque tu as des arguments de types LONG DOUBLE que tu veux convertir
en INT tu perds de la précision à chaque conversion aussi
il serait préférable d'employer des long double(s) puis convertir à la fin en INT
parce que dans ton exemple tu divises un DOUBLE par un INT (nbre)
ValueTempo = double(Temps1) * double(nMesure/nbre)
bien que tu ai converti en DOUBLE cela pose des problèmes par la suite
puis conversion de DOUBLE en byte
TriTime[i] = (byte)dblTampon;
for(i=(byte)BaseTemps2;i<6;i++)
si on abuse des conversions de type (cast) on s'expose à des chiffres inexacts parfois (faire transiter des valeurs par des variables temporaires peuvent également contribuer aux erreurs)
pourquoi l'un marche et pas l'autre ?
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
1
Bon on vas dire que je suis très très con. J'ai beau tout remanier j'arrive toujour pas a comprendre ni pourquoi ni comment obtenir un résultat correct. Je suppose que vous avez fait des essais avant d'avancer vos commentaires ? Y'aurait-il une âme charitable qui veuille bien me donner une solution qui marche ?????
Merci d'avance. Car là je me suis acheter un gros couteau et je suis au bord du suicide ... j'ai déjà tué le chien du voisin ... et bouffer les canaris du 4eme...
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
1
Bon on vas dire que je suis très très con. J'ai beau tout remanier j'arrive toujour pas a comprendre ni pourquoi ni comment obtenir un résultat correct. Je suppose que vous avez fait des essais avant d'avancer vos commentaires ? Y'aurait-il une âme charitable qui veuille bien me donner une solution qui marche ?????
Merci d'avance. Car là je me suis acheter un gros couteau et je suis au bord du suicide ... j'ai déjà tué le chien du voisin ... et bouffer les canaris du 4eme...

Voici mon nouveau code qui ne marche toujour pas...

// tempo2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <conio.h>

typedef unsigned char byte;
typedef unsigned long ULONG;

void Calcul(long double Temps1,long double nMesure,long double BaseTemps2,int nbre)
{
byte TriTime[6]={0,0,0,0,0,0};

int i, intTempo;
long double dblTempo,ValueTempo;
long double dblTampon;

ValueTempo = Temps1 * nMesure/nbre;
for(i=(int)BaseTemps2;i<6;i++)
{
switch(i)
{
case 0: intTempo = 1000; break;
case 1: intTempo = 1000; break;
case 2: intTempo = 60; break;
case 3: intTempo = 60; break;
case 4: intTempo = 24; break;
case 5: intTempo = 24; break;
}

if(i!=5) ValueTempo /= intTempo;
dblTempo = ValueTempo - (int)ValueTempo;

if(i==5)
{
TriTime[i] = (int)ValueTempo;
TriTime[i-1] = (int)(dblTempo * intTempo);
}
else if(dblTempo != 0)
{
dblTampon = (dblTempo * intTempo);
printf("int(%f) -> ",dblTampon); // ici j'ai 50.00000
TriTime[i] = (byte)dblTampon;
printf("%d\n",TriTime[i]); // ici j'ai int(50.00000)=49
getch();
}
}
}

int main(int argc, char* argv[])
{
printf("Ca fonctionne pas :\n\n");
Calcul(1,2050,1,1); // Ca fonctionne pas
printf("\nCa fonctionne :\n\n");
Calcul(1,2060,1,1); // Ca fonctionne ...
printf("\nExplain me please !!!!!");
getch();
return 0;
}
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
1
Tu veux donc dire que 50 vaut en fait 49.999999 ? et pourquoi dans ces cas là 60 ne vaut pas 59.99999 ?

Tu fait comment dans ces cas là pour faire des calculs précis avec cette imprecision ? (ce n'est pas mon cas mais pour certain ca doit plutot etre non négligeable non .... ?)
Messages postés
117
Date d'inscription
samedi 12 janvier 2002
Statut
Membre
Dernière intervention
14 janvier 2003
3
dans ton cas 60 vaut 60.0000000000057, tu perds de la precision des le premier calcul :
ValueTempo /= intTempo;

Si tu veux faire du calcul precis, va falloir chercher des librairies specialisees (sinon je ne me trompe pas BOOST www.boost.org peux faire ca en C++).
Messages postés
132
Date d'inscription
mercredi 6 mars 2002
Statut
Membre
Dernière intervention
27 novembre 2012
1
OK Merci pour ton explication plus que clair. Je trouve ca completement fou... mais tu dois avoir raison.

Merci pour ton aide @