2010-05-02 99 views
1

(所有被声明为整数,没有被初始化为任何事情事前我已经包括math.h中,并正在与-lm编译)C程序给简单的数学提供不正确的输出!

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); 

给出的cachesize时为1024块大小为16的输出如下:

setnumber: 64 
sbits: 5 

但是log(64)/ log(2)= 6!

它在给定cachesize 512和blocksize 32时正常工作。我似乎无法获胜。

我真的很希望这是我的一个愚蠢的错误,如果有人能指出它是什么,我将不胜感激!谢谢!

PS:我先发布了这个在雅虎答案第一,但这可能是愚蠢的。不会再这样做。

+0

@DuffDuff - 不忘记接受最好的答案。 – 2010-05-02 23:28:57

+2

+1发布到雅虎答案是一个愚蠢的想法:) – 2010-05-02 23:38:53

回答

5

log返回一个双精度值。你应该舍入而不是截断。但是,您可以在此处使用log2

+0

优秀!谢谢。 =] – DuffDuff 2010-05-02 22:48:26

+0

另外,还有一个'log2()'函数可以直接得到基数2的对数,而不是自己进行分割。 – 2010-05-02 22:49:16

+0

你在我添加之前发布了一秒,卡尔。 :) – 2010-05-02 22:49:58

1

发生了什么事是,无论是log(2)log(setnumber)是作为浮点数精确表示,他们的舍入误差阴谋导致它们的商向下舍的东西只比6小,当你转换到,然后截断到5整数。

使用log2()将解决在某些平台上有良好的品质数学库这个问题,但C标准实际上并不保证有关log()log2()(精度东西的确,有些平台只实现log2()log()/log(2),所以它可能会给你现在遇到的同样的问题)。

您想使用ilogb()函数,该函数将其参数的指数作为有符号整数值返回。

setbits = ilogb(setnumber); 

这在另外一些平台上有更快的好处。

(诚然,这使用ilogb是不能移植到使用非基2浮点系统,但是这是一个非常小的关注,然后平台,只是有以次充好的数学库)