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 из int, который в этом случае является 64-битным (OS X, python 2.6.1) python long int, который имеет произвольную точность. Несмотря на то, что типы не совпадают, они похожи, и Python позволяет использовать обычные числовые операторы. Обычно это полезно. Это полезно при сглаживании различий между 32-битным и 64-битным, например.
Преобразование из int
в long
является одним из способов:
>>> type((maxint+2)-2)
<type 'long'>
После завершения преобразования все операции над этой переменной выполняются произвольной точностью. Операции произвольной точности на несколько порядков медленнее, чем нативные операции int. На script, над которым я работаю, я бы выполнил какое-то исполнение, и это из-за этого ускорилось. Рассмотрим:
>>> print maxint**maxint # execution so long it is essentially a crash
Итак, мой вопрос: есть ли способ победить или не разрешить авто-продвижение Python int
на Python long
?
Изменить, следить:
Я получил несколько комментариев в форме: "Почему бы вам не хотеть иметь поведение переполнения стиля С?" Проблема заключалась в том, что этот фрагмент кода работал нормально на 32 битах в C и Perl (с use int
) с поведением C переполнения. Произошла неудачная попытка перенести этот код на Python. Различное поведение переполнения Python оказывается (частью) проблемы. В коде много разных этих идиом (C, Perl, некоторые python), смешанные в (и эти комментарии смешались), поэтому это было сложно.
По существу, выполняемый анализ изображения представляет собой фильтр верхних частот на основе диска для выполнения аналогичного сравнения изображений. Часть фильтра верхних частот имеет целочисленное умножение двух больших многочленов. Переполнение было, по сути, логикой "не заботьтесь, это большая...", поэтому результат был таким же, как предполагалось, с переполнением на основе C. Таким образом, использование правила Хорнера с временем O (n 2) было отходом, поскольку большие многочлены были бы просто "большими" - арифметикой грубой справедливости арифметики насыщения каротином.
Изменение многочленного умножения на основе цикла на форму БПФ, вероятно, значительно быстрее. FFT работает в близком к линейному времени vs O (n 2) для многочлена многочлена Horner. Переход с диска на встроенную память также ускорит это. Изображения не очень большие, но исходный код был написан в то время, когда они считались "огромными!!!" Владелец кода не совсем готов уничтожить его любимый код, так что посмотрим. "Правильный ответ" для него, вероятно, это просто держать Perl или C, если он хочет этот код.
Спасибо за ответы. Я не знал о десятичном модуле Python, и это, казалось, было самым близким к тому, что я просил - даже если в этом случае есть другие проблемы!