C:使用对数函数

时间:2016-02-23 19:19:48

标签: c logarithm

给出公式:

NUM_DIGITS_IN_N_FOR_BASE_B = 1 + floor(ln(abs(N)) / ln(b))

这样b是2到36之间的基数,而N的类型是int。

根据这篇文章post 1,似乎可以假设为所有整数[INT_MIN, INT_MAX]的范围返回的值可以在没有舍入或溢出错误的情况下工作。我对此有点怀疑。我的怀疑主义来自我最近的一篇帖子@ post 2。如果使用数学定义不安全"在计算机程序中,是否有另一种技巧可用于计算给定基数b的数字N中的位数?

2 个答案:

答案 0 :(得分:2)

  

计算基数N中整数位数是否安全   b使用对数函数?

由于四舍五入错误,绝对不是。具体而言,风险是log(N)/log(b)略小于确切值。当Nb的精确倍数时,最有可能发生这种情况。

  

如何计算基数N中整数b中的位数?

N除以b循环,直到N为零。请参阅以下代码中的countDigits功能。处理N <= 0的值是留给读者的练习。

例如,请考虑以下代码

int countDigits( int N, int b )
{
    int count;
    for ( count = 0; N; count++ )
        N /= b;
    return count;
}

int main( void )
{
    int N, b;
    if ( scanf( "%d %d", &N, &b ) != 2 )
        return 1;

    printf( "log(%3d) = %.50lf\n", N, log(N) );
    printf( "log(%3d) = %.50lf\n", b, log(b) );
    printf( "ratio    = %.50lf\n", log(N)/log(b) );
    printf( "expected = %d\n", countDigits(N, b) );
    double digits = 1 + floor(log(N) / log(b));
    printf( "computed = %lf\n", digits );
}

如果用户为N输入243,为b输入3,则输出为

log(243) = 5.49306144334054824440727315959520637989044189453125
log(  3) = 1.09861228866810978210821758693782612681388854980469
ratio    = 4.99999999999999911182158029987476766109466552734375
expected = 6
computed = 5.000000

由于243 10 = 100000 3 ,预期的位数为6。对数方法的问题是log(243)稍微过小或log(3)稍微过大,导致比率恰好低于5时应该是5 }}

答案 1 :(得分:2)

@user3386109很好地回答了帖子的第一部分。

第二部分:

  

还有另一种技巧可用于计算数字N中的位数   给出一个基数b。?

// Works for all `N` including `0`, `INT_MIN`
int num_digs = 1;
int T = N;
while (T /= b) num_digs++;

这会计算位数。不计算符号字符。