In Python, how do you find the number of digits in an integer?
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))
.
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
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))
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.
Python 2.*
int
s 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, int
s (like long
s 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!
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.
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
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
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
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)
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...
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
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!
def length(i):
return len(str(i))
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.
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.
def count_digit(number):
if number >= 10:
count = 2
else:
count = 1
while number//10 > 9:
count += 1
number = number//10
return count
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
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
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).
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.
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.
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.
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
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
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
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.
Solution without imports and functions like str()
def numlen(num):
result = 1
divider = 10
while num % divider != num:
divider *= 10
result += 1
return result
You can use this solution:
n = input("Enter number: ")
print(len(n))
n = int(n)
coin_digit = str(coin_fark).split(".")[1]
coin_digit_len = len(coin_digit)
print(coin_digit_len)
精彩评论