Python es más fuertemente tipado que otros lenguajes de scripting. Por ejemplo, en Perl:Python: ¿Hay alguna manera de evitar que ocurra una conversión automática de int a long int?
perl -E '$c=5; $d="6"; say $c+$d' #prints 11
Pero en 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 inspeccionará una cadena y convertir en un número, y el trabajo de los operadores + -/* **
como se espera con un número. PHP es similar.
Python usa +
para concatenar cadenas por lo que el intento de operación de c+d
falla porque c es una cadena, d un int. Python tiene un sentido más fuerte de numeric types que Perl. OK - Puedo lidiar con eso.
Pero tenga en cuenta:
>>> 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
Ahora Python autopromote de un int, que en este caso es un poco largo, 64 (OS X, Python 2.6.1) a un long int Python que es de precisión arbitraria . Aunque los tipos no son iguales, son similares y Python permite el uso de los operadores numéricos habituales. Por lo general, esto es útil. Es útil para suavizar las diferencias entre 32 bits y 64 bits, por ejemplo.
La conversión de int
a long
es una manera:
>>> type((maxint+2)-2)
<type 'long'>
Una vez realizada la conversión, todas las operaciones en esa variable ahora se hacen en precisión arbitraria. Las operaciones de precisión arbitraria son órdenes de magnitud más lentas que las operaciones int nativas. En un script en el que estoy trabajando, me gustaría que la ejecución sea rápida y que se extienda a horas debido a esto. Considere lo siguiente:
>>> print maxint**maxint # execution so long it is essentially a crash
Así que mi pregunta: ¿Hay una manera de derrotar o no permitir la auto-promoción de un pitón int
a una pitón long
?
Editar, seguimiento: '¿por qué en la tierra que usted quiere tener un comportamiento desbordamiento estilo C'
recibí varios comentarios en la forma de El problema era que esta pieza de código funcionaba bien en 32 bits en C y Perl (con use int
) con el comportamiento de desbordamiento de C. Hubo un intento fallido de transferir este código a Python. El comportamiento de desbordamiento diferente de Python resulta ser (parte) del problema. El código tiene muchos de esos diferentes modismos (C, Perl, algo de pitón) mezclados (y esos comentarios mezclados), por lo que fue un desafío.
Básicamente, el análisis de imágenes que se realiza es un filtro de paso alto basado en disco para realizar una comparación de imágenes similar. Parte del filtro de paso alto tiene una multiplicación basada en números enteros de dos polinomios grandes. El desbordamiento era esencialmente un tipo de lógica de "no me importa, es grande ...", por lo que el resultado fue el deseado con un desbordamiento basado en C. Entonces, el uso de la regla de Horner con O (n) fue un desperdicio ya que los polinomios más grandes serían simplemente "grandes", una forma de justicia aproximada de la aritmética de saturación de carot-top.
Cambiar la multiplicación de polinomios basados en bucle a una forma de FFT es probablemente mucho más rápido.FFT se ejecuta casi en tiempo lineal frente a O (n) para la polinomial de regla de Horner multiplicar. Pasar de un disco a otro en la memoria también lo acelerará. Las imágenes no son terriblemente grandes, pero el código original se escribió en un momento en que se consideraban "enormes". El propietario del código no está listo para destruir su código querido, así que ya veremos. La 'respuesta correcta' para él probablemente sea mantener a Perl o C si él quiere ese código.
Gracias por las respuestas. No sabía acerca del módulo decimal de Python, y parecía ser lo más parecido a lo que estaba preguntando, ¡aunque hay otros problemas que resolver en este caso!
maxint ** maxint es un número con >> 750 decimales, espero que no estés realmente sorprendido, lleva un tiempo. Además, ¿qué se supone que debe suceder cuando un número no cabe en 32 bits? –
¿Estás diciendo que las operaciones matemáticas básicas hacen que tu aplicación funcione durante horas más de lo normal? Eso suena como su error, no python's – Falmarri
Además, ¿qué debería pasar en lugar de autopromoción? Segfault? Parece que debe mantener sus números debajo de sys.maxint ... – Falmarri