获取C中以2为底的对数时出错

时间:2019-04-22 07:37:31

标签: c math

我想获取数字1到2048的二进制对数,但是我不知道为什么它不起作用,它没有获得正确的数字。

如果我使用浮点数,它可以工作,但是它曾经用于整数,我已经用这种方法完成了一个程序,现在由于这个原因它不起作用。将unsigned int更改为int无效。有人知道为什么吗?

for(unsigned int numero=1;numero<=2048;numero*=2)
{
    int x=log10(numero)/log10(2);
    printf("%d\n",x);
}

return 0;

它打印:

0 1 2 2 4 5 5 6 8 9 10 11

应该是:

0 1 2 3 4 5 6 7 8 9 10 11

看起来它适用于某些数字,但是我不明白为什么它不适用于所有数字。

1 个答案:

答案 0 :(得分:2)

log10返回一个浮点数(双精度)。对于您传递的大多数数字,log10的值在浮点数中不能精确表示,因此您可能会得到类似log10(8)/log10(2) == 2.9999999的值,而不是确切的3。转换为int会将其截断为2。要解决此问题,您应该正确舍入:

int x = lrint(log10(numero)/log10(2));

或者如果您的编译器没有lrint函数,则可以使用:

int x = log10(numero)/log10(2) + 0.5;

适用于这种情况。

请注意,还有其他方法可以计算所需的结果。由于浮点数已将指数存储在基数2中,因此可以通过调用frexp来检索它:

int x;
frexp(numero, &x);

另一种方法是完全避免浮点数学运算,而使用内在函数获取numero中设置的最后一位的索引。不幸的是,没有跨平台的方法可以做到这一点。