如何统计不同基数中的数字位数?

时间:2015-04-24 12:24:36

标签: python c algorithm base

我正在处理不同基地的数字(基数为10,基数为8,基数为16等)。我试图计算每个数字中的字符数。

实施例

  

号码:ABCDEF

     

位数: 6

我知道基于对数的方法,但我遇到了一些问题。

  1. This Python script输出无法正确计算1,000,000个中的3,969个数字中的位数。

  2. 我认为使用对数的方法可能会相当慢

  3. 链接:

    • This C program必须非常慢(如果我有一个非常大的数字怎么办?)。它也不能处理不同基数的数字(例如,基数为16)。

    • 不是this的欺骗,因为OP只询问基数为10

    编辑当然我可以计算字符串的长度,但最让我感兴趣的是,是否可以进行的计算而不需要字符串。我想知道只需要知道 source-base 转换为的基础的算法。

    Edit2: source-base base-10 转换为的基础可以是任何其他基础。

    我们如何计算不同基数中的数字位数?

    如果我知道base-10中的数字,如何在不执行转换的情况下计算转换为base-16(base-8等)的相同数字的位数?< / p>

    注意:非常感谢一些Python或C代码

3 个答案:

答案 0 :(得分:8)

对数不应该很慢。您可以通过以下公式轻松计算任意基数的对数:logBaseN(x)=logBaseA(x)/logBaseA(N) - 您可以使用ln(基数e = 2.718 ...)或logBase10或您拥有的任何数据。所以你真的不需要一个程序,一个公式应该这样做:

num_digets(N, base) = 1 + floor(log(N) / log(base))

其中N是您的号码,base是您想要该号码的基数。

有关详细说明,请查看此处: http://www.mathpath.org/concepts/Num/numdigits.htm

答案 1 :(得分:2)

请注意,您的Python代码中的NumToStr()函数由于您的基础中的off-by-one而不正确,应该是:

def NumToStr(num):
    str=''
    while num:
            str+=alpha[(num)%base]
            num=(num)/base
    return ''.join(list(reversed(str)))

请注意,检查此函数是否返回正确的结果会发现错误(例如,使用alpha="0123456789")。

通过此修复,我们使用给定的公式获得正确的位数:

nDigits = int(ceil(log(nmb, base)))

除了以确定基地的精确权力(base**0base**1base**2等等),它正好比它简单一个应该。这可以通过稍微更改forumla来解决:

nDigits = 1 + floor(log(nmb, base))

请注意,即使这对某些输入似乎也失败了(例如,从base-10转换为base-10,它错误地表示1000位为3位,1000000位为6位)。这似乎是由于浮子的固有精度,例如:

print floor(log(1000, 10))

输出2而不是预期的3

关于你提到的性能问题,在你完成分析/基准测试之前,我不会担心这些简单代码的性能问题。例如,你的非常慢&#34;对于128位数字,C代码最多只需要38个除以10。如果您需要比此更好的性能,那么您将遇到与此处提到的任何简单方法相同的问题。我能想到的最快的事情是使用查找表和线性插值的组合的自定义log()函数,但是你必须要小心得到的精度。

答案 2 :(得分:1)

我不确定我理解你的问题。当你说你的初始数字在基数b1时,是否意味着你在基数b1中将它表示为一个字符串?也许你想构建一些表格,告诉你基数b1中的哪个数字对应于b2,b2 ^ 2,b2 ^ 3,...然后将你的数字与这些数字进行比较,看看它适合的位置。

否则我会选择你提到的算法,它可以很容易地被任何基础所采用。

输入:您的整数x,您想要计算数字的基数b2。

int number_of_digits (int x, int b2) {
    int n = 0;
    while (x >0) {
        x/=b2;
        n++;
    }
    return n;
}

这两种方法在n中都是线性的。

编辑:如果您想加快速度,可以将其作为二进制搜索来实现。然后你可以得到O(log(n))。