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


当前回答

我的代码相同如下,我已经使用了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,因此上面提到的条件不满足。但是,此代码仅适用于整数。

其他回答

这个问题已经问了好几年了,但是我已经编写了一个基准测试,其中包含了几种计算整数长度的方法。

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 to 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)略快,比其他方法快得多。

没有导入和str()这样的函数的解决方案

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

所有的数学。Log10的解会给你带来问题。

数学。Log10速度很快,但当你的数字大于999999999999997时就会出现问题。这是因为浮点数有太多的.9,导致结果四舍五入。

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

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

顶部的答案是说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)

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

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

我的代码相同如下,我已经使用了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,因此上面提到的条件不满足。但是,此代码仅适用于整数。