Python中整数的长度

问题描述 投票:179回答:16

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

python count integer
16个回答
246
投票

如果你想要一个整数的长度和整数中的位数一样,你总是可以将它转换为像str(133)这样的字符串,并找到它的长度,如len(str(123))


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

1
投票

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

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


1
投票
def length(i):
  return len(str(i))

1
投票

可以使用以下命令快速完成整数:

len(str(abs(1234567890)))

其中获取绝对值“1234567890”的字符串长度

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

如果您希望它适用于浮动,您可以使用以下任一方法:

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

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

备查。


1
投票

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

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

0
投票

用科学记数法格式化并删除指数:

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

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

请注意小数点后的有效位数(“。5e”中的“5”如果将科学记数法的小数部分向上舍入为另一位数,则可能是一个问题。我将其设置为任意大,但可以反映出你知道的最大数量的长度。


-11
投票
>>> a=12345
>>> a.__str__().__len__()
5

202
投票

没有转换为字符串

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

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

21
投票

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

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

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

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


13
投票

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

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

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

极简主义递归FTW


13
投票

让数字为n然后n中的位数由下式给出:

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

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

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


6
投票

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

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)稍快,并且明显快于其他。


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测试的所有代码示例


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)
© www.soinside.com 2019 - 2024. All rights reserved.