Reputation: 2074
I've completed Euler Project problem #8 (the answer is not included in this question), but ran into some unexpected behavior with numpy.prod
. The function returned negative numbers for some list of all positive, single-digit integers. This looks related to this question.
import numpy as np
# this implementation doesn't work
np.prod(list(map(int, '9478851843858')))
Out[139]: -1817706496
# but these do
np.prod(np.array(list(map(int, '9478851843858' )), dtype='int64'))
Out[141]: 2477260800
reduce((lambda x, y: x*y),list(map(int,list('9478851843858'))))
Out[144]: 2477260800
These are other examples:
('3975369781797', -514256656),
('9476545682848', -579076096),
('4765456828489', -579076096),
('7536978179778', -748460672),
('8694788518438', -1322254336),
('5397536978179', -1594459696),
('6652947654568', -1682231296),
('9478851843858', -1817706496)]
But not these:
('4788518438586', 1651507200),
('6978179778461', 1792336896),
('8787992724428', 1820786688),
('6947885184385', 1857945600),
('4355766896648', 1975599104),
('5576689664895', 2039787520),
('9194934969835', 2040733440),
('9878799272442', 2048385024),
('8617866458359', 2090188800),
('9781797784617', 2091059712)]
What about passing the python list to np.prod
causes it to return a negative integer?
Upvotes: 0
Views: 437
Reputation: 44838
NumPy is written in C and C++, and it doesn't have the "unbounded" integer type that Python has. So all integers are of widths your CPU supports. This means that overflows and underflows can occur.
Take a look at this C code:
#include <stdio.h>
#include <stdint.h>
int main(void) {
int64_t data = 2477260800ULL;
printf("i64: %lld, i32: %d\n", data, (int32_t)data);
}
And here's the output:
~> clang test.c
~> ./a.out
i64: 2477260800, i32: -1817706496
So it looks like your NumPy is using 32-bit signed integers that can't contain the unsigned number 2477260800 because bin(2477260800) == '0b10010011101010000000000000000000'
, and that's a negative int32_t
.
Upvotes: 3