Me gustaría representar un valor como 64bit firmado long
, de modo que los valores mayores que (2 ** 63) -1 se representan como negativos, sin embargo, Python long
tiene una precisión infinita. ¿Hay una manera "rápida" de lograr esto?Python tipo long vs C 'long long'
Respuesta
usted podría utilizar ctypes.c_longlong
:
>>> from ctypes import c_longlong as ll
>>> ll(2 ** 63 - 1)
c_longlong(9223372036854775807L)
>>> ll(2 ** 63)
c_longlong(-9223372036854775808L)
>>> ll(2 ** 63).value
-9223372036854775808L
Esto es realmente única una opción si sepa con seguridad que un signed long long
tendrá una anchura de 64 bits en la (s) máquina (s) de destino.
Editar:jorendorff's idea de definir una clase de números de 64 bits es atractivo. Lo ideal es minimizar el número de creaciones de clases explícitas.
Usando c_longlong
, se podría hacer algo como esto (nota:! Python 3.x):
from ctypes import c_longlong
class ll(int):
def __new__(cls, n):
return int.__new__(cls, c_longlong(n).value)
def __add__(self, other):
return ll(super().__add__(other))
def __radd__(self, other):
return ll(other.__add__(self))
def __sub__(self, other):
return ll(super().__sub__(other))
def __rsub__(self, other):
return ll(other.__sub__(self))
...
De esta manera el resultado de ll(2 ** 63) - 1
será de hecho 9223372036854775807
. Sin embargo, esta construcción puede dar como resultado una penalización en el rendimiento, por lo que dependiendo de lo que quieras hacer exactamente, definir una clase como la anterior no puede valer la pena. En caso de duda, use timeit
.
Lo más rápido es, probablemente, para truncar el resultado de 64 bits de sí mismo:
def to_int64(n):
n = n & ((1 << 64) - 1)
if n > (1 << 63) - 1:
n -= 1 << 64
return n
Por supuesto, puede definir su propio tipo numérico que hace automáticamente cada vez que lo hace cualquier tipo de operación aritmética:
class Int64:
def __init__(self, n):
if isinstance(n, Int64):
n = n.val
self.val = to_int64(n)
def __add__(self, other):
return Int64(self.val + other)
def __radd__(self, other):
return Int64(other + self.val)
def __sub__(self, other):
return Int64(self.val - other)
...
pero eso no es particularmente "rápido" de implementar.
Eche un vistazo al módulo ctypes, se usa para llamar a bibliotecas/DLL extranjeras de python. Hay un algunos tipos de datos que corresponden a los tipos C, por ejemplo
c_longlong clase
¿Se puede usar numpy? Tiene un tipo int64 que hace exactamente lo que quieres.
In [1]: import numpy
In [2]: numpy.int64(2**63-1)
Out[2]: 9223372036854775807
In [3]: numpy.int64(2**63-1)+1
Out[3]: -9223372036854775808
Es transparente para los usuarios, a diferencia del ejemplo ctypes, y está codificado en C por lo que será más rápido que rodar su propia clase en Python. Numpy puede ser más grande que las otras soluciones, pero si está haciendo un análisis numérico, apreciará tenerlo.
- 1. C++: long long int vs. long int vs. int64_t
- 2. unsigned long long vs unsigned long (portabilidad punto de vista)
- 3. cadena de conversión a long long
- 4. Multiplicando dos long long ints C
- 5. impresión unsigned long long int Tipo Valor Devuelve resultados extraños
- 6. Tipo de clave principal: int vs long
- 7. equivalente en Java de unsigned long long?
- 8. Especificador de formato de 'long long'
- 9. (lldb) Imprimir unsigned long long en hexadecimal
- 10. Divide Long Long Number como porcentaje
- 11. ¿GCC es compatible con long long int?
- 12. ¿Hay tipos más grandes que long long int en C++?
- 13. double double vs long int
- 14. ¿Hay tipo Long en SQLite?
- 15. 'long long int' se interpreta como 'long int'. ¿Cómo puedo evitar esto?
- 16. long para HWND (VS8 C++)
- 17. ¿Debo usar long long o int64_t para código portable?
- 18. long double returns y ctypes
- 19. Bitwise "&" on a long?
- 20. Cómo convertir 'long long' (o __int64) a __m64
- 21. Long type 64bit linux
- 22. ¿Cómo se maneja Python int y long?
- 23. PostgreSQL Long VACUUM
- 24. long int en PHP
- 25. Rails: Long Polling Practices
- 26. mq_receive: message too long
- 27. Java long to binary
- 28. cast Long a BigDecimal
- 29. Flask long routines
- 30. Java long to Mysql