在Python中,如何找到整数中的位数?


当前回答

对于子孙后代来说,这无疑是迄今为止解决这个问题最慢的方法:

def num_digits(num, number_of_calls=1):
    "Returns the number of digits of an integer num."
    if num == 0 or num == -1:
        return 1 if number_of_calls == 1 else 0
    else:
        return 1 + num_digits(num/10, number_of_calls+1)

其他回答

顶部的答案是说mathlog10更快,但我得到的结果表明len(str(n))更快。

arr = []
for i in range(5000000):
    arr.append(random.randint(0,12345678901234567890))
%%timeit

for n in arr:
    len(str(n))
//2.72 s ± 304 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit

for n in arr:
    int(math.log10(n))+1
//3.13 s ± 545 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

此外,我没有在数学方法中添加逻辑来返回准确的结果,我只能想象这会使它更加缓慢。

我不知道之前的答案是如何证明数学方法更快的。

假设您要求的是可以存储在整数中的最大数字,则该值与实现有关。我建议你在使用python时不要这样想。在任何情况下,相当大的值都可以存储在python 'integer'中。记住,Python使用鸭子类型!

编辑: 我在澄清提问者想要数字数之前给出了我的答案。就此而言,我同意公认答案所建议的方法。没什么可补充的了!

正如其他答案所示,使用log10会导致大n的错误结果,而使用len(str(…))或手动循环会导致大n的性能变慢。Jodag的答案提供了一个非常好的替代方案,它只适用于可能会使您的计算机崩溃的整数,但我们可以做得更好,甚至更快(对于n足够小的数学。Log2保证是准确的),避免使用对数,而是使用二进制:

def num_digits(n: int) -> int:
    assert n > 0
    i = int(0.30102999566398114 * (n.bit_length() - 1)) + 1
    return (10 ** i <= n) + i

让我们来分析一下。首先是奇怪的n.bit_length()。这将以二进制形式计算长度:

assert 4 == (0b1111).bit_length()
assert 8 == (0b1011_1000).bit_length()
assert 9 == (0b1_1011_1000).bit_length()

与对数不同,这对于整数来说既快速又精确。结果是,这个结果正好是(log2(n)) + 1。为了单独得到地板(log2(n)),我们减去1,因此n.bit_length() - 1。

接下来,我们乘以0.30102999566398114。这相当于log10(2)稍微舍入。这利用了对数规则,以便从地板(log2(n))计算地板(log10(n))的估计值。

现在,您可能想知道我们在这一点上可能有多差,因为尽管0.30102999566398114 * log2(n) ~ log10(n),但对于floor(0.30102999566398114 * floor(log2(n))) ~ floor(log10(n)),情况并非如此。回想一下x - 1 < floor(x) <= x,我们可以做一些快速的计算:

log2(n) - 1 < floor(log2(n)) <= log2(n)

log10(n) - 0.30102999566398114 < 0.30102999566398114 * floor(log2(n)) <= log10(n)

floor(log10(n) - 0.30102999566398114) < floor(0.30102999566398114 * floor(log2(n))) <= floor(log10(n))

请注意,floor(log10(n) - 0.30102999566398114)至少是floor(log10(n)) - 1,这意味着我们与结果最多相差1。这是最后的修正,我们检查10 ** i <= n,当结果太小时导致额外的1 +,当结果刚刚好时导致0 +。

类似于Jodag的答案,这种方法实际上对非常非常大的n无效,大约在10 ** 2 ** 52左右,其中i的误差超过-1。然而,这种大小的整数可能会使您的计算机崩溃,所以这应该足够了。

n = 3566002020360505
count = 0
while(n>0):
  count += 1
  n = n //10
print(f"The number of digits in the number are: {count}")

output: number中的位数为:16

这里是最简单的方法,不需要将int转换为字符串:

假设给出的数字为15位,例如;n = 787878899999999;

n=787878899999999 
n=abs(n) // we are finding absolute value because if the number is negative int to string conversion will produce wrong output

count=0 //we have taken a counter variable which will increment itself till the last digit

while(n):
    n=n//10   /*Here we are removing the last digit of a number...it will remove until 0 digits will left...and we know that while(0) is False*/
    count+=1  /*this counter variable simply increase its value by 1 after deleting a digit from the original number
print(count)   /*when the while loop will become False because n=0, we will simply print the value of counter variable

输入:

n=787878899999999

输出:

15