如何找到整数的数字长度?

2025-02-05 13:23:00
admin
原创
65
摘要:问题描述:在 Python 中,如何找到整数的位数?解决方案 1:如果您想要整数的长度(即整数中的位数),您可以随时将其转换为字符串str(133)并找到其长度len(str(123))。解决方案 2:无需转换为字符串import math digits = int(math.log10(n))+1 处理零和...

问题描述:

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


解决方案 1:

如果您想要整数的长度(即整数中的位数),您可以随时将其转换为字符串str(133)并找到其长度len(str(123))

解决方案 2:

无需转换为字符串

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

解决方案 3:

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

math.log10 速度很快,但是当您的数字大于 999999999999997 时会出现问题。这是因为浮点数有太多 .9,导致结果向上舍入。

因此,为了获得最佳性能,请使用math.log较小的数字,并且仅len(str())超出可以处理的范围math.log

def getIntegerPlaces(theNumber):
    if theNumber <= 999999999999997:
        return int(math.log10(theNumber)) + 1
    else:
        return len(str(theNumber))

解决方案 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 - 100000以下是至的结果sys.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:

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

在 Python 3 中,ints(与longPython 2 中的 s 类似)可以采用任意大小,直至达到可用内存量;sys.getsizeof它可以为任何给定值提供良好的指示,尽管它也计算一些固定的开销:

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

如果像其他答案所暗示的那样,您正在考虑整数值的某些字符串表示形式,那么只需采用len该表示形式,无论它是以 10 为基数还是其他!

解决方案 6:

设数字为n,则数字的个数n由下式给出:

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

请注意,这将为 +ve 个小于 10e15 的整数提供正确答案。超过该范围,返回类型的精度限制math.log10就会生效,答​​案可能会偏离 1。我只会使用len(str(n))超出该范围的值;这需要的O(log(n))时间与迭代 10 的幂相同。

感谢@SetiVolkylany 提醒我注意这个限制。令人惊讶的是,看似正确的解决方案在实施细节上却有警告。

解决方案 7:

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

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

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

极简递归 FTW

解决方案 8:

正如亲爱的用户 @Calvintwr 所说,该函数math.log10在处理超出范围 [-9999999999999997, 999999999999997] 的数字时出现问题,导致出现浮点错误。我在使用 JavaScript(Google V8 和 NodeJS)和 C(GNU GCC 编译器)时都遇到了这个问题,因此'purely mathematically'这里无法找到解决方案。


根据这个要点和答案,亲爱的用户@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 测试

解决方案 9:

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

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

解决方案 10:

如其他答案所示,使用log10会导致较大的结果不正确,n而使用len(str(...))或手动循环会导致较大的性能降低n。Jodag 的答案提供了一个非常好的替代方案,它只对可能导致计算机崩溃的整数失败,但我们可以通过完全避免对数并使用二进制来做得更好甚至更快(对于n足够小的math.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()

与对数不同,对于整数来说,这既快速又精确。事实证明,这恰好得到floor(log2(n)) + 1。为了得到floor(log2(n))本身,我们减去1,因此n.bit_length() - 1

接下来,我们乘以0.30102999566398114。这相当于log10(2)略微向下舍入。这利用对数规则来计算 的估计floor(log10(n))floor(log2(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。但是,这种大小的整数可能会使您的计算机崩溃,因此这应该足够了。

解决方案 11:

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

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%,比版本快 5% len( str())。好吧……如果你不疯狂使用它,它就没那么有吸引力了。

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

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

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

解决方案 12:

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

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)

解决方案 13:

floor(log10(n))一种使用基于“计算整数 n 和 b 的 log(n,b) 下限的更好方法? ”的自校正实现的快速解决方案。

import math

def floor_log(n, b):
    res = math.floor(math.log(n, b))
    c = b**res
    return res + (b*c <= n) - (c > n)

def num_digits(n):
    return 1 if n == 0 else 1 + floor_log(abs(n), 10)

这非常快并且可以随时工作n < 10**(2**52)(这真的非常大)。

解决方案 14:

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

解决方案 15:

假设您要求整数中可以存储的最大数字,则该值取决于实现。我建议您在使用 Python 时不要这样想。无论如何,Python“整数”中可以存储相当大的值。请记住,Python 使用鸭子类型!

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

解决方案 16:

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

解决方案 17:

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

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

备查。

解决方案 18:

采用科学计数法格式化并去掉指数:

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

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

请注意小数点后的有效数字的数量(“.5e”中的“5”可能会成为问题,如果它将科学计数法的小数部分四舍五入为另一位数字的话)。我把它设置得任意大,但可以反映您所知道的最大数字的长度。

解决方案 19:

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

解决方案 20:

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

解决方案 21:

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

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

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

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

解决方案 22:

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

from math import *

def digit_count(数字):

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,因此不满足上述条件。但是,此代码仅适用于整数。

解决方案 23:

最佳答案都说 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)

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

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

解决方案 24:

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

输出:数字的位数为:16

解决方案 25:

如果您正在寻找不使用内置函数的解决方案。唯一需要注意的是当您发送时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

解决方案 26:

这是最简单的方法,无需将 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

解决方案 27:

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

count_number = input('Please enter a number    ')

print(len(count_number))

注意:永远不要将 int 作为用户输入。

解决方案 28:

无需导入和 str() 等函数的解决方案

def numlen(num):
    result = 1
    divider = 10
    while num % divider != num:
        divider *= 10
        result += 1
    return result

解决方案 29:

你可以使用这个解决方案:

n = input("Enter number: ")
print(len(n))
n = int(n)

解决方案 30:

def NoOfDigit(num):
 noOfDigit = 0
 while num>0:        #eventually zero after continuous integer division
  num = num//10      #integer Division, Eg. 123//10 will give 12
  noOfDigit += 1     #this is our number of digit
 return noOfDigit

让我们看几个例子:

示例 1,对于这种情况,它可以正常工作

num = 12345553
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')

示例 2,负整数需要变为正数才能使此函数起作用

num = -1234 #in case of negative number you need to make it absoulte value
print (f'Number of Digits in {num} is: {NoOfDigit(abs(num))}')

示例 3,函数无法理解整数前的零,因此在输入函数之前需要注意

num = 012345553 #this will not be a valid integer for this code
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用