C程序为简单的数学提供错误的输出!

时间:2010-05-02 22:45:23

标签: c

(所有都被声明为int,没有事先被初始化为任何东西。我已经包含math.h并且正在使用-lm进行编译)

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并且blockize为16时,输出如下:

setnumber: 64
sbits: 5

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

当给出cachesize 512并阻塞32时,它可以正常工作。我似乎无法获胜。

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

PS:我先在Yahoo Answers上发布了这个,但这可能很傻。不会那样做。

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

正在发生的事情是,log(2)log(setnumber)都不能完全代表浮点数,而且它们的舍入误差会导致它们的商数向下舍入到小于{{1}的值。 },然后在转换为整数时截断为6

使用5可以在某些具有高质量数学库的平台上解决此问题,但C标准实际上并未保证log2( )log( )的准确性(实际上,某些平台只是将log2( )实现为log2( ),因此它可能会给您带来与您现在相同的问题。)

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

ilogb( )

这有一个额外的好处,就是在某些平台上要快得多。

(不可否认,这种使用setbits = ilogb(setnumber); 不能移植到使用非基数-2浮点数的系统,但这比那些只有伪劣数学库的平台要小得多。