Неправильные результаты с Python multiply () и prod () - PullRequest
1 голос
/ 18 февраля 2010

Может кто-нибудь объяснить следующее? Я использую Python 2.5

Рассмотрим 1 * 3 * 5 * 7 * 9 * 11 ... * 49. Если вы введете все это из интерактивной консоли IPython (x, y), вы получите 58435841445947272053455474390625L, что правильно. (почему нечетные числа: именно так, как я это сделал изначально)

Python multiply.reduce () или prod () должны давать одинаковый результат для эквивалентного диапазона. И это так, до определенного момента. Здесь это уже неправильно:

: k = range(1, 50, 2)
: multiply.reduce(k)
: -108792223

Использование prod (k) также приведет к -108792223 в результате. Другие неправильные результаты начинают появляться для эквивалентных диапазонов длины 12 (то есть k = диапазон (1,24,2)).

Я не уверен почему. Кто-нибудь может помочь?

Ответы [ 2 ]

6 голосов
/ 18 февраля 2010

Это связано с тем, что numpy.multiply.reduce() преобразует список диапазонов в массив типа numpy.int32, а операция сокращения переполняет то, что в какой-то момент может быть сохранено в 32 битах:

>>> type(numpy.multiply.reduce(range(1, 50, 2)))
<type 'numpy.int32'>

Как Майк Грэмговорит, что вы можете использовать параметр dtype, чтобы использовать целые числа Python вместо значений по умолчанию:

>>> res = numpy.multiply.reduce(range(1, 50, 2), dtype=object)
>>> res
58435841445947272053455474390625L
>>> type(res)
<type 'long'>

Но использование numpy для работы с объектами Python в этом случае бессмысленно, лучшее решение - KennyTM:

>>> import functools, operator
>>> functools.reduce(operator.mul, range(1, 50, 2))
58435841445947272053455474390625L
2 голосов
/ 18 февраля 2010

ЦП не умножает произвольно большие числа, он выполняет только определенные операции, определенные для определенных диапазонов чисел, представленных в 2, 0-1 битах.

Python '*' отлично обрабатывает большие целые числа посредством правильного представления и специального кода за пределами инструкций CPU или FPU для умножения.

Это на самом деле необычно для языков.

В большинстве других языков обычно число представляется в виде фиксированного массива битов. Например, в C или SQL вы можете выбрать 8-битное целое число, которое может представлять от 0 до 255, или от -128 до +127, или вы можете выбрать 16-битное целое число, которое может представлять до 2 ^ 16-1, что 65535. Когда представлен только диапазон чисел, превышение лимита с помощью какой-либо операции, такой как * или +, может иметь нежелательный эффект, например, получение отрицательного числа. Возможно, вы столкнулись с такой проблемой при использовании внешней библиотеки, которая, вероятно, изначально является C, а не python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...