Probleme avec mon modulo

Fermé
Demonaz84 Messages postés 12 Date d'inscription samedi 10 septembre 2016 Statut Membre Dernière intervention 5 décembre 2016 - 22 sept. 2016 à 04:25
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 - 22 sept. 2016 à 23:13
Bonjour à tous,

une partie de mon programme de caisse enregistreuse doit arrondir le montant final à payer afin d'éliminer les sous qui n'existent plus. donc si le total est 10.72 ca doit afficher 10.70.

j'ai essayer une formule de modulo mais ca fonctionne pas tout le temps, par exemple si c'est 10.47 ça va arrondir à 10.45 mais, si c'est 10.43 ça écrit 10.41, et je comprend pas pourquoi.

bien sûr mes talents de codeur sont très faible étant un débutant total, et les commandes que j'ai le droit d'utiliser sont très restraintes, mais tout de même je ne comprend pas pourquoi cette anomalie de l'arrondissement du change dépendant du modulo.

si quelqu'un pourrait me donner un indice pour résoudre ce problème afin que je puisse tourner la page sur le cas du modulo qui m'empèche de poursuivre mon programme ça serait génial et apprécié.

voici le segment du code qui concerne mon problème de modulo:


case 'P':
if (dSousTotal != 0)
{
do
{
system("cls");

dTps = dSousTotal * 5 / 100;

dTvq = (dSousTotal + dTps) * 9.5 / 100;

dTotal = dSousTotal + dTps + dTvq;

iArrondissement1 = dTotal * 100;

iArrondissement2 = iArrondissement1 % 10;

//Test pour vérifier si ma programmation du modulo est fonctionnelle
std::cout << "arrondissement1 = " << iArrondissement1 << " arrondissement2 = " << iArrondissement2 << "\n";

std::cout << "Finaliser la transaction\n"
<< "\n"
<< "Sous-total: " << dSousTotal << "$\n"
<< "TPS: " << dTps << "$\n"
<< "TVQ: " << dTvq << "$\n"
<< "Total: " << dTotal << "$\n";

if (iArrondissement2 == 0)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << dTotal << "$\n";
}
if (iArrondissement2 == 1)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal - 0.01) << "$\n";
}
if (iArrondissement2 == 2)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal - 0.02) << "$\n";
}
if (iArrondissement2 == 3)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal + 0.02) << "$\n";
}
if (iArrondissement2 == 4)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal + 0.01) << "$\n";
}
if (iArrondissement2 == 5)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << dTotal << "$\n";
}
if (iArrondissement2 == 6)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal - 0.01) << "$\n";
}
if (iArrondissement2 == 7)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal - 0.02) << "$\n";
}
if (iArrondissement2 == 8)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal + 0.02) << "$\n";
}
if (iArrondissement2 == 9)
{
std::cout << "Montant à payer: " << std::fixed << std::setprecision(2) << (dTotal + 0.01) << "$\n";
}



(le code continue après ça mais c'est ce segment que je dois absolument résoudre mon problème de modulo qui arrondi mal)

PS. J'ai essayer de mettre de la couleur dans ce post pour que le code soit plus lisible mais je ne trouve pas l'option '' c++ '' dans la liste :(

2 réponses

piopicolo Messages postés 1395 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 31 juillet 2023 193
22 sept. 2016 à 06:35
Bonjour,
Si en fait tu veux supprimer la deuxième décimale quel qu'en soit la valeur (0 à 9) (ce qui est plus sympa pour le client plutôt que d'arrondir au dessus si la valeur est supérieure ou égale à 5), tu multiplies ton chiffre par dix et tu supprimes la partie décimale puis tu divises par 10.
Mais ce n'est peut-être pas ce que tu veux faire.
A+
0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
22 sept. 2016 à 22:31
Bonjour,

Pour avoir un arrondi à 5 centimes. 20 fois le nombre doit être entier d'où :
double totalArrondi = std::floor(dTotal * 20. + .5) / 20.;
.
Le + 0.5 permet un arrondi au plus proche, sinon ce serait un arrondi en dessous. Fonctionne pour tout nombre positif ou nul.

Attention, les nombres flottants ne sont pas des décimaux. Le nombre final est très proche de la valeur décimale mais doit être affiché avec set::precision(2).
0
Demonaz84 Messages postés 12 Date d'inscription samedi 10 septembre 2016 Statut Membre Dernière intervention 5 décembre 2016
22 sept. 2016 à 22:46
salut, merci beaucoup pour la reponse !

cependant je n'ai pas le droit de me servir de '' floor'' , parce que on ne l'a pas vu en classe.

""
Votre code ne doit utiliser que les instructions vues en classe :
 Variables et constantes
 Types de base (char, short, unsigned short, int, unsigned int, long, unsigned long, float, double, bool)
 Entrées et sorties (std::cin et std::cout)
 Opérations arithmétiques
 Instructions conditionnelles
 Opérations logiques
 Boucles
 Instruction system: system("pause"), system("cls")
 Modificateurs de sorties: std::fixed, std::setprecision()
""

y aurait-il une façon de faire le même résultat sans la commande ''floor'' ?
0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101 > Demonaz84 Messages postés 12 Date d'inscription samedi 10 septembre 2016 Statut Membre Dernière intervention 5 décembre 2016
22 sept. 2016 à 23:13
Si le cast a été vu en classe. Un code qui marche pour les montants de 0 à 107374182
double totalArrondi = (int)(dTotal * 20. + .5) / 20.;
// ou en 2 lignes
int nbPieces = dTotal * 20. + .5;  // produit un warning car il manque le cast
double totalArrondi = nbPieces / 20.;
// dans ton code, tu l'utilises quand tu fait :
iArrondissement2 = iArrondissement1 % 10; // % ne fonctionne qu'avec 2 entiers et  iArrondissement1 est donc implicitement 'casté' en int avec warning

Et je ne dis pas bravo à ton prof qui utilise std::system()
0