2

When I execute the below on Ipython:

test = np.array([1,2,3,4])
test**50

it returns:

array([          1, -2147483648, -2147483648, -2147483648])

which has both the wrong value and sign. Any clues why I might be getting this?

3
  • 4
    Numpy integer numbers have limited range. When you get a very large number (e.g., 2**50), it "wraps around" and becomes negative. This phenomenon is called overflow. Unlike Numpy, Python itself does not have this limitation: 4**50 is 1267650600228229401496703205376. Commented Jan 17, 2017 at 6:43
  • 1
    @DYZ ... to be more precise the Numpy types are, as you say, constrained for efficiency (and many are signed types, as you say). But Python's native integer objects will be automatically promoted into large integer objects to prevent overflow. Specifically the np.array() constructor will set the dtype to the minimal sized type which can handle the initial values provided. You can used a keyword argument (option) dtype= to over-ride this or to "upcast" the types. test = np.array([1,2,3,4], dtype='int') should work better. But still might not handle this extreme. Commented Jan 17, 2017 at 8:11
  • (Specifically when I tested this example witih Python 2.7.17 and Numpy 1.11.1 I get the auto-promotion to large integer and all is, apparently, fine up to about test**31 ... but beyond that the operation causes: RuntimeWarning: invalid value encountered in power). So the Numpy broadcast of such large exponentiations isn't necessary completely transparent as compared to the same operations on native Python large integers). docs.scipy.org/doc/numpy/reference/arrays.dtypes.html Commented Jan 17, 2017 at 8:17

1 Answer 1

2

As mentioned in the comments, this happens because the integer data type overflows. Numpy initializes the array with a low level int data type because that fits the data you provided.

test = np.array([1,2,3,4])
test.dtype
# dtype('int32')

test[0] = 2**31 - 1  # works
test[0] = 2**31      # OverflowError: Python int too large to convert to C long

A 32 bit signed integer is used (on my system), which can hold values between -2147483648 and 2147483647.

You can force the array to have a different data type, e.g. floating point:

test = np.array([1, 2, 3, 4], dtype=float)
# test = np.array([1.0, 2.0, 3.0, 4.0])  # this is the same
test**50

# array([  1.00000000e+00,   1.12589991e+15,   7.17897988e+23, 1.26765060e+30])

Here is a list of data types that can be passed as strings to the dtype argument.

If you want Python's large integers instead of floating point precision, this works too (performance warning):

test = np.array([1,2,3,4], dtype=object)
test**50

# array([1, 1125899906842624, 717897987691852588770249, 
#        1267650600228229401496703205376], dtype=object)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.