2013-01-16 5 views
-2

Je viens de commencer à coder en C++ mais j'ai une bonne expérience avec MATLAB et MySql. J'essaie de calculer quelques nombres composés donc la précision est la clé. J'ai essayé de le faire en utilisant des nombres doubles, mais pour une raison quelconque, je ne reçois jamais une précision de 7 chiffres significatifs (la même chose qu'un flotteur). J'ai même essayé d'utiliser un long double pour essayer les calculs mais je n'ai toujours que 7 sf. de précision.Visual Express 2010 double précision variable

N'ai-je pas initialisé correctement les doubles? Je pensais qu'ils faisaient partie de la bibliothèque standard? Toute aide grandement appréciée. Le code ci-dessous donne les principales parties du code utilisées pour le calcul (le reste est principalement le chargement de données ou le débogage).


MISE À JOUR

Voici un échantillon du code (moins la lecture de données). J'ai entré les 5 premières valeurs. Les calculs devraient donner (RÉSULTATS ATTENDUS) Calculé dans Excel, en utilisant exactement la même entrée:

0 
-1.09526 
4.364551963 
2.745835774 
3.029002506 

Qu'est-ce que le code ci-dessous donne (SORTIE RÉEL):

0 
-1.095260000 
4.3591394642 
2.7340763329 
3.0179393198 

code:

#include <fstream> 
#include <iostream> 
#include <sstream> 
#include <string> 
#include <vector> 


using namespace std; 

int main(){ 

std::vector<double> compoundedcalculation; // pre-allocating for the compounded calculations 
std::vector<double> dailycompound; // pre-allocating for daily compoundvalue 
compoundedcalculation.insert(compoundedcalculation.end(), 0.0); // setting the first value as 0 

double dailycompoundval[] = {0,-1.09526,5.46038,-1.61801,0.283089}; 
dailycompound.assign(dailycompoundval,dailycompoundval+5); 
double indCC; 

for (int n = 0; n < 5 ;n++) 
    { 
    indCC = ((((1+((compoundedcalculation.at(n))/1000))*(1+((dailycompound.at(n))/1000)))-1)*1000); 

    printf(" %.17g \n", indCC); 


    compoundedcalculation.insert(compoundedcalculation.end(), indCC); 
    } 
return 0; 
} 

Merci pour l'effort.


MISE À JOUR 2:

Les deux attendus et les résultats réels utilisent la même formule pour la capitalisation.

Compounded Total = ((1+ (Daily Rate/10000)) * (1+ (Précédent Compounded Total/10000)))

Les tarifs journaliers sont:

1er jour: 0 2 jour: -1,09526 3ème jour: 5,46038 4ème jour: -1,61801 5ème jour: 0,283089

+1

Comment pouvez-vous dire qu'il stocke seulement 7 chiffres de précision? – yiding

+0

Vous devez inclure la partie où vous imprimez les numéros ou recherchez-vous uniquement le débogueur? – Mario

+0

Il est inutile de nous demander de deviner. Si vous voulez une aide significative, vous devez montrer un programme qui présente un comportement que vous ne comprenez pas. Ensuite, nous pouvons l'expliquer. –

Répondre

1

Dans Visual studio, double est IEEE754 à double precison. Cela a 53 bits de précision binaire, ou environ 15-16 chiffres significatifs décimaux.

Votre code de diagnostic qui imprime les valeurs n'imprime probablement que 7 chiffres de précision. Ou votre vue de débogueur affiche seulement 7 chiffres de précision. En d'autres termes, le problème ne réside pas dans le type de données sous-jacent, mais dans la façon dont vous visualisez ces données.

Update 1

Vos commentaires indiquent que vous croyez que les calculs sur les valeurs doubles de précision sont réalisées avec une précision unique. Par défaut, ce ne sera pas le cas. Cela peut arriver si vous avez changé le contrôle de précision à virgule flottante avec un appel à _controlfp.Toutefois, si votre contrôle à virgule flottante est défini sur la valeur par défaut, les opérations sur les valeurs à double précision ne seront pas arrondies à la précision simple.

Mise à jour 2

Vos calculs Excel effectuent un calcul différent. La sortie de votre programme C++ correspond au code. La première sortie de valeur non nulle -1.09526 qui correspond au code. Parce que le code indique que la valeur doit être dailycompoundval[1]. La valeur correspondante de votre code Excel est -1.095231419 qui ne correspond donc pas au code C++.

En d'autres termes, la question est un rouge-hareng. Il n'y a pas de problèmes d'arrondi ici. Le problème est entièrement dû aux différences entre les deux versions différentes de votre code.

Mise à jour 3

Code C++ ne correspond pas à l'expression dans la dernière mise à jour. Le code utilise un facteur multiplicatif de 1000, mais votre expression utilise un facteur de 10000.

+0

Merci pour votre réponse, mais l'erreur de précision est dans le calcul réel plutôt que l'affichage/résultat. – Mkoll

+0

@Mkoll Si tel est le cas, le prouver. Produire un programme qui montre cela. Jusqu'à ce que vous puissiez le faire, nous ne pouvons pas faire grand-chose. –

+0

Avoir modifié le message d'origine pour inclure un petit programme pour produire l'erreur. Bravo – Mkoll

4

double est flottante IEEE 64 bits sur votre machine, il stocke 15-17 chiffres décimaux significatifs. Vous n'avez pas à faire quelque chose de spécial pour cela. Votre problème est la façon dont vous l'imprimez à l'écran, que vous n'avez pas montré. Par défaut, les valeurs sont arrondies à 6 chiffres significatifs, vous devez donc augmenter comme suit:

cout.precision(17); 
cout << x; 

ou

printf("%.17g", x); 

fonction de votre mode de sortie.

MISE À JOUR: Prendre une calculatrice de haute précision et de faire le calcul que je reçois manuellement:

n = 0: ((1 + 0/1000)*(1 + 0/1000) - 1)*1000 
     == 0 
n = 1: ((1 + 0/1000)*(1 + -1.09526/1000) - 1)*1000 
     == -1.09526 
n = 2: ((1 + -1.09526/1000)*(1 + 5.46038/1000) - 1)*1000 
     == 4.3591394642012 
n = 3: ((1 + 4.3591394642012/1000)*(1 + -1.61801/1000) - 1)*1000 
     == 2.734076332956727816388 
n = 4: ((1 + 2.734076332956727816388/1000)*(1 + 0.283089/1000) - 1)*1000 
     == 3.017939319891748203508813462532 

Les mêmes résultats que je reçois quand je lance le code:

0 
-1.0952599999999999 
4.3591394642012 
2.7340763329567279 
3.0179393198917484 

Cependant, quand je remplacer 1000 par 10000 je reçois vos "résultats attendus",

0 
-1.0952599999999999 
4.3645219464201199 
2.7458057624046663 
3.0289724931454134 

qui semble répondre à votre question.

+0

Merci pour votre réponse, mais l'erreur de précision est dans le calcul réel plutôt que l'affichage/résultat. – Mkoll

+0

@Mkoll: si vous avez essayé ce qui précède, postez la sortie attendue et la sortie que vous avez. De préférence poster un [SSCCE] (http://sscce.org/). – ybungalobill

+0

Hey ybungalobill, ont ajouté un exemple des résultats et un petit programme du problème. Merci! – Mkoll

Questions connexes