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


当前回答

所有的数学。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))

其他回答

设数字为n,则n中的位数为:

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

注意,这将为+ve个整数< 10e15给出正确答案。除此之外,返回类型的数学的精度限制。Log10开始起作用,结果可能相差1。我可以简单地在后面用len(str(n));这需要O(log(n))时间,相当于10的幂次迭代。

感谢@SetiVolkylany让我注意到这个限制。令人惊讶的是,看似正确的解决方案在实现细节中有警告。

正如其他答案所示,使用log10会导致大n的错误结果,而使用len(str(…))或手动循环会导致大n的性能变慢。Jodag的答案提供了一个非常好的替代方案,它只适用于可能会使您的计算机崩溃的整数,但我们可以做得更好,甚至更快(对于n足够小的数学。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()

与对数不同,这对于整数来说既快速又精确。结果是,这个结果正好是(log2(n)) + 1。为了单独得到地板(log2(n)),我们减去1,因此n.bit_length() - 1。

接下来,我们乘以0.30102999566398114。这相当于log10(2)稍微舍入。这利用了对数规则,以便从地板(log2(n))计算地板(log10(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。然而,这种大小的整数可能会使您的计算机崩溃,所以这应该足够了。

所有的数学。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))
n = 3566002020360505
count = 0
while(n>0):
  count += 1
  n = n //10
print(f"The number of digits in the number are: {count}")

output: number中的位数为:16

如果你必须要求用户输入,然后你必须数出有多少个数字,那么你可以这样做:

count_number = input('Please enter a number\t')

print(len(count_number))

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