Arrondi

[Résolu]
Signaler
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
-
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
-
good-day everybody

ya quelques temps je m suis amusé (si on peut dire) a refaire la fonction round() de la TI 83 en TIBasic.
Ca marchait super bien, et comme je n'ai rien trouvé de tel en C++ (a part floor, qui fait une troncature, et ceil (je crois)), j'ai voulu implémenter ca.

ca donne:

double round(double nombre,int arrondi){
double puissance=(double)pow(10,arrondi);
return floor(puissance*nombre+0.5)/puissance;
}
int main()
{
double nbre=1.123456546;

cout << "valeur arrondie de " << nbre << " a 4 chiffres apres la virgule: " << round(nbre,4) << "\n\n";
system("PAUSE");
return 0;
}

Comme vous le voyez, cette fonction fait un arrondi (pas une troncature! un vrai arrondi a n chiffres apres la virgules), et en TIBasic ca donnait axactement la meme chose que la fonction rand().

Celle ci aussi parche bien, mais commence a planter a partir de 1000, là il aime pas du tout et retourne une valeur arrondie différemment.

Voili voilou, si vous savez pourquoi vous etes le bienvenu :)

Merci

PS: double, long ou float, ca ne change rien du tt :(

10 réponses

Messages postés
95
Date d'inscription
samedi 19 juin 2004
Statut
Membre
Dernière intervention
20 avril 2010

Cela vient de la précision d'affichage dont parlait Genda67, pour le contourner, fait un
cout.precision(10);

avant le cout<<

A+,
JP.
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

Euh, tu veux une fonction qui ecrit un nombre selon une précision ? genre le nombre "pi" : 3.1416 ou pi = 3.141, etc ?
Ben si tu veux qqch qui gère la présicion, tu as un manipulateur en C++ qui le fait :

cout << setprecision(4) << pi << "\t" << setprecision(3) << pi;

ou en C:

float pi = 3.1416

printf("pi avec 2 chiffres significatifs s'écrit : %.3", pi); // affichage à 0.001 près :)

Genda67, à votre service !
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
nan c'est pas ca.
ces 2 fonctions je les connais, elles ne font que modifier la précision d'AFFICHAGE.
Ma fonction fait un vrai arrondi, comme en maths ou en physique.
Ne me demande pas a quoi ca sert, c'est juste pour le fun :)
Messages postés
95
Date d'inscription
samedi 19 juin 2004
Statut
Membre
Dernière intervention
20 avril 2010

Une petite remarque sur la précision des types : le type double ne gere pas un nombre infini de nombre après la virgule (de mémoire la précision est de 15 digit mais je suis pas sur), ce qui parfois amener de curieux résultats.

Je penche perso pour la solution de Genda67, en c++ du moins : en effet ios_base::precision permet de gerer des arrondis mathématique et ne tronque donc pas le nombre (je n'en suis pas sur pour le printf par contre). Pour info Genda, l'arrondi de 3.1416 à 3 chiffres apres la virgule est 3.142 et pas 3.141.

Par contre si tu as besoin d'une grande précision dans les calculs, alors il faut te pencher sur des librairies spécialisés qui permettent de gerer des nombre plus précisement que les types prédefinis. Par exemple GNU MP

A+,
JP.

PS: ta fonction ne marche pas avec les nombre négatifs, il faut retrancher 0.5 dans ce cas !
Messages postés
509
Date d'inscription
samedi 28 juin 2003
Statut
Membre
Dernière intervention
3 août 2010

Avec ceci ça devrait marcher:
double Round(double valeur, int arrondi)
{
double a, b, c;

a = pow(10.0, (double)arrondi);
b = (double)(int)(valeur*a);

c = fabs(valeur*a - b);
if((c>0.5)&&(valeur>0))
return (b+1.0)/a;
else if((c>0.5)&&(valeur<0))
return (b-1.0)/a;

return b/a;
}
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
(double)(int)?
je vois bien comment ton code marche mais ca je comprend pas.

Sinon effectivement ca devrait marcher, masi moi j'aimerai savoir pourquoi mon prog a moi ne marche pas (c'est qd meme plus simple, il n'y a qu'une ligne!)
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
(int) pour garder que la partie entiere
Messages postés
95
Date d'inscription
samedi 19 juin 2004
Statut
Membre
Dernière intervention
20 avril 2010

Le code de gagah fait la meme chose que le tien, à part pour les nombre négatifs. Par contre si ton problème est un problème de précision, alors cela ne va pas regler ton problème.
Encore une fois, le double n'est pas d'une précision infinie.

Pour info son code peux aussi se résumer en une ligne :

double round(double nombre,int arrondi){
double puissance=(double)pow(10,arrondi);

return (nombre>0)?((int)(puissance*nombre+0.5))/puissance:((int)(puissance*nombre-0.5))/puissance;

}


et plus clairement :
double round(double nombre,int arrondi){
double puissance=(double)pow(10,arrondi);

if (nombre>0) {
return floor(puissance*nombre+0.5)/puissance;
}else {
return floor(puissance*nombre-0.5)/puissance;

}


ce qui revient au code de gagah !

A+,
JP.
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
oui je sais, ya 12 ou 15 chiffres dans un double (je sé plus).
mais a partir de 1000, mon prog, qui marche jusque la, ne met plus que 2 chiffres apres la virgule, ce qui fait 4+3=7chiffres, et pas 12!

A priori, meme un float devrait pouvoir le faire.
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
exact.
la ça marche dans tous les cas.
Merci.
:D