Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何找到整数中的数字长度?_Python_Count_Integer - Fatal编程技术网

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

Python 如何找到整数中的数字长度?,python,count,integer,Python,Count,Integer,在Python中,如何查找整数中的位数?如果希望整数的长度与整数中的位数相同,则始终可以将其转换为类似字符串的str(133),并查找其类似长度的len(str(123)) 假设您要求的是可以存储在整数中的最大数字,则该值取决于实现。我建议您在使用python时不要这样想。在任何情况下,相当大的值都可以存储在python的“整数”中。记住,Python使用duck类型 编辑: 在澄清询问者想要数字之前,我给出了答案。因此,我同意接受答案所建议的方法。没有更多的补充 不转换为字符串 import

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

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

假设您要求的是可以存储在整数中的最大数字,则该值取决于实现。我建议您在使用python时不要这样想。在任何情况下,相当大的值都可以存储在python的“整数”中。记住,Python使用duck类型

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

不转换为字符串

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

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

在Python3中,
int
s(就像Python2中的
long
s)可以使用任意大小的可用内存
sys.getsizeof
为任何给定值提供了一个良好的指示,尽管它也计算了一些固定开销:

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

如其他答案所示,如果您正在考虑整数值的字符串表示形式,那么只需取该表示形式的
len
,以10为基数或其他形式

将数字设为
n
,则
n
中的位数如下所示:

>>> a=12345
>>> a.__str__().__len__()
5
math.floor(math.log10(n))+1
请注意,这将为+ve整数<10e15给出正确答案。除此之外,返回类型的
math.log10
的精度限制开始生效,答案可能会被1关闭。除此之外,我只需使用
len(str(n))
;这需要
O(log(n))
时间,这与迭代10的幂相同


感谢@SetiVolkylany将我的注意力带到了这个极限。令人惊讶的是,看似正确的解决方案在实施细节上有很多警告。

对于子孙后代来说,这无疑是解决这个问题最慢的解决方案:

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)
所有math.log10解决方案都会给你带来问题。 math.log10速度很快,但当您的数字大于999999999997时会出现问题。这是因为浮点有太多的.9,导致结果向上取整

解决方案是对高于该阈值的数字使用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
def getIntegerPlaces(编号):
如果编号=10**计数器:
计数器+=1
返回计数器

好吧,如果不转换为字符串,我将执行以下操作:

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

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)
def lenDigits(x):
"""
假设int(x)
"""
x=绝对值(x)
如果x<10:
返回1
返回1+伦迪吉特(x/10)

最小递归FTW

可以使用以下方法快速对整数执行此操作:

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

作为将来的参考。

如亲爱的用户@Calvintwr所述,函数
math.log10
在[-999999999997,999999999997]范围之外的数字中存在问题,我们在该范围内得到浮点错误。我在JavaScript(googlev8和NodeJS)和C(gnugcc编译器)上遇到了这个问题,因此这里不可能有一个纯数学的解决方案


基于此和亲爱的用户@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


使用Python 3.5以科学记数法测试的所有代码示例,并提取指数:

int("{:.5e}".format(1000000).split("e")[1]) + 1
我不知道速度,但很简单


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

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

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

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

def libc_大小(i):
返回libc.snprintf(buf,100,c_char_p(b'%i'),i)#相当于'return snprintf(buf,100,'%i',i')`
def str_尺寸(i):
返回len(str(i))#作为字符串的'i'长度
def数学_尺寸(i):
返回1+math.floor(math.log10(i))#1+log10/i的floor
def exp_尺寸(i):
返回int(“{.5e}”.format(i).split(“e”)[1])+1#例如'1e10`->'10`+1->11
def模块尺寸(i):
返回len(“%i”%i)#使用字符串模而不是str(i)
def fmt_尺寸(i):
返回len({0}).format(i))#与上面相同,但str.format
(libc函数需要一些设置,我没有包括)

size\u exp
要感谢布莱恩·普雷斯洛普斯基,
size\u str
要感谢吉克坦特拉,
size\u math
要感谢约翰·拉鲁伊

结果如下:

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到1000000上运行)

以下是
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_size
len(“%i”%i)
)是最快的,略快于使用
str(i)
,并且明显快于其他方法
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count
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)
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)
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count
count_number = input('Please enter a number\t')

print(len(count_number))
from math import *
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
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
n = [ int( (i+1)**( 17/7. )) for i in xrange( 1000000 )] + [0,10**16-1,10**16,10**16+1]
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)
n = 3566002020360505
count = 0
while(n>0):
  count += 1
  n = n //10
print(f"The number of digits in the number are: {count}")
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
coin_digit = str(coin_fark).split(".")[1]
coin_digit_len = len(coin_digit)
print(coin_digit_len)