Travailler avec des flotteurs et des entiers

J’ai créé un programme semblable à un guichet automatique qui contient l’argent dans le compte d’une personne. Lorsque la personne souscrit un retrait, elle le soustrait du compte avec un supplément de .50. Le problème que j’ai est de travailler avec les entiers et les flottants dans ce programme. J’ai converti le compte entier en un nombre à virgule flottante, mais un message d’erreur s’affiche lorsque j’essaie d’imprimer la déclaration. Est-ce que quelqu’un peut me dire ce que je fais mal?

#include  int main (void) { int account = 2000; int withdrawal; float charge = 0.50; printf ("How much money would you like to take out? "); scanf ("%i", &withdrawal); while (withdrawal % 5 != 0) { printf ("Withdrawal must be divisible by 5. "); scanf("%i", &withdrawal); } account = ((float) account - charge) - withdrawal; printf("Remaining account: %.2f\n", account); return 0; } 

 int account = 2000; printf("Remaining account: %.2f\n", account); 

C’est faux; il doit s’agir de "%d" pour un entier, ou mieux, remplacez le type de variable de votre account par quelque chose qui pourrait représenter le 0,50 que vous surchargez. Je ne vous recommande pas non plus d’utiliser (imprécis) float s pour de l’argent. Vous ne voulez pas retirer 10.499999997 alors que vous vouliez dire 10.5 . Vous devez penser aux règles de précision et d’arrondi que vous utiliseriez. Autant que je sache, ils sont tous deux prescrits par des lois ou quelque chose du genre.

Vous ne pouvez tout simplement pas utiliser de valeurs à virgule flottante pour représenter la devise, car elles ont des propriétés incorrectes. Tous les nombres ne sont pas exactement représentables, vous aurez donc des effets “mystérieux”.

Il vaut mieux utiliser une approche “à point fixe”, le plus simple est de prendre un type entier plus grand, tel que long , puis de le multiplier par un entier, généralement 100 si tout ce dont vous avez besoin est exprimé en cent (pour la devise américaine). Si vous avez besoin de fractions de centimes, multipliez par 10 000, par exemple, pour pouvoir représenter toutes les valeurs jusqu’à un centième de centième.

Avec ce schéma, 1 $ serait:

 long one_dollar = 1 * 10000; 

Et 13 cents seraient:

 long thirteen_cents = 13 * 100; 

Notez que cela limite la quantité d’argent que vous pouvez représenter. Finalement, vous aurez peut-être besoin d’une bibliothèque de précision arbitraire pour obtenir des entiers de précision “illimitée”.

S’il vous plaît , n’utilisez pas de flotteurs pour manipuler de l’argent. Utilisez un type entier, comme pour suivre les cents, puis convertissez-le à la sortie en dollars et en cents (ou toute autre devise).

En particulier, 0.1 décimal n’a pas une représentation exacte en virgule flottante. Au lieu de cela, il est représenté comme une fraction binary répétée sans fin (0.19999999999 …. hex ). De même, 0,01 décimal correspond à environ 0,028F5C28F … hex .

Rendez votre vie un peu plus facile, et plutôt que de considérer vos “intérêts” comme des dollars, considérez-les comme des “cents”, vous n’aurez donc pas besoin de nombres à virgule flottante.

L’avertissement que vous voyez est dû au fait que vous passez un int à printf() après lui avoir donné %.2f comme chaîne de formatage. Cette chaîne de format doit être utilisée pour les nombres à virgule flottante. Voir printf .

Il y a cependant une faille plus fondamentale dans le code. Vous ne devez pas utiliser de variables à virgule flottante pour représenter des nombres lorsque des fractions décimales exactes sont requirejses, en particulier lorsque vous travaillez avec des montants monétaires. En bref, la raison pour laquelle vous n’utilisez pas de nombres à virgule flottante dans votre application est que les fractions décimales ne peuvent pas être représentées exactement. Dans chaque système de numération positionnel, certains nombres sont représentés par une séquence répétée infinie. Par exemple,

dans le système décimal 1/3 est représenté par 0.33 [3]

(crochets indiquant une séquence de chiffres répétée à l’infini). De même, en binary, certains nombres nécessitent une séquence infinie de 0 et de 1 pour être représentés. Par exemple,

dans le système binary, 1/10 est égal à 0,000110011 [0011]

Comme les registres et les emplacements de mémoire ont une longueur finie, celle-ci est arrondie vers le haut ou le bas et représente un nombre légèrement supérieur ou inférieur à 0,1. Ainsi, vous ne pouvez pas stocker la valeur exacte 0.1 dans un float ou un double .

Pour plus de détails, voir Ce que tous les informaticiens devraient savoir sur l’arithmétique en virgule flottante .

Une alternative consiste par exemple à utiliser des variables entières représentant des cents.

vous imprimez le compte comme s’il s’agissait d’un nombre à virgule flottante ( %2f ) même s’il s’agit d’un entier, utilisez plutôt le spécificateur de format %d

Vous devriez probablement utiliser des nombres décimaux codés en binary lorsque vous traitez avec de l’argent. Cela vous permettra d’utiliser une seule variable pour les dollars et les cents. Pendant que vous y êtes, vous pouvez spécifier une union de structure typedef qui vous permettra de spécifier la valeur en dollars, en cents, en dollars entiers uniquement et en cents restants uniquement. À court d’échange avec d’autres monnaies, cela conviendra à tous les scénarios monétaires.