2010-12-02 17 views
3

Je suis vraiment confus sur ce code.Comment boucler et augmenter de 0.01 à chaque fois?

Voici ce que je veux faire: Commencer avec une valeur "v" de 5, effectuer le reste des fonctions/calculs, augmenter la valeur "v" de 0,01, effectuer les fonctions/calculs, puis augmenter la valeur "v" de 0.01 à nouveau, exécute les fonctions ... faites ceci 500 fois ou jusqu'à ce que la valeur "v" de 10.00 soit atteinte, selon ce qui est le plus facile à coder.

Voici mon code au moment:

//start loop over v 
for(iv=5;iv<=500;iv++) { 
    v=0.01*iv; 
    //Lots and lots of calculations with v here 
} 

Voici ce que je reçois: je tenté de mettre iv < = 10 donc il ne 10 boucles que juste pour que je puisse le tester d'abord avant d'en quittant tous nuit. Il n'a fait que 6 boucles, commençant à v = 0,05 et se terminant à 0,1. Donc, le problème est que a) il n'a pas fonctionné pendant 10 boucles, b) il n'a pas commencé à 5.00, il a commencé à 0.05.

Toute aide serait appréciée.

EDIT: De la merde, tant de réponses! J'ai essayé 2 réponses différentes jusqu'à présent, les deux fonctionnent! J'ai regardé cela et changé le code pendant 3 heures, je ne peux pas croire que c'était si facile.

Répondre

7

Vous devez commencer à iv = 500. et si vous voulez 10 boucles, et iv++ est la mise à jour, alors vous arrêtez avant 510.

Raison: v = 0.01*iv, donc v = 5 signifie iv = 5/0.01 = 500. Comme pour le nombre d'itérations, si votre boucle for est de la forme for (x = N; x < M; x++) (constante N et M), alors max(0, M-N) boucles sont exécutées, si x n'est pas modifié dans la boucle et pas de choses étranges (par exemple débordement, moulages cachés de nombres négatifs à non signé, etc.) se produit.

EDIT

Au lieu d'utiliser v = 0.01 * iv, v = iv/100.0 est probablement plus précis. Raison: 0.01 n'est pas exactement représentable en virgule flottante, mais 100.0 l'est.

+0

Je pense que vous vous trompez sur l'erreur d'une multiplication étant identique à un plus grand nombre d'ajouts. Avec chaque ajout, l'erreur s'accumule parce que non seulement parce que 0.01 n'est pas exactement représentable, mais aussi parce que les résultats intermédiaires ne sont pas exactement représentables. – janm

+0

@janm: Oui. J'étais coupable de traiter les points flottants comme réels quand j'essayais d'y penser tout à l'heure. Corrigée. – lijie

-1

iv <= 10 ne le fait pas pour 10 boucles, il le fait jusqu'à iv est supérieur à 10.

+3

Cela ne résout pas réellement le problème. –

+2

En effet, ce n'est pas le cas. Mais cela * a * a) explique les observations du demandeur, et b) n'aggrave pas le problème. –

0
double iv; 
for(iv = 5.0; iv <= 10.0 ; iv += 0.01) { 
/* stuff here */ 
} 
+5

Les opérations avec des nombres à virgule flottante doivent être évitées autant que possible en raison d'inexactitudes IEEE 754. –

-1
//start loop over v 
for(iv=0;iv<500;iv++) //loop from 0 to 499 
{ 
    v=v+0.01; //increase v by 0.01 
    //Lots and lots of calculations with v here 
} 

cela devrait le faire

+3

Les opérations avec des nombres à virgule flottante doivent être évitées autant que possible en raison d'inexactitudes IEEE 754. –

0
int i; 
double v; 
v = 5; 
for (i = 0; i < 500; i++) 
{ 
    v += 0.01; 
    // Do Calculations Here. 

    if (v >= 10.00) break; 
} 

Cela vous donne à la fois. Cela va itérer au plus 500 fois, mais va sortir de cette boucle si la valeur v atteint (ou dépasse) 10,00.

Si vous vouliez seulement un ou l'autre:

10,00 Version:

double v; 
v = 5.0; 
while (v < 10.00) 
{ 
    v += 0.01; 
    // Do Calculations Here. 
} 

La version 500 itérations:

double v; 
int i; 
v = 5.0; 
for(i = 0; i < 500; i++) 
{ 
    v += 0.01; 
    // Do Calculations. 
} 

(Notez que ce n'est pas C99, qui permet une syntaxe de déclaration plus propre dans les boucles).

+3

Je suis fatigué de le dire, mais les opérations avec des nombres à virgule flottante doivent être évitées autant que possible en raison d'inexactitudes IEEE 754. –

+1

Comment proposez-vous d'incrémenter un nombre de 0,01, puis d'utiliser ce nombre dans les calculs sans opérations à virgule flottante? Surtout avec ceci étant un problème de devoirs, et à moins que ce soit dans certaines classes de méthodes numériques (ce qui ne semble pas être le cas), cela ne devrait pas avoir d'importance. –

+2

Peut-être que, au lieu d'indiquer pourquoi toutes les réponses sont fausses, vous pourriez fournir le bon. –

2

Changer le code de SiegeX il utilise des nombres entiers (« plus précis »):

double dv; 
int iv; 
for(iv = 500; dv <= 1000; iv += 1) 
{ 
    dv = (double)iv/100.0; 
} 
+0

Il n'est pas nécessaire de lancer 'iv' en' double' - la constante '100.0' a le type' double', donc 'iv' sera promu par les conversions arithmétiques habituelles. – caf

+0

@caf Je sais, mais juste pour que Johnny comprenne qu'il devra utiliser '(double)' avec 'iv' quand il veut le changer en 'double', et ne fera aucune erreur. –