How to find length of digits in an integer?

Question:

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

Asked By: Strigoides

||

Answers:

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

Answered By: GeekTantra

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!

Answered By: batbrat

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
Answered By: John La Rooy

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!

Answered By: Alex Martelli
>>> a=12345
>>> a.__str__().__len__()
5
Answered By: ghostdog74
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
def length(i):
  return len(str(i))
Answered By: user467871

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.

Answered By: BiGYaN

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)

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))
Answered By: Calvintwr

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

Answered By: odradek

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.

Answered By: Frogboxe

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

Answered By: PADYMKO

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.

Answered By: user7969724

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
Answered By: datanew

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.

Answered By: NoOneIsHere
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count
Answered By: Del_sama

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

print(len(count_number))

Note: Never take an int as user input.

Answered By: Sagar Biswas
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
Answered By: user8886245

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.

Answered By: Devvrat Chaubal

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…

Answered By: Captain'Flam

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.

Answered By: cranberrysauce
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

Answered By: Khaled

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
Answered By: san1512

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
coin_digit = str(coin_fark).split(".")[1]
coin_digit_len = len(coin_digit)
print(coin_digit_len)
Answered By: alpc

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

Answered By: jodag

Solution without imports and functions like str()

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

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
Answered By: Damn Ryder

you can use it like this,

n = -123.123
digits = len(str(abs(int(n))))
print(digits)

digitswithdecimals = len(str(abs(n)))-1
print(digitswithdecimals)

OUTPUT:

3

6

Explanation :

int(n) – strips any decimal number from the number

::: -123.123 >> -123

<. . . . . . . . . . . . . #to include decimal points we will remove this part and subtracts by 1 to get exclude the point ‘.’ >

abs(int(n)) – strips negative from the previous result ,if any

::: -123 >> 123

str(abs(int(n))) – convert the previous result to string

::: 123 >> ‘123’

len(str(abs(int(n)))) – return the length of the string

::: length(‘123’) = 3

Answered By: Jihad Ali Hashim

You can use this solution:

n = input("Enter number: ")
print(len(n))
n = int(n)
Answered By: elnaz nasiri

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.

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.