Arrondi

Résolu
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 - 27 oct. 2004 à 21:24
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 - 28 oct. 2004 à 17:11
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

jpthomasset Messages postés 95 Date d'inscription samedi 19 juin 2004 Statut Membre Dernière intervention 20 avril 2010
28 oct. 2004 à 12:00
Cela vient de la précision d'affichage dont parlait Genda67, pour le contourner, fait un
cout.precision(10);

avant le cout<<

A+,
JP.
3
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
27 oct. 2004 à 21:50
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 !
0
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
27 oct. 2004 à 22:16
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 :)
0
jpthomasset Messages postés 95 Date d'inscription samedi 19 juin 2004 Statut Membre Dernière intervention 20 avril 2010
27 oct. 2004 à 22:42
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 !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
gagah1 Messages postés 509 Date d'inscription samedi 28 juin 2003 Statut Membre Dernière intervention 3 août 2010
27 oct. 2004 à 23:10
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;
}
0
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
27 oct. 2004 à 23:22
(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!)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
27 oct. 2004 à 23:32
(int) pour garder que la partie entiere
0
jpthomasset Messages postés 95 Date d'inscription samedi 19 juin 2004 Statut Membre Dernière intervention 20 avril 2010
28 oct. 2004 à 00:02
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.
0
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
28 oct. 2004 à 11:11
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.
0
Arnaud16022 Messages postés 1329 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 16 juin 2010 2
28 oct. 2004 à 17:11
exact.
la ça marche dans tous les cas.
Merci.
:D
0
Rejoignez-nous