Vorrei rappresentare un valore come 64bit firmato long
, tale che i valori superiori a (2 ** 63) -1 sono rappresentati come negativi, tuttavia Python long
ha una precisione infinita. C'è un modo 'veloce' per me per raggiungere questo obiettivo?Python type long vs C 'long long'
risposta
si potrebbe usare 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
questo è davvero solo un'opzione se Sappiamo per certo che uno signed long long
sarà largo 64 bit sui computer di destinazione.
Modifica:jorendorff's idea di definizione di una classe per i numeri a 64 bit è allettante. Idealmente, vuoi minimizzare il numero di creazioni di classe esplicite.
Utilizzando c_longlong
, si potrebbe fare qualcosa di simile (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))
...
In questo modo il risultato di ll(2 ** 63) - 1
sarà davvero 9223372036854775807
. Questa costruzione potrebbe tuttavia comportare una penalizzazione delle prestazioni, quindi a seconda di cosa si vuole fare esattamente, la definizione di una classe come quella sopra potrebbe non valerne la pena. In caso di dubbi, utilizzare timeit
.
La cosa più veloce è probabilmente quello di troncare il risultato a 64 bit da soli:
def to_int64(n):
n = n & ((1 << 64) - 1)
if n > (1 << 63) - 1:
n -= 1 << 64
return n
Ovviamente si può definire un tipo numerico che fa automaticamente questo ogni volta che si fa alcun tipo di operazione aritmetica:
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)
...
ma che non è particolarmente "veloce" da implementare.
Dai un'occhiata al modulo ctypes, è usato per chiamare DLL/librerie esterne da python. C'è un alcuni tipi di dati che corrispondono a tipi C, ad esempio
classe c_longlong
È possibile utilizzare numpy? Ha un tipo int64 che fa esattamente quello che vuoi.
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
E 'trasparente agli utenti, a differenza l'esempio ctypes, ed è codificato in C, in modo che sarà più veloce rispetto a rotazione la propria classe in Python. Numpy può essere più grande delle altre soluzioni, ma se stai facendo analisi numerica, apprezzerai averlo.
- 1. C++: long long int vs long int vs int64_t
- 2. C++ doppia a long long
- 3. Perché non è common_type <long, unsigned long> :: type = long long?
- 4. Long type 64bit linux
- 5. unsigned long long int pow
- 6. (lldb) Stampa unsigned long long in hex
- 7. Divide Long Long Number in percentuale
- 8. Il GCC supporta long long int?
- 9. aritmetica Java int vs. long
- 10. Wrap long lines in Python
- 11. Dimensioni di "long long" nella macchina a 128 bit?
- 12. cpp: eclipse non riconosce il tipo 'long long'
- 13. Funzione hash per un paio di long long?
- 14. long long è 8 byte, ma ottengo un overflow intero?
- 15. Come convertire 'long long' (o __int64) in __m64
- 16. Doppio a `unsigned long long` provoca memoria (pila?) La corruzione
- 17. MySQL: long table vs wide table
- 18. Java long to Mysql
- 19. NSDecimalNumber round long numbers
- 20. int to long assignment
- 21. Oracle: LONG o CLOB?
- 22. printf e long double
- 23. Qual è la differenza tra unsigned long/long/int in c/C++?
- 24. Wrap long lines in .vimrc
- 25. C#: Come convertire da long a ulong
- 26. sizeof (long) in C++ a 64 bit
- 27. Differenza tra long e int in C#?
- 28. Problema durante la conversione della stringa in long long in C
- 29. gcc codice di compilazione C++: undefined reference to `operator new [] (unsigned long long)'
- 30. RC2102: String letteral too long