给出公式:
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中的位数?
答案 0 :(得分:2)
计算基数
N
中整数位数是否安全b
使用对数函数?
由于四舍五入错误,绝对不是。具体而言,风险是log(N)/log(b)
略小于确切值。当N
是b
的精确倍数时,最有可能发生这种情况。
如何计算基数
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++;
这会计算位数。不计算符号字符。