```
在Python中,如何找到一个整数的数字个数?
```str(133)
,然后像len(str(123))
那样找到它的长度。Math.log10
方法仅需7.486343383789062e-05秒,大约快了1501388倍! - FadedCoderMath.log10
替代。 - Peymanabs()
函数来去除负号。例如:len(str(abs(-123))) == 3
。 - Neil不需要转换为字符串
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
99999999999999999999999999999999999999999999999999999999999999999999999
(71个数字9),int(math.log10(x)) +1
返回 72 吗? 我以为我可以依赖log10方法,但实际上我必须使用len(str(x))
代替 :( - Mareckymath.log10(999999999999999)
等于14.999999999999998
,所以int(math.log10(999999999999999))
变成了14
。但当math.log10(9999999999999999)
等于16.0
。也许使用round
函数是解决此问题的方法。 - jamylak10**12
以下,len(str(n))
是最快的。在此之上,普通的log10始终是最快的,但超过10**15
后,它就不正确了。只有在大约10**100
的时候,我的解决方案(带有10**b
检查的~log10)才能胜过len(str(n))
。总之,**请使用len(str(n))
**! - gengkev当您的数字大于999999999999997时,math.log10速度很快,但会出现问题。这是因为浮点数有太多.9,导致结果四舍五入。
因此,为了获得最佳性能,请对较小的数字使用math.log
,并仅在超出math.log
处理范围时使用len(str())
:
def getIntegerPlaces(theNumber):
if theNumber <= 999999999999997:
return int(math.log10(theNumber)) + 1
else:
return len(str(theNumber))
2 ** 3456789
),len(str(number))
大约需要12秒钟。
我忘记了这个后台任务好几分钟,但它还是没有完成。 - itsTyrion这个问题被提出已经几年了,但是我编制了一个基准测试,比较了几种计算整数长度的方法。
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_size
(len("%i" % i)
)是最快的,略快于使用str(i)
,而其他方法则慢得多。
libc = ctyle.CDLL('libc.so.6', use_errno=True)
(猜测是这个)。而且对于大于sys.maxsize
的数字不起作用,因为浮点数不能是“非常大”的。所以任何超过这个范围的数字,我想你只能使用较慢的方法了。 - Torxedlen("%i" % i)
翻译成 C++ 吗?我想在 C++ 中测试它。 - Tom TomPython 2.*
中的int
类型占用4或8个字节(32或64位),具体取决于你使用的Python版本。通过sys.maxint
(对于32位整数是2**31-1
,对于64位整数是2**63-1
),你可以确定使用的是哪一种。
在Python 3中,int
类型(类似于Python 2中的long
)可以占用任意大小的内存空间,只受可用内存的限制;sys.getsizeof
可以给出任何给定值所占用的大致内存大小,但它也会计算一些固定开销:
>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28
如果,正如其他答案所建议的,你想要某个整数值的字符串表示形式,那么只需取该表示形式的len
值,无论是十进制还是其他进制!
假设数字为n
,则n
的位数由以下公式给出:
math.floor(math.log10(n))+1
请注意,这将为小于10e15的正整数提供正确的答案。超出该范围,math.log10
返回类型的精度限制会生效,答案可能会偏离1。在此之后,我建议使用len(str(n))
;这需要O(log(n))
时间,与迭代10的幂相同。assert list(range(1,51)) == [math.floor(math.log10(n))+1 for n in (10**e for e in range(50))]
即可。 - BiGYaN15.0
>>> math.floor(math.log10(999999999999998))+1
16.0```
请查看我的答案https://dev59.com/UHI95IYBdhLWcg3wtwRe#42736085。
- PADYMKO好的,如果不转换为字符串,我会这样做:
def lenDigits(x):
"""
Assumes int(x)
"""
x = abs(x)
if x < 10:
return 1
return 1 + lenDigits(x / 10)
极简递归胜利
在不将整数转换为字符串的情况下计算数字的数量:
x=123
x=abs(x)
i = 0
while x >= 10**i:
i +=1
# i is the number of digits
如用户@Calvintwr所述,函数math.log10
在范围外的数字[-999999999999997, 999999999999997]中存在浮点数误差问题。我在JavaScript(Google V8和NodeJS)和C(GNU GCC编译器)中遇到了这个问题,因此“纯数学”解决方案在这里是不可能的。
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下测试过
这是一个臃肿但快速的版本:
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]