2010-05-02 7 views
1

(tous sont déclarés comme ints, ne sont initialisés à quoi que ce soit à l'avance. J'ai inclus math.h et je suis en compilant avec -lm)C programme donnant une sortie incorrecte pour les mathématiques simples!

cachesize = atoi(argv[1]); 
blocksize = atoi(argv[3]); 
setnumber = (cachesize/blocksize); 
printf("setnumber: %d\n", setnumber); 
setbits = (log(setnumber))/(log(2)); 
printf("sbits: %d\n", setbits); 

lorsqu'il est administré cachesize comme 1024 et blocksize que la sortie 16 est la suivante :

setnumber: 64 
sbits: 5 

mais log (64)/log (2) = 6!

Cela fonctionne correctement quand cachesize 512 et bloque 32. Je n'arrive pas à gagner. J'espere vraiment que c'est une erreur stupide de ma part, et je serais reconnaissant si quelqu'un pouvait indiquer ce que c'est! Je vous remercie! PS: J'ai posté cela dans Yahoo Answers d'abord, mais c'était probablement stupide. Je ne referai pas ça.

+0

@DuffDuff - ne pas oublie d'accepter la meilleure réponse. –

+2

+1 à poster sur Yahoo Réponse étant une idée stupide :) –

Répondre

5

log renvoie un double. Vous devriez arrondir au lieu de tronquer. Cependant, vous pouvez utiliser log2 ici.

+0

Excellent! Je vous remercie. =] – DuffDuff

+0

De plus, il existe une fonction 'log2()' pour obtenir directement les logarithmes de base 2, au lieu de faire cette division vous-même. –

+0

Vous avez posté cela une seconde avant que j'ajoute ça, Carl. :) –

1

Ce qui se passe est que ni log(2) ou log(setnumber) sont exactement représentables sous forme de nombres à virgule flottante, et leurs erreurs d'arrondi conspirent pour provoquer leur quotient pour arrondir à quelque chose juste plus petit que 6, qui tronque alors 5 lors de la conversion à entier.

L'utilisation log2() résoudra ce problème sur certaines plates-formes qui ont une bibliothèque de mathématiques de bonne qualité, mais la norme C ne garantit pas quoi que ce soit sur l'exactitude des log() ou log2() (en effet, certaines plates-formes simplement mettre log2() comme log()/log(2), donc cela peut vous donner le même problème que vous avez maintenant).

Vous souhaitez utiliser la fonction ilogb(), qui renvoie l'exposant de son argument en tant que valeur entière signée.

setbits = ilogb(setnumber); 

Cela a l'avantage d'être un peu plus rapide sur certaines plateformes.

(Il est vrai que, cette utilisation ilogb n'est pas portable aux systèmes qui utilisent non-radix-2-virgule flottante, mais c'est une préoccupation beaucoup plus petite que les plates-formes qui ont juste des bibliothèques mathématiques de mauvaise qualité)

Questions connexes