In Python, how do you find the number of digits in an integer?
32 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)).
7 Comments
Math.log10 method took only 7.486343383789062e-05 seconds, approximately 1501388 times faster!Math.log10 instead.abs() to remove negative sign. eg. len(str(abs(-123))) == 3Without 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 20 Comments
int(math.log10(x)) +1 for 99999999999999999999999999999999999999999999999999999999999999999999999 (71 nines) returns 72 ? I thought that I could rely on log10 method but I have to use len(str(x)) instead :(math.log10(999999999999999) is equal to 14.999999999999998 so int(math.log10(999999999999999)) becomes 14. But then math.log10(9999999999999999) is equal to 16.0. Maybe using round is a solution to this problem.10**12, len(str(n)) is the fastest. Above that, plain log10 is always the fastest, but above 10**15, it's incorrect. Only at around 10**100 does my solution (~log10 with the 10**b check) begins to beat out len(str(n)). In conclusion, use len(str(n)) !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)) 7 Comments
2**3456789), len(str(number)) took about 12 seconds. I forgot this in the background for minutes and it was still not doneIt'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.
6 Comments
libc = ctyle.CDLL('libc.so.6', use_errno=True) (guessing this is it). And it doesn't work for numbers greater than sys.maxsize because floating point numbers can't be "very large". So any number above that, I guess you're stuck with one of the slower methods.len("%i" % i) to C++. I want test tis in C++.timeit module to measure the "string modulo" approach over 1 000 000 repetitions, it is slower than the floor(log10()) approach or the len(str()) approach.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!
3 Comments
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.
3 Comments
assert list(range(1,51)) == [math.floor(math.log10(n))+1 for n in (10**e for e in range(50))].>>> math.floor(math.log10(999999999999997))+1 15.0 >>> math.floor(math.log10(999999999999998))+1 16.0. Look my answer stackoverflow.com/a/42736085/6003870.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
1 Comment
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
Comments
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 1 Comment
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.
Comments
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...
1 Comment
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).
1 Comment
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!
Comments
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.
3 Comments
int) than to truncate its decimal string representation: len(str(abs(int(0.1234567890)))) returns 1.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.
Comments
def count_digit(number): if number >= 10: count = 2 else: count = 1 while number//10 > 9: count += 1 number = number//10 return count 1 Comment
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 Comments
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.
Comments
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.
Comments
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 1 Comment
a: int is correct, this doesn't work for float. For example, number_length(1.5) returns 1.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 Comments
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.
1 Comment
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)}')
len(str(n)), in newer versions of Python this will break for integers with over 4300 digits because converting the full binary into base 10 is very slow and had posed DOS risks. If you need to find the number of digits in a very large integer, use the more mathematical solutions instead.