23

I'm new to Python, I was reading this page where I saw a weird statement:

if n+1 == n:  # catch a value like 1e300
    raise OverflowError("n too large")

x equals to a number greater than it?! I sense a disturbance in the Force.

I know that in Python 3, integers don't have fixed byte length. Thus, there's no integer overflow, like how C's int works. But of course the memory can't store infinite data.

I think that's why the result of n+1 can be the same as n: Python can't allocate more memory to preform the summation, so it is skipped, and n == n is true. Is that correct?

If so, this could lead to incorrect result of the program. Why don't Python raise an error when operations are not possible, just like C++'s std::bad_alloc?

Even if n is not too large and the check evaluates to false, result - due to the multiplication - would need much more bytes. Could result *= factor fail for the same reason?

I found it in the offical Python documentation. Is it really the correct way to check big integers / possible integer "overflow"?

klenium
  • 2,468
  • 2
  • 24
  • 47
  • 1
    n == n is true. I assume you mean n == (n+1) – E.Serra Sep 03 '18 at 14:26
  • 1
    That code doesn't actually catch large `int`s like 1e300. The int would have to be seriously huge for that to happen due to memory reasons. It does catch floats though, for the obvious reason. n must be a float. – Denziloe Sep 03 '18 at 14:26
  • @E.Serra No, I don't. I meant if the summation in `n (+1)` is skipped, it may see and work with only `(n) (==) (n)`. – klenium Sep 03 '18 at 14:34
  • @Denziloe Indeed, my bad. We often use 'e' for integers too in math, but in Python we may use the `**` operator to get large integers. – klenium Sep 03 '18 at 14:36
  • 1
    Well, this function in the docs catches `1e16`, but accepts `10 ** 5000000` which is bad I think, because `1e16 < 10 ** 50` so that check is only for float inputs (there is no implicit conversion). – klenium Sep 03 '18 at 15:16

3 Answers3

42

Python3

Only floats have a hard limit in python. Integers are implemented as “long” integer objects of arbitrary size in python3 and do not normally overflow.

You can test that behavior with the following code

import sys

i = sys.maxsize
print(i)
# 9223372036854775807
print(i == i + 1)
# False
i += 1
print(i)
# 9223372036854775808

f = sys.float_info.max
print(f)
# 1.7976931348623157e+308
print(f == f + 1)
# True
f += 1
print(f)
# 1.7976931348623157e+308

You may also want to take a look at sys.float_info and sys.maxsize

Python2

In python2 integers are automatically casted to long integers if too large as described in the documentation for numeric types

import sys

i = sys.maxsize
print type(i)
# <type 'int'>

i += 1
print type(i)
# <type 'long'>

Could result *= factor fail for the same reason?

Why not try it?

import sys

i = 2
i *= sys.float_info.max
print i
# inf

Python has a special float value for infinity (and negative infinity too) as described in the docs for float

kalehmann
  • 4,821
  • 6
  • 26
  • 36
  • I accepted your answer because it gives a reverence to `MemoryError` (I didn't know about it) which is raised if I'd try to work with too big integers. – klenium Sep 03 '18 at 15:21
  • Btw my 3rd question is for big integers, not small (in bits) floats. Working with a number with more than 100k digits is not something I want to try out. :) It's enough to know how it would work in theory. – klenium Sep 03 '18 at 15:41
8

Integers don't work that way in Python.

But float does. That is also why the comment says 1e300, which is a float in scientific notation.

harold
  • 61,398
  • 6
  • 86
  • 164
8

I had a problem of with integer overlflows in python3, but when I inspected the types, I understood the reason:

import numpy as np

a = np.array([3095693933], dtype=int)
s = np.sum(a)
print(s)
# 3095693933
s * s
# -8863423146896543127
print(type(s))
# numpy.int64
py_s = int(s)
py_s * py_s
# 9583320926813008489

Some pandas and numpy functions, such as sum on arrays or Series return an np.int64 so this might be the reason you are seeing int overflows in Python3.

The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156