C:使用对数函数计算基数(b)的整数(N)中的位数是安全的

C:使用对数函数计算基数(b)的整数(N)中的位数是安全的,c,logarithm,C,Logarithm,根据公式: NUM_DIGITS_IN__N_,用于底部=1+楼层(ln(abs(N))/ln(B)) 使得b是介于2和36之间的基数,N是int类型 根据这篇文章,可以假设所有整数[INT\u MIN,INT\u MAX]范围内返回的值不会出现舍入或溢出错误。我对此有点怀疑。我的怀疑来自我最近的一篇帖子。如果在计算机程序中使用数学定义是不“安全”的,那么在给定基数b的情况下,计算数字N中的位数还有其他技巧吗 以基数计算整数N的位数是否安全 b使用对数函数 不,绝对不是,因为四舍五入错误。具体而

根据公式:

NUM_DIGITS_IN__N_,用于底部=1+楼层(ln(abs(N))/ln(B))

使得
b
是介于2和36之间的基数,
N
是int类型

根据这篇文章,可以假设所有整数
[INT\u MIN,INT\u MAX]
范围内返回的值不会出现舍入或溢出错误。我对此有点怀疑。我的怀疑来自我最近的一篇帖子。如果在计算机程序中使用数学定义是不“安全”的,那么在给定基数b的情况下,计算数字N中的位数还有其他技巧吗

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

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

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

在循环中将
N
除以
b
,直到
N
为零。请参见下面代码中的
countDigits
功能。
N的处理值很好地回答了文章的第一部分

第二部分:

计算数字N中的位数还有其他技巧吗 给一个基数b


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

按照标准,这是不安全的。我还怀疑舍入错误。最好使用整数算法;注意,您可能不需要精确的对数,而是需要整数结果。基本思想是找到MSbit。@user3386109可以以非常简单的方式为INT_MIN或0添加特殊情况。@user3386109很好,这就是我认为会发生的事情。现在问题依然存在。计算基数b数字位数的最佳方法是什么。我希望我能选择帖子作为答案。
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 );
}
log(243) = 5.49306144334054824440727315959520637989044189453125
log(  3) = 1.09861228866810978210821758693782612681388854980469
ratio    = 4.99999999999999911182158029987476766109466552734375
expected = 6
computed = 5.000000
// Works for all `N` including `0`, `INT_MIN`
int num_digs = 1;
int T = N;
while (T /= b) num_digs++;