2010-08-06 35 views
2

noob veut calculer l'intérêt composé sur l'iPhone.Objective C Math Formula Fail

float principal; 
float rate; 
int compoundPerYear; 
int years; 
float amount; 

formule doit être: = capital * (1 + taux/compoundPerYear)^(taux * ans)

je reçois légèrement réponse incorrecte avec:

amount = principal*pow((1+(rate/compoundPerYear)), (compoundPerYear*years)); 

Je suis test avec le taux de .1, mais les rapports de débogueur .100000001.

Est-ce que je fais mal? Dois-je utiliser des doubles ou des classes spéciales (par exemple, NSNumber)?

Merci pour toute autre idée! Après d'autres recherches, il semble que la classe NSDecimalNumber soit exactement ce dont j'ai besoin. Maintenant, je dois juste comprendre comment utiliser ce mauvais garçon.

+0

voir ma réponse http://stackoverflow.com/questions/14155360/convert-to-float-and-calculate/14155699#14155699 peut-être cela aidera un peu :) – TheTiger

Répondre

5

double vous rapproche, mais vous ne pouvez pas représenter 1/10 exactement en binaire (en utilisant la notation en virgule flottante IEEE, de toute façon).

Si vous êtes vraiment intéressé, vous pouvez regarder What Every Computer Scientist Should Know About Floating-Point Arithmetic. Lien honteusement volé d'un autre thread SO. L'explication rapide et sale est que le flottant est stocké en binaire avec des bits qui représentent des puissances fractionnelles de 2 (1/2, 1/4, 1/8, ...). Il n'y a tout simplement pas de méthode mathématique pour additionner ces fractions à exactement 1/10, donc 0,1 ne peut pas être représenté exactement en notation flottante IEEE.

double étend la précision du nombre en vous donnant plus de chiffres avant/après la base, mais il ne change pas le format du binaire d'une manière qui peut compenser cela. Vous aurez juste le bit supplémentaire quelque part plus tard sur la ligne, le plus probable.

Voir aussi:

et d'autres sujets similaires.


Poursuite de l'expansion que je ruminais sur le chemin du retour du travail: une façon que vous pourriez peut gérer cela est simplement en représentant toutes les valeurs monétaires en cents (comme int), puis conversion en dollars. cents lors de l'affichage des données. Ceci est en fait assez facile, aussi, puisque vous pouvez profiter de la troncature de division entière lors de la conversion:

int interest, dollars, cents; 
interest = 16034; //$160.34, in cents 
dollars = value/100; //The 34 gets truncated: dollars == 160 
cents = value % 100; //cents == 34 
printf("Interest earned to date: $%d.%d\n", dollars, cents); 

Je ne sais pas Objective-C, mais nous espérons que cet exemple C est logique aussi. Encore une fois, c'est juste une façon de le gérer. Il serait également amélioré en ayant une fonction qui fait le formatage de chaîne chaque fois que vous avez besoin d'afficher les données.

Vous pouvez évidemment trouver votre propre moyen (encore mieux!) De le faire, mais peut-être que cela vous aidera à démarrer. Si quelqu'un d'autre a des suggestions sur celui-ci, j'aimerais les entendre aussi!

+0

Merci pour votre réponse. J'espère que je peux avoir le temps (et les cerveaux) pour lire ce que chaque ordinateur. . . article un de ces jours, mais le tout début était utile. Le système de centimes que vous suggérez est ingénieux, mais trop confus pour moi. Cela fonctionnerait-il avec des pourcentages, multiplication, exposants, logorthms, etc.? – alrightSpider

+0

Ça peut marcher, oui. Le principal avantage est que vous avez un nombre à virgule flottante de moins à s'inquiéter. Même si vous utilisez NSDecimalNumber pour représenter le taux, il pourrait être plus facile de laisser les valeurs monétaires en cents. Ensuite, vous pouvez effectuer l'arithmétique entière autant que possible (par exemple en ajoutant deux montants d'argent ensemble). Si NSDecimalNumber est suffisamment précis pour vos calculs, il est tout à fait logique d'y aller. Encore une fois, je ne suis pas beaucoup d'un gars objectif-C :) – eldarerathis

+1

IMHO, comptabilité et mélange à virgule flottante seulement avec un soin et une considération immenses. Je crois comprendre qu'il existe des pratiques exemplaires établies, et que ce serait une bonne idée de les connaître et de les suivre. Une bonne première étape consiste à commencer par travailler en cents plutôt qu'en dollars. Si vous avez toujours besoin d'un type de valeur à virgule flottante, alors passer à celui qui fonctionne dans la base 10 au lieu de la base 2 peut aider. Ce n'est que la pointe d'un * très gros * iceberg des problèmes. – RBerteig

1

Réponse courte: N'utilisez jamais de nombres flottants pour de l'argent.

La méthode la plus simple qui fonctionne sur la plupart des plates-formes est de représenter l'argent comme des quantités entières de sa plus petite unité. La plus petite unité est souvent quelque chose comme un cent, bien que souvent 1/10 ou 1/100 d'un cent soient les unités de base réelles.

Sur de nombreuses plates-formes, il existe également des types de nombre disponibles pouvant représenter des nombres décimaux à virgule fixe.

Assurez-vous d'arrondir à droite. La comptabilité financière utilise souvent l'arrondi des banquiers.