I am doing a puzzle where I have to deal with numbers of order 10^18. However, I find python isn't able to handle very large numbers in all areas.
To be specific, if we assign a = 1000000000000000000 (10^18) and do basic arithmetic calculations (+, -, /, *), its responding. However, its showing OverflowError when I use it in range()
>>> a = 1000000000000000000
>>> a/2
500000000000000000L
>>> a*2
2000000000000000000L
>>> a+a
2000000000000000000L
>>> a*a
1000000000000000000000000000000000000L
>>> range(a)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
range(a)
OverflowError: range() result has too many items
>>> xrange(a)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
xrange(a)
OverflowError: Python int too large to convert to C long
I used Python 2.7.
I would like to do it in python 2.7 using inbuild functions. Isn't that possible?
In Python 2.x, range
and xrange
are limited to working with C long
and your large integers are just too big for that. This limitation is simply due to the implementation choices made for range
and xrange
.
In Python 3.x the limitation has been removed and you can perform range()
with very large integers.
>>> range(2**128)
range(0, 340282366920938463463374607431768211456)
The official list of changes for Python 3 has this to say:
range()
now behaves likexrange()
used to behave, except it works with values of arbitrary size. The latter no longer exists.
In Python 2.x the range()
function returned a list. Clearly there's no hope of allocating memory for all the elements for very large ranges. The xrange()
function returns an xrange
object. The documentation describes it as "an opaque sequence type which yields the same values as the corresponding list, without actually storing them all simultaneously". The documentation goes on to say this:
xrange()
is intended to be simple and fast. Implementations may impose restrictions to achieve this. The C implementation of Python restricts all arguments to native C longs (“short” Python integers), and also requires that the number of elements fit in a native C long.
This explains the limitations in Python 2.x.
I'm not quite sure what you can usefully do with the new Python 3 support for very large ranges. For example, I would not recommend you try this:
2**128 in range(2**128)
That will run for a long time.
You indicate in the comments that you are writing code to count up to a large number. You can do this trivially in Python with code like this:
i = 0
while i<N:
doSomething(i)
i += 1
But you will discover that if N
is a large number then this will take a very long time. There's not any getting around that for values of N
of the order 218 as per your question.