Python中整数的长度

时间:2010-02-03 04:56:52

标签: python count integer

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

26 个答案:

答案 0 :(得分:233)

如果您希望整数的长度与整数中的位数一样,您始终可以将其转换为str(133)之类的字符串,并查找其长度,如len(str(123))

答案 1 :(得分:194)

无需转换为字符串

import math
digits = int(math.log10(n))+1

还要处理零和负数

import math
if n > 0:
    digits = int(math.log10(n))+1
elif n == 0:
    digits = 1
else:
    digits = int(math.log10(-n))+2 # +1 if you don't count the '-' 

你可能想把它放在一个函数中:)

以下是一些基准测试。即使是非常小的数字,len(str())已经落后了

timeit math.log10(2**8)
1000000 loops, best of 3: 746 ns per loop
timeit len(str(2**8))
1000000 loops, best of 3: 1.1 µs per loop

timeit math.log10(2**100)
1000000 loops, best of 3: 775 ns per loop
 timeit len(str(2**100))
100000 loops, best of 3: 3.2 µs per loop

timeit math.log10(2**10000)
1000000 loops, best of 3: 844 ns per loop
timeit len(str(2**10000))
100 loops, best of 3: 10.3 ms per loop

答案 2 :(得分:30)

所有math.log10解决方案都会给您带来麻烦。

math.log10很快,但是当你的数字大于999999999999997时会出现问题。这是因为浮点数太多.9s,导致结果四舍五入。

解决方案是对高于该阈值的数字使用while计数器方法。

为了更快地创建10 ^ 16,10 ^ 17,依此类推,并将其作为变量存储在列表中。这样,它就像一个表查找。

def getIntegerPlaces(theNumber):
    if theNumber <= 999999999999997:
        return int(math.log10(theNumber)) + 1
    else:
        counter = 15
        while theNumber >= 10**counter:
            counter += 1
        return counter

答案 3 :(得分:21)

Python 2.* int取4或8个字节(32或64位),具体取决于您的Python构建。 sys.maxint2**31-1表示32位整数,2**63-1表示64位整数)会告诉您这两种可能性中的哪一种。

在Python 3中,int s(如Python 2中的long)可以采用任意大小的可用内存量; sys.getsizeof为您提供了任何给定值的良好指示,尽管 也计算了一些固定的开销:

>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28

如果像其他答案所暗示的那样,你正在考虑整数值的一些字符串表示,那么只需取出该表示的len,无论是基数10还是其他!

答案 4 :(得分:13)

将数字设为n,然后n中的位数由下式给出:

math.floor(math.log10(n))+1

请注意,这将为+ ve整数提供正确的答案&lt; 10E15。除此之外,math.log10的返回类型的精确限制开始,答案可能会被1除。我只会使用len(str(n))之外的那个;这需要O(log(n))时间,这与迭代10次幂相同。

感谢@SetiVolkylany让我对这个限制的注意。令人惊讶的是,看似正确的解决方案在实现细节方面有一些警告。

答案 5 :(得分:13)

好吧,如果没有转换成字符串,我会做类似的事情:

def lenDigits(x): 
    """
    Assumes int(x)
    """

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

极简主义递归FTW

答案 6 :(得分:5)

如亲爱的用户@Calvintwr所述,函数math.log10在范围之外的数字[-999999999999997,999999999999997]中存在问题,我们得到浮点错误。我在使用JavaScript(Google V8和NodeJS)和C(GNU GCC编译器)时遇到了这个问题,因此这里不可能有'purely mathematically'解决方案。

基于此gistanswer亲爱的用户@Calvintwr

import math


def get_count_digits(number: int):
    """Return number of digits in a number."""

    if number == 0:
        return 1

    number = abs(number)

    if number <= 999999999999997:
        return math.floor(math.log10(number)) + 1

    count = 0
    while number:
        count += 1
        number //= 10
    return count

我在长度高达20(含)的数字上进行了测试,并且可以。它必须足够,因为64位系统上的长度最大整数是19(len(str(sys.maxsize)) == 19)。

assert get_count_digits(-99999999999999999999) == 20
assert get_count_digits(-10000000000000000000) == 20
assert get_count_digits(-9999999999999999999) == 19
assert get_count_digits(-1000000000000000000) == 19
assert get_count_digits(-999999999999999999) == 18
assert get_count_digits(-100000000000000000) == 18
assert get_count_digits(-99999999999999999) == 17
assert get_count_digits(-10000000000000000) == 17
assert get_count_digits(-9999999999999999) == 16
assert get_count_digits(-1000000000000000) == 16
assert get_count_digits(-999999999999999) == 15
assert get_count_digits(-100000000000000) == 15
assert get_count_digits(-99999999999999) == 14
assert get_count_digits(-10000000000000) == 14
assert get_count_digits(-9999999999999) == 13
assert get_count_digits(-1000000000000) == 13
assert get_count_digits(-999999999999) == 12
assert get_count_digits(-100000000000) == 12
assert get_count_digits(-99999999999) == 11
assert get_count_digits(-10000000000) == 11
assert get_count_digits(-9999999999) == 10
assert get_count_digits(-1000000000) == 10
assert get_count_digits(-999999999) == 9
assert get_count_digits(-100000000) == 9
assert get_count_digits(-99999999) == 8
assert get_count_digits(-10000000) == 8
assert get_count_digits(-9999999) == 7
assert get_count_digits(-1000000) == 7
assert get_count_digits(-999999) == 6
assert get_count_digits(-100000) == 6
assert get_count_digits(-99999) == 5
assert get_count_digits(-10000) == 5
assert get_count_digits(-9999) == 4
assert get_count_digits(-1000) == 4
assert get_count_digits(-999) == 3
assert get_count_digits(-100) == 3
assert get_count_digits(-99) == 2
assert get_count_digits(-10) == 2
assert get_count_digits(-9) == 1
assert get_count_digits(-1) == 1
assert get_count_digits(0) == 1
assert get_count_digits(1) == 1
assert get_count_digits(9) == 1
assert get_count_digits(10) == 2
assert get_count_digits(99) == 2
assert get_count_digits(100) == 3
assert get_count_digits(999) == 3
assert get_count_digits(1000) == 4
assert get_count_digits(9999) == 4
assert get_count_digits(10000) == 5
assert get_count_digits(99999) == 5
assert get_count_digits(100000) == 6
assert get_count_digits(999999) == 6
assert get_count_digits(1000000) == 7
assert get_count_digits(9999999) == 7
assert get_count_digits(10000000) == 8
assert get_count_digits(99999999) == 8
assert get_count_digits(100000000) == 9
assert get_count_digits(999999999) == 9
assert get_count_digits(1000000000) == 10
assert get_count_digits(9999999999) == 10
assert get_count_digits(10000000000) == 11
assert get_count_digits(99999999999) == 11
assert get_count_digits(100000000000) == 12
assert get_count_digits(999999999999) == 12
assert get_count_digits(1000000000000) == 13
assert get_count_digits(9999999999999) == 13
assert get_count_digits(10000000000000) == 14
assert get_count_digits(99999999999999) == 14
assert get_count_digits(100000000000000) == 15
assert get_count_digits(999999999999999) == 15
assert get_count_digits(1000000000000000) == 16
assert get_count_digits(9999999999999999) == 16
assert get_count_digits(10000000000000000) == 17
assert get_count_digits(99999999999999999) == 17
assert get_count_digits(100000000000000000) == 18
assert get_count_digits(999999999999999999) == 18
assert get_count_digits(1000000000000000000) == 19
assert get_count_digits(9999999999999999999) == 19
assert get_count_digits(10000000000000000000) == 20
assert get_count_digits(99999999999999999999) == 20

使用Python 3.5测试的所有代码示例

答案 7 :(得分:4)

问这个问题已经有好几年了,但是我已经为几种计算整数长度的方法编制了基准。

def libc_size(i): 
    return libc.snprintf(buf, 100, c_char_p(b'%i'), i) # equivalent to `return snprintf(buf, 100, "%i", i);`

def str_size(i):
    return len(str(i)) # Length of `i` as a string

def math_size(i):
    return 1 + math.floor(math.log10(i)) # 1 + floor of log10 of i

def exp_size(i):
    return int("{:.5e}".format(i).split("e")[1]) + 1 # e.g. `1e10` -> `10` + 1 -> 11

def mod_size(i):
    return len("%i" % i) # Uses string modulo instead of str(i)

def fmt_size(i):
    return len("{0}".format(i)) # Same as above but str.format

(libc函数需要一些设置,我没有提供)

size_exp感谢Brian Preslopsky,size_str感谢GeekTantra,size_math感谢John La Rooy

以下是结果:

Time for libc size:      1.2204 μs
Time for string size:    309.41 ns
Time for math size:      329.54 ns
Time for exp size:       1.4902 μs
Time for mod size:       249.36 ns
Time for fmt size:       336.63 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.240835x)
+ math_size (1.321577x)
+ fmt_size (1.350007x)
+ libc_size (4.894290x)
+ exp_size (5.976219x)

(免责声明:该函数在输入1到1,000,000上运行)

以下是sys.maxsize - 100000sys.maxsize的结果:

Time for libc size:      1.4686 μs
Time for string size:    395.76 ns
Time for math size:      485.94 ns
Time for exp size:       1.6826 μs
Time for mod size:       364.25 ns
Time for fmt size:       453.06 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.086498x)
+ fmt_size (1.243817x)
+ math_size (1.334066x)
+ libc_size (4.031780x)
+ exp_size (4.619188x)

如您所见,mod_sizelen("%i" % i))是最快的,比使用str(i)快一点,并且比其他人快得多。

答案 8 :(得分:3)

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

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)

答案 9 :(得分:2)

from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1

答案 10 :(得分:1)

这是一个庞大但快速的版本:

def nbdigit ( x ):
    if x >= 10000000000000000 : # 17 -
        return len( str( x ))
    if x < 100000000 : # 1 - 8
        if x < 10000 : # 1 - 4
            if x < 100             : return (x >= 10)+1 
            else                   : return (x >= 1000)+3
        else: # 5 - 8                                                 
            if x < 1000000         : return (x >= 100000)+5 
            else                   : return (x >= 10000000)+7
    else: # 9 - 16 
        if x < 1000000000000 : # 9 - 12
            if x < 10000000000     : return (x >= 1000000000)+9 
            else                   : return (x >= 100000000000)+11
        else: # 13 - 16
            if x < 100000000000000 : return (x >= 10000000000000)+13 
            else                   : return (x >= 1000000000000000)+15

对于不太大的数字,仅进行5次比较。 在我的计算机上,它比math.log10版本快30%,比len( str())版本快5%。 好吧...如果您不疯狂使用它,那么没有吸引力。

这是我用来测试/测量功能的一组数字:

n = [ int( (i+1)**( 17/7. )) for i in xrange( 1000000 )] + [0,10**16-1,10**16,10**16+1]

注意:它不管理负数,但适应很容易...

答案 11 :(得分:1)

def digits(n)
    count = 0
    if n == 0:
        return 1
    
    if n < 0:
        n *= -1

    while (n >= 10**count):
        count += 1
        n += n%10

    return count

print(digits(25))   # Should print 2
print(digits(144))  # Should print 3
print(digits(1000)) # Should print 4
print(digits(0))    # Should print 1

答案 12 :(得分:1)

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

输出:数字的位数为:16

答案 13 :(得分:1)

如果您正在寻找不使用内置函数的解决方案。 唯一需要注意的是发送 a = 000 时。

def number_length(a: int) -> int:
    length = 0
    if a == 0:
        return length + 1
    else:
        while a > 0:
            a = a // 10
            length += 1
        return length
    

if __name__ == '__main__':
    print(number_length(123)
    assert number_length(10) == 2
    assert number_length(0) == 1
    assert number_length(256) == 3
    assert number_length(4444) == 4

答案 14 :(得分:1)

可以使用以下方法快速完成整数:

len(str(abs(1234567890)))

获取&#34; 1234567890&#34;

的绝对值字符串的长度

abs返回没有任何底片的数字(只有数字的大小),str将其转换/转换为字符串,len返回该字符串的字符串长度。< / p>

如果您希望它适用于花车,您可以使用以下任一项:

# Ignore all after decimal place
len(str(abs(0.1234567890)).split(".")[0])

# Ignore just the decimal place
len(str(abs(0.1234567890)))-1

供将来参考。

答案 15 :(得分:1)

def length(i):
  return len(str(i))

答案 16 :(得分:1)

这是另一种计算任意数字小数点前位数的方法

from math import fabs

len(format(fabs(100),".0f"))
Out[102]: 3

len(format(fabs(1e10),".0f"))
Out[165]: 11

len(format(fabs(1235.4576),".0f"))
Out[166]: 4

我做了一个简短的基准测试,10,000 次循环

num     len(str(num))     ----  len(format(fabs(num),".0f")) ---- speed-up
2**1e0  2.179400e-07 sec  ----     8.577000e-07 sec          ---- 0.2541
2**1e1  2.396900e-07 sec  ----     8.668800e-07 sec          ---- 0.2765
2**1e2  9.587700e-07 sec  ----     1.330370e-06 sec          ---- 0.7207
2**1e3  2.321700e-06 sec  ----     1.761305e-05 sec          ---- 0.1318

它更慢但更简单。

但即使这个解决方案也确实给出了来自 9999999999999998 的错误结果

len(format(fabs(9999999999999998),".0f"))
Out[146]: 16
len(format(fabs(9999999999999999),".0f"))
Out[145]: 17

答案 17 :(得分:1)

假设您要求的最大数字可以存储在整数中,则该值取决于实现。我建议你在使用python时不要这么想。在任何情况下,相当大的值可以存储在python'整数'中。请记住,Python使用duck typing!

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

答案 18 :(得分:0)

最重要的答案是说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)

此外,我还没有在数学方法中添加逻辑以返回准确的结果,我只能想象它会进一步放慢速度。

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

答案 19 :(得分:0)

用科学记数法格式化并拔掉指数:

int("{:.5e}".format(1000000).split("e")[1]) + 1

我不知道速度,但这很简单。

请注意小数点后的有效位数(&#34; 5&#34;&#34; .5e&#34;如果将科学记数法的小数部分向上舍入,则可能会出现问题另一个数字。我把它设置得任意大,但可以反映你知道的最大数字的长度。

答案 20 :(得分:0)

我的相同代码如下;我使用了log10方法:

from math import *

def digit_count(number):

if number>1 and round(log10(number))>=log10(number) and number%10!=0 :
    return round(log10(number))
elif  number>1 and round(log10(number))<log10(number) and number%10!=0:
    return round(log10(number))+1
elif number%10==0 and number!=0:
    return int(log10(number)+1)
elif number==1 or number==0:
    return 1

我必须指定1和0的情况,因为log10(1)= 0和log10(0)= ND,因此不满足提到的条件。但是,此代码仅适用于整数。

答案 21 :(得分:0)

如果您必须要求用户提供输入,然后您必须计算有多少个数字,则可以按照以下步骤操作:

count_number = input('Please enter a number\t')

print(len(count_number))

注意:切勿将int作为用户输入。

答案 22 :(得分:0)

def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count

答案 23 :(得分:0)

计算不将整数转换为字符串的位数:

x=123
x=abs(x)
i = 0
while x >= 10**i:
    i +=1
# i is the number of digits

答案 24 :(得分:-1)

coin_digit = str(coin_fark).split(".")[1]
coin_digit_len = len(coin_digit)
print(coin_digit_len)

答案 25 :(得分:-11)

>>> a=12345
>>> a.__str__().__len__()
5