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