如何求一个整数的数字长度?

发布于 2024-08-19 22:25:23 字数 26 浏览 2 评论 0原文

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

In Python, how do you find the number of digits in an integer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

小伙你站住 2024-08-26 22:25:24

自从提出这个问题以来已经有好几年了,但我已经编制了几种计算整数长度的方法的基准。

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 - 100000sys.maxsize< 的结果/code>:

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) 稍快一些 并且比其他人快得多。

It's been several years since this question was asked, but I have compiled a benchmark of several methods to calculate the length of an integer.

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

(the libc function requires some setup, which I haven't included)

size_exp is thanks to Brian Preslopsky, size_str is thanks to GeekTantra, and size_math is thanks to John La Rooy

Here are the results:

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)

(Disclaimer: the function is run on inputs 1 to 1,000,000)

Here are the results for 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)

As you can see, mod_size (len("%i" % i)) is the fastest, slightly faster than using str(i) and significantly faster than others.

浅笑依然 2024-08-26 22:25:24

Python 2.* int 占用 4 或 8 个字节(32 或 64 位),具体取决于您的 Python 版本。 sys.maxint2**31-1 对于 32 位整数,2**63-1 对于 64 位整数)将告诉你这两种可能性中的哪一种。

在 Python 3 中,int(如 Python 2 中的long)可以采用任意大小,最高可达可用内存量; sys.getsizeof 为您提供了任何给定值的良好指示,尽管它确实也计算了一些固定开销:

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

如果,如其他答案所示,您正在考虑某个字符串整数值的表示形式,然后只需取该表示形式的 len 即可,无论是以 10 为基数还是以其他方式!

Python 2.* ints take either 4 or 8 bytes (32 or 64 bits), depending on your Python build. sys.maxint (2**31-1 for 32-bit ints, 2**63-1 for 64-bit ints) will tell you which of the two possibilities obtains.

In Python 3, ints (like longs in Python 2) can take arbitrary sizes up to the amount of available memory; sys.getsizeof gives you a good indication for any given value, although it does also count some fixed overhead:

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

If, as other answers suggests, you're thinking about some string representation of the integer value, then just take the len of that representation, be it in base 10 or otherwise!

等待我真够勒 2024-08-26 22:25:24

令数字为n,则n 中的位数由下式给出:

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

请注意,这将为+ve 整数给出正确答案。 10e15。除此之外,math.log10 返回类型的精度限制开始生效,答案可能会偏离 1。我会简单地使用 len(str(n))那;这需要 O(log(n)) 时间,与迭代 10 的幂相同。

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

Let the number be n then the number of digits in n is given by:

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

Note that this will give correct answers for +ve integers < 10e15. Beyond that the precision limits of the return type of math.log10 kicks in and the answer may be off by 1. I would simply use len(str(n)) beyond that; this requires O(log(n)) time which is same as iterating over powers of 10.

Thanks to @SetiVolkylany for bringing my attenstion to this limitation. Its amazing how seemingly correct solutions have caveats in implementation details.

坏尐絯 2024-08-26 22:25:24

好吧,如果不转换为字符串,我会做类似的事情:

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

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

Minimalist recursion FTW

Well, without converting to string I would do something like:

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

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

Minimalist recursion FTW

残花月 2024-08-26 22:25:24

正如亲爱的用户 @Calvintwr 所提到的,函数 math.log10 在数字超出范围 [-999999999999997, 999999999999997] 时出现问题,我们会遇到浮点错误。我在 JavaScript(Google V8 和 NodeJS)和 C(GNU GCC 编译器)中遇到了这个问题,因此这里不可能使用“纯数学”解决方案。


基于此要点回答亲爱的用户@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

我在长度最大为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 进行测试

As mentioned the dear user @Calvintwr, the function math.log10 has problem in a number outside of a range [-999999999999997, 999999999999997], where we get floating point errors. I had this problem with the JavaScript (the Google V8 and the NodeJS) and the C (the GNU GCC compiler), so a 'purely mathematically' solution is impossible here.


Based on this gist and the answer the dear user @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

I tested it on numbers with length up to 20 (inclusive) and all right. It must be enough, because the length max integer number on a 64-bit system is 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

All example of codes tested with the Python 3.5

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

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

Count the number of digits w/o convert integer to a string:

x=123
x=abs(x)
i = 0
while x >= 10**i:
    i +=1
# i is the number of digits
在巴黎塔顶看东京樱花 2024-08-26 22:25:24

这是一个庞大但快速的版本:

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]

注意:它不管理负数,但适应很容易......

Here is a bulky but fast version :

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

Only 5 comparisons for not too big numbers.
On my computer it is about 30% faster than the math.log10 version and 5% faster than the len( str()) one.
Ok... no so attractive if you don't use it furiously.

And here is the set of numbers I used to test/measure my function:

n = [ int( (i+1)**( 17/7. )) for i in xrange( 1000000 )] + [0,10**16-1,10**16,10**16+1]

NB: it does not manage negative numbers, but the adaptation is easy...

时间海 2024-08-26 22:25:24

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

与对数不同,这对于整数来说既快速又精确。事实证明,这恰好产生 floor(log2(n)) + 1。为了获得 floor(log2(n)) 本身,我们减去 1,因此得到 n.bit_length() - 1

接下来,我们乘以 0.30102999566398114。这相当于稍微向下舍入的 log10(2)。这利用对数规则来根据 floor(log2(n)) 计算 floor(log10(n)) 的估计值。

现在,您可能想知道此时我们的情况如何,因为虽然 0.30102999566398114 * log2(n) ~ log10(n),但 floor(0.30102999566398114 * Floor 则不然) (log2(n))) ~ 楼层(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,当结果太小或 < code>0 + 时结果正好。

与 Jodag 的答案类似,这种方法实际上对于非常非常大的 n 失败,大约在 10 ** 2 ** 52 处,其中 i 关闭超过-1。但是,该大小的整数可能会使您的计算机崩溃,因此这应该足够了。

As shown by other answers, using log10 leads to incorrect results for large n while using len(str(...)) or manual looping leads to slow performance for large n. Jodag's answer provides a really good alternative which only fails for integers that will likely crash your computer, but we can do a bit better and even faster (for n small enough that math.log2 is guaranteed to be accurate) by avoid logarithms altogether and using binary instead:

def num_digits(n: int) -> int:
    assert n > 0
    i = int(0.30102999566398114 * (n.bit_length() - 1)) + 1
    return (10 ** i <= n) + i

Let's break this down. First, there's the weird n.bit_length(). This calculates the length in binary:

assert 4 == (0b1111).bit_length()
assert 8 == (0b1011_1000).bit_length()
assert 9 == (0b1_1011_1000).bit_length()

Unlike logarithms, this is both fast and precise for integers. As it turns out, this results in exactly floor(log2(n)) + 1. In order to get the floor(log2(n)) on its own, we subtract 1, hence the n.bit_length() - 1.

Next, we multiply by 0.30102999566398114. This is equivalent to log10(2) slightly rounded down. This takes advantage of logarithmic rules in order to calculate an estimate of floor(log10(n)) from floor(log2(n)).

Now, you might be wondering how off we might be at this point, because although 0.30102999566398114 * log2(n) ~ log10(n), the same is not true for floor(0.30102999566398114 * floor(log2(n))) ~ floor(log10(n)). Recall that x - 1 < floor(x) <= x so that we can do some quick math:

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))

Note then that floor(log10(n) - 0.30102999566398114) is at least floor(log10(n)) - 1, meaning we are at most 1 off from our result. This is where the final correction comes in, where we check 10 ** i <= n, which results in an extra 1 + when the result is too small or 0 + when the result is just right.

Similar to Jodag's answer, this approach actually fails for very very large n, somewhere around 10 ** 2 ** 52 where i is off by more than -1. However, integers of that size will likely crash your computer, so this should suffice.

北座城市 2024-08-26 22:25:24

对于后人来说,毫无疑问是迄今为止解决这个问题最慢的方法:

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)

For posterity, no doubt by far the slowest solution to this problem:

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)
眼角的笑意。 2024-08-26 22:25:24

一种快速解决方案,基于“更好的方法”使用 floor(log10(n)) 的自我纠正实现计算整数 n 和 b 的 log(n,b) 下限?”。

import math

def floor_log(n, b):
    res = math.floor(math.log(n, b))
    c = b**res
    return res + (b*c <= n) - (c > n)

def num_digits(n):
    return 1 if n == 0 else 1 + floor_log(abs(n), 10)

这非常快,并且只要 n n n n n n n n n n n 10**(2**52)(这真的很大)。

A fast solution that uses a self-correcting implementation of floor(log10(n)) based on "Better way to compute floor of log(n,b) for integers n and b?".

import math

def floor_log(n, b):
    res = math.floor(math.log(n, b))
    c = b**res
    return res + (b*c <= n) - (c > n)

def num_digits(n):
    return 1 if n == 0 else 1 + floor_log(abs(n), 10)

This is quite fast and will work whenever n < 10**(2**52) (which is really really big).

月下凄凉 2024-08-26 22:25:24
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
冷情妓 2024-08-26 22:25:24

假设您要求以整数形式存储的最大数字,则该值取决于实现。我建议大家在使用python的时候不要这样想。无论如何,Python 的“整数”中可以存储相当大的值。请记住,Python 使用鸭子类型!

编辑:
我在澄清提问者想要位数之前就给出了答案。为此,我同意已接受答案建议的方法。没什么可补充的了!

Assuming you are asking for the largest number you can store in an integer, the value is implementation dependent. I suggest that you don't think in that way when using python. In any case, quite a large value can be stored in a python 'integer'. Remember, Python uses duck typing!

Edit:
I gave my answer before the clarification that the asker wanted the number of digits. For that, I agree with the method suggested by the accepted answer. Nothing more to add!

守望孤独 2024-08-26 22:25:24
def length(i):
  return len(str(i))
def length(i):
  return len(str(i))
鹿港小镇 2024-08-26 22:25:24

对于整数,可以使用以下方法快速完成:

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

供将来参考。

It can be done for integers quickly by using:

len(str(abs(1234567890)))

Which gets the length of the string of the absolute value of "1234567890"

abs returns the number WITHOUT any negatives (only the magnitude of the number), str casts/converts it to a string and len returns the string length of that string.

If you want it to work for floats, you can use either of the following:

# Ignore all after decimal place
len(str(abs(0.1234567890)).split(".")[0])

# Ignore just the decimal place
len(str(abs(0.1234567890)))-1

For future reference.

战皆罪 2024-08-26 22:25:24

用科学记数法格式化并去掉指数:

int("{:.5e}".format(1000000).split("e")[1]) + 1

我不知道速度,但很简单。

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

Format in scientific notation and pluck off the exponent:

int("{:.5e}".format(1000000).split("e")[1]) + 1

I don't know about speed, but it's simple.

Please note the number of significant digits after the decimal (the "5" in the ".5e" can be an issue if it rounds up the decimal part of the scientific notation to another digit. I set it arbitrarily large, but could reflect the length of the largest number you know about.

隔纱相望 2024-08-26 22:25:24
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count
暗恋未遂 2024-08-26 22:25:24
def digits(n)
    count = 0
    if n == 0:
        return 1
    
    if n < 0:
        n *= -1

    while (n >= 10**count):
        count += 1
        n += n%10

    return count

print(digits(25))   # Should print 2
print(digits(144))  # Should print 3
print(digits(1000)) # Should print 4
print(digits(0))    # Should print 1
def digits(n)
    count = 0
    if n == 0:
        return 1
    
    if n < 0:
        n *= -1

    while (n >= 10**count):
        count += 1
        n += n%10

    return count

print(digits(25))   # Should print 2
print(digits(144))  # Should print 3
print(digits(1000)) # Should print 4
print(digits(0))    # Should print 1
泪是无色的血 2024-08-26 22:25:24

这是另一种计算任何数字小数点前位数的方法,

from math import fabs

len(format(fabs(100),".0f"))
Out[102]: 3

len(format(fabs(1e10),".0f"))
Out[165]: 11

len(format(fabs(1235.4576),".0f"))
Out[166]: 4

我做了一个简短的基准测试,针对 10,000 个循环,

num     len(str(num))     ----  len(format(fabs(num),".0f")) ---- speed-up
2**1e0  2.179400e-07 sec  ----     8.577000e-07 sec          ---- 0.2541
2**1e1  2.396900e-07 sec  ----     8.668800e-07 sec          ---- 0.2765
2**1e2  9.587700e-07 sec  ----     1.330370e-06 sec          ---- 0.7207
2**1e3  2.321700e-06 sec  ----     1.761305e-05 sec          ---- 0.1318

它速度较慢,但​​是一个更简单的选择。

但即使这个解决方案确实给出了错误的结果 9999999999999998

len(format(fabs(9999999999999998),".0f"))
Out[146]: 16
len(format(fabs(9999999999999999),".0f"))
Out[145]: 17

Here is another way to compute the number of digit before the decimal of any number

from math import fabs

len(format(fabs(100),".0f"))
Out[102]: 3

len(format(fabs(1e10),".0f"))
Out[165]: 11

len(format(fabs(1235.4576),".0f"))
Out[166]: 4

I did a brief benchmark test, for 10,000 loops

num     len(str(num))     ----  len(format(fabs(num),".0f")) ---- speed-up
2**1e0  2.179400e-07 sec  ----     8.577000e-07 sec          ---- 0.2541
2**1e1  2.396900e-07 sec  ----     8.668800e-07 sec          ---- 0.2765
2**1e2  9.587700e-07 sec  ----     1.330370e-06 sec          ---- 0.7207
2**1e3  2.321700e-06 sec  ----     1.761305e-05 sec          ---- 0.1318

It is slower but a simpler option.

But even this solution does give wrong results from 9999999999999998

len(format(fabs(9999999999999998),".0f"))
Out[146]: 16
len(format(fabs(9999999999999999),".0f"))
Out[145]: 17
皓月长歌 2024-08-26 22:25:24

我的代码如下;我使用了 log10 方法:

from math import *

def digital_count(number):

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 ,因此条件提到的不满意。但是,此代码仅适用于整数。

My code for the same is as follows;i have used the log10 method:

from math import *

def digit_count(number):

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

I had to specify in case of 1 and 0 because log10(1)=0 and log10(0)=ND and hence the condition mentioned isn't satisfied. However, this code works only for whole numbers.

晨光如昨 2024-08-26 22:25:24

最常见的答案是 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)

此外,我还没有在数学方法中添加逻辑来返回准确的结果,我只能想象它会进一步减慢速度。

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

Top answers are saying mathlog10 faster but I got results that suggest len(str(n)) is faster.

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)

Besides, I haven't added logic to the math way to return accurate results and I can only imagine it slows it even more.

I have no idea how the previous answers proved the maths way is faster though.

三月梨花 2024-08-26 22:25:24
n = 3566002020360505
count = 0
while(n>0):
  count += 1
  n = n //10
print(f"The number of digits in the number are: {count}")

输出:数字的位数为:16

n = 3566002020360505
count = 0
while(n>0):
  count += 1
  n = n //10
print(f"The number of digits in the number are: {count}")

output: The number of digits in the number are: 16

爱的故事 2024-08-26 22:25:24

如果您正在寻找不使用内置函数的解决方案。
唯一需要注意的是当您发送 a = 000 时。

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

If you are looking for a solution without using inbuilt functions.
Only caveat is when you send a = 000.

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
明媚殇 2024-08-26 22:25:24

这是最简单的方法,无需将 int 转换为字符串:

假设给出 15 位数字,例如; n=787878899999999;

n=787878899999999 
n=abs(n) // we are finding absolute value because if the number is negative int to string conversion will produce wrong output

count=0 //we have taken a counter variable which will increment itself till the last digit

while(n):
    n=n//10   /*Here we are removing the last digit of a number...it will remove until 0 digits will left...and we know that while(0) is False*/
    count+=1  /*this counter variable simply increase its value by 1 after deleting a digit from the original number
print(count)   /*when the while loop will become False because n=0, we will simply print the value of counter variable

输入:

n=787878899999999

输出:

15

Here is the simplest approach without need to be convert int into the string:

suppose a number of 15 digits is given eg; n=787878899999999;

n=787878899999999 
n=abs(n) // we are finding absolute value because if the number is negative int to string conversion will produce wrong output

count=0 //we have taken a counter variable which will increment itself till the last digit

while(n):
    n=n//10   /*Here we are removing the last digit of a number...it will remove until 0 digits will left...and we know that while(0) is False*/
    count+=1  /*this counter variable simply increase its value by 1 after deleting a digit from the original number
print(count)   /*when the while loop will become False because n=0, we will simply print the value of counter variable

Input :

n=787878899999999

Output:

15
吾性傲以野 2024-08-26 22:25:24

如果您必须要求用户提供输入,然后您必须计算有多少个数字,那么您可以按照以下步骤操作:

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

print(len(count_number))

注意:切勿将 int 作为用户输入。

If you have to ask an user to give input and then you have to count how many numbers are there then you can follow this:

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

print(len(count_number))

Note: Never take an int as user input.

我做我的改变 2024-08-26 22:25:24

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

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

Solution without imports and functions like str()

def numlen(num):
    result = 1
    divider = 10
    while num % divider != num:
        divider *= 10
        result += 1
    return result
梦醒灬来后我 2024-08-26 22:25:24

您可以使用此解决方案:

n = input("Enter number: ")
print(len(n))
n = int(n)

You can use this solution:

n = input("Enter number: ")
print(len(n))
n = int(n)
梓梦 2024-08-26 22:25:24
def NoOfDigit(num):
 noOfDigit = 0
 while num>0:        #eventually zero after continuous integer division
  num = num//10      #integer Division, Eg. 123//10 will give 12
  noOfDigit += 1     #this is our number of digit
 return noOfDigit

让我们看几个例子:

#Example 1,在这种情况下效果很好

num = 12345553
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')

#Example 2,需要将负整数设为正数才能使该函数工作

num = -1234 #in case of negative number you need to make it absoulte value
print (f'Number of Digits in {num} is: {NoOfDigit(abs(num))}')

#Example 3,整数前的零不是函数可以理解,因此在我们输入函数之前需要注意它

num = 012345553 #this will not be a valid integer for this code
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')
def NoOfDigit(num):
 noOfDigit = 0
 while num>0:        #eventually zero after continuous integer division
  num = num//10      #integer Division, Eg. 123//10 will give 12
  noOfDigit += 1     #this is our number of digit
 return noOfDigit

Let's see a few examples:

#Example 1, it will work fine for this case

num = 12345553
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')

#Example 2, negative integer number need to be made positive to this function to work

num = -1234 #in case of negative number you need to make it absoulte value
print (f'Number of Digits in {num} is: {NoOfDigit(abs(num))}')

#Example 3, zero before integer is not understood by the function so it needs to be taken care before we feed into the function

num = 012345553 #this will not be a valid integer for this code
print (f'Number of Digits in {num} is: {NoOfDigit(num)}')
请持续率性 2024-08-26 22:25:23

如果您想要整数的长度作为整数中的位数,您始终可以将其转换为字符串,如 str(133) 并找到其长度,如 len(str(123 ))

If you want the length of an integer as in the number of digits in the integer, you can always convert it to string like str(133) and find its length like len(str(123)).

一紙繁鸢 2024-08-26 22:25:23

无需转换为字符串

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

Without conversion to string

import math
digits = int(math.log10(n))+1

To also handle zero and negative numbers

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 '-' 

You'd probably want to put that in a function :)

Here are some benchmarks. The len(str()) is already behind for even quite small numbers

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
时光与爱终年不遇 2024-08-26 22:25:23

所有 math.log10 解决方案都会给您带来问题。

math.log10 速度很快,但当您的数字大于 999999999999997 时会出现问题。这是因为浮点数有太多 .9,导致结果向上舍入。

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

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

All math.log10 solutions will give you problems.

math.log10 is fast but gives problem when your number is greater than 999999999999997. This is because the float have too many .9s, causing the result to round up.

Therefore, to get the best performance, use math.log for smaller numbers and only len(str()) beyond what math.log can handle:

def getIntegerPlaces(theNumber):
    if theNumber <= 999999999999997:
        return int(math.log10(theNumber)) + 1
    else:
        return len(str(theNumber))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文