cython

Форк
0
/
longintrepr.pyx 
55 строк · 1.4 Кб
1
# mode: run
2

3
# Test longintrepr declarations by implementing a simple function
4

5
from cpython.longintrepr cimport *
6
cimport cython
7

8
@cython.cdivision(True)
9
def lshift(long a, unsigned long n):
10
    """
11
    Return a * 2^n as Python long.
12

13
    >>> print(lshift(3, 1))
14
    6
15
    >>> print(lshift(1, 30))
16
    1073741824
17
    >>> print(lshift(-12345, 115))
18
    512791237748899576593671817473776680960
19
    >>> print(-12345 << 115)
20
    -512791237748899576593671817473776680960
21
    >>> [i for i in range(100) if (65535 << i) != lshift(65535, i)]
22
    []
23
    >>> print(lshift(0, 12345))
24
    0
25
    >>> print(lshift(2**62, 0))   # doctest: +ELLIPSIS
26
    Traceback (most recent call last):
27
    ...
28
    OverflowError...
29
    """
30
    if not a:
31
        return _PyLong_New(0)
32
    cdef unsigned long apos = a if a > 0 else -a
33
    if (apos >> 1) >= <unsigned long>PyLong_BASE:
34
        raise OverflowError
35

36
    cdef unsigned long index = n // PyLong_SHIFT
37
    cdef unsigned long shift = n % PyLong_SHIFT
38

39
    cdef digit d = apos
40
    cdef digit low = (d << shift) & PyLong_MASK
41
    cdef digit high = (d >> (PyLong_SHIFT - shift))
42

43
    if high == 0:
44
        ret = _PyLong_New(index + 1)
45
        ret.ob_digit[index] = low
46
    else:
47
        ret = _PyLong_New(index + 2)
48
        ret.ob_digit[index] = low
49
        ret.ob_digit[index + 1] = high
50

51
    while index >= 1:
52
        index -= 1
53
        ret.ob_digit[index] = 0
54

55
    return ret
56

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.