【问题标题】:How to count the number of digits in numbers in different bases?如何计算不同基数的数字位数?
【发布时间】:2015-07-03 01:24:38
【问题描述】:

我正在处理不同基数(base-10、base-8、base-16 等)的数字。我正在尝试计算每个数字中的字符数。

例子

号码:ABCDEF

位数:6

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

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

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

链接:

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

  • 不是this 的骗子,因为 OP 只询问 base-10


编辑:当然我可以计算字符串的长度,但我最感兴趣的是,是否可以在没有字符串约定的情况下进行计算。我想知道只知道 source-base要转换为的基础 的算法。

Edit2: source-basebase-10 并且 要转换为的基础 可以是任何其他基地。


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

如果我知道以 10 为底的数字,我如何计算转换为以 16 为底(以 8 为底等)的同一数字中的位数而不执行转换

注意:一些 Python 或 C 代码将不胜感激

【问题讨论】:

  • 在给你一个完整的答案之前只是一个想法,如果这样的方法让你满意:找到所需的幂 n 例如 16^n > your_number > 16^n ,因为这样的数量数字应该类似于 n...
  • 您是在问我们如何调试您的 Python 脚本吗?
  • @EmmanuelJay,我认为任何足够快的方法都适合。
  • @abarnert,不,我想我可以自己解决这个问题。此脚本用于测试使用对数的方法。
  • @vib,哦,是的,我忘了说source_base 是base-10,哎呀,现在正在编辑...

标签: python c algorithm base


【解决方案1】:

请注意,您的 Python 代码中的 NumToStr() 函数不正确,因为您的基础中存在一对一,它应该是:

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)))

except 对于底数的精确幂(base**0base**1base**2 等...),它恰好比应有的值小一。这可以通过将论坛稍微更改为:

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

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

print floor(log(1000, 10))

输出2,而不是预期的3

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

【讨论】:

    【解决方案2】:

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

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

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

    更多解释请看这里: http://www.mathpath.org/concepts/Num/numdigits.htm

    【讨论】:

    • Google 设法向我隐藏了这个链接,现在要调查它
    • 谢谢。我猜 n = 0 将是一个特例?
    • @MattiasWadman 是的,当然。在所有基础上都是1。如果这对您来说是个问题,您还需要处理负数(并决定在您的情况下合理的返回值是多少 - N-N 的位数相同,但为了显示您可能需要为- 添加一个额外的字符。
    【解决方案3】:

    我不确定我是否理解您的问题。当您说您的初始数字以 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 中是线性的。

    EDIT :如果您想更快,可以将其实现为二进制搜索。然后你可以得到 O(log(n))。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 2017-08-06
      • 2018-06-12
      • 2014-12-11
      • 1970-01-01
      相关资源
      最近更新 更多