Python более строго типизирован, чем другие языки сценариев. Например, в Perl:
perl -E '$c=5; $d="6"; say $c+$d' #prints 11
Но в Python:
>>> c="6"
>>> d=5
>>> print c+d
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
Perl проверит строку и преобразует ее в число, а операторы + - / * **
работают с числом, как вы ожидаете. PHP похож.
Python использует +
для объединения строк, поэтому попытка операции c+d
завершается неудачно, поскольку c является строкой, d int. Python имеет более сильный смысл числовых типов , чем Perl. ОК, я могу с этим справиться.
Но подумайте:
>>> from sys import maxint
>>> type(maxint)
<type 'int'>
>>> print maxint
9223372036854775807
>>> type(maxint+2)
<type 'long'>
>>> print maxint+2
9223372036854775809
>>> type((maxint+2)+maxint)
<type 'long'>
>>> print ((maxint+2)+maxint)
18446744073709551616
Теперь Python будет autopromote из целого числа, которое в данном случае имеет длину 64 бита (OS X, python 2.6.1), в целое число Python с произвольной точностью. Несмотря на то, что типы не совпадают, они похожи, и Python позволяет использовать обычные числовые операторы. Обычно это полезно. Это полезно, например, для сглаживания различий между 32 и 64 битами.
Преобразование из int
в long
является одним из способов:
>>> type((maxint+2)-2)
<type 'long'>
Как только преобразование выполнено, все операции с этой переменной теперь выполняются с произвольной точностью. Операции произвольной точности на несколько порядков медленнее, чем собственные операции int. В сценарии, над которым я работаю, некоторые из них должны быть быстрыми, а другие - продолжаться часами из-за этого. Рассмотрим:
>>> print maxint**maxint # execution so long it is essentially a crash
Итак, мой вопрос: есть ли способ победить или запретить автоматическое продвижение Python int
на Python long
?
Редактировать, продолжение:
Я получил несколько комментариев в форме «с какой стати вы хотели бы иметь поведение переполнения в стиле C?» Проблема заключалась в том, что этот конкретный фрагмент кода работал нормально на 32 битах в C и Perl (с use int
) с поведением переполнения Си. Произошла неудачная попытка перенести этот код на Python. Различное поведение переполнения в Python оказывается (частью) проблемы. В коде смешаны многие из этих различных идиом (C, Perl, немного Python) (и эти комментарии смешаны), так что это было сложно.
По сути, выполняемый анализ изображения представляет собой высокочастотный фильтр на основе диска для выполнения аналогичного сравнения изображений. Часть фильтра верхних частот имеет целочисленное умножение двух больших полиномов. Переполнение было, по сути, логикой «все равно, это большое ...», поэтому результат был таким, как предполагалось при переполнении на основе Си. Таким образом, использование правила Хорнера со временем O (n 2 ) было пустой тратой, так как большие полиномы были бы просто "большими" - грубая форма арифметики насыщенности вершины каротины.
Изменение полиномиального умножения на основе цикла на форму БПФ, вероятно, значительно быстрее. БПФ работает близко к линейному времени против O (n 2 ) для умножения полинома по правилу Хорнера. Переход с диска в память также ускорит это. Изображения не очень большие, но оригинальный код был написан в то время, когда они считались "огромными !!!" Владелец кода не совсем готов отказаться от своего любимого кода, так что посмотрим. Вероятно, «правильный ответ» для него - просто оставить Perl или C, если он хочет этот код.
Спасибо за ответы. Я не знал о десятичном модуле Python, и это, казалось, было ближе всего к тому, о чем я спрашивал - хотя в этом случае нужно решить и другие проблемы!