Если Ваш SQL Server использования 2005, существует действительно прохладный способ сделать эту использующую Общую Таблицу Выражения.
Это вынимает все gruntwork из составления временной таблицы, и basicly позволяет Вам делать все это только с С и ОБЪЕДИНЕНИЕ.
Вот хорошее учебное руководство:
http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1278207,00.html
Вы можете использовать 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
Это действительно только вариант, если вы точно знаете, что подписанный длинный long
будет иметь ширину 64 бита на целевой машине (ах).
Редактировать: Идея Йорендорфа об определении класса для 64-битных чисел является привлекательной. В идеале вы хотите минимизировать количество явных созданий классов.
Используя c_longlong
, вы можете сделать что-то вроде этого ( примечание: только 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))
...
Таким образом, результат ll (2 ** 63) - 1
действительно будет 9223372036854775807
. Однако такая конструкция может привести к снижению производительности, поэтому, в зависимости от того, что именно вы хотите сделать, определение класса, подобного приведенному выше, может не стоить того. В случае сомнений используйте timeit
.
Можете ли вы использовать numpy ? Он имеет тип int64, который делает именно то, что вы хотите.
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
Он прозрачен для пользователей, в отличие от примера ctypes, и написан на C, поэтому он будет быстрее, чем развертывание вашего собственного класса в Python. Numpy может быть больше, чем другие решения, но если вы занимаетесь численным анализом, вы оцените его наличие.
Быстрее всего, вероятно, самому усечь результат до 64 бит:
def to_int64(n):
n = n & ((1 << 64) - 1)
if n > (1 << 63) - 1:
n -= 1 << 64
return n
Вы, конечно, можете определить свой собственный числовой тип, который будет делать это автоматически каждый раз, когда вы выполняете какие-либо арифметические операции:
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)
...
, но это не очень «быстро» для реализации.
Взгляните на модуль ctypes, он используется для вызова сторонних DLL / библиотек из python. Есть несколько типов данных, которые соответствуют типам C, например
class c_longlong