예제 #1
0
def factorial(n):
    """Returns the factorial of n.

    Parameters
        * n: int (n >= 0)

    Returns:
        * prod: int

    Raises:
        * ValueError: If n < 0.

    Examples:
        >>> factorial(10)
        3628800
        >>> factorial(40)
        815915283247897734345611269596115894272000000000L
        >>> factorial(-1)
        Traceback (most recent call last):
        ...
        ValueError: factorial: Must have n >= 0.

    Details:
        The algorithm used is a binary splitting method. See Section 10.2.3 of
        "Pi and the AGM" by Borwein and Borwein for information about this
        method.
    """
    if n < 0:
        raise ValueError("factorial: Must have n >= 0.")
    elif n in (0, 1):
        return 1

    prod = 1
    for k in xrange(1, n.bit_length()):
        lower = (n >> k) + 1
        upper = (n >> (k - 1)) + 1

        if lower % 2 == 0:
            lower += 1

        partial = 1
        for j in xrange(lower, upper, 2):
            partial *= j
        prod *= (partial**k)

    return prod << (n - bit_count(n))
예제 #2
0
def factorial(n):
    """Returns the factorial of n.

    Parameters
        * n: int (n >= 0)

    Returns:
        * prod: int

    Raises:
        * ValueError: If n < 0.

    Examples:
        >>> factorial(10)
        3628800
        >>> factorial(40)
        815915283247897734345611269596115894272000000000L
        >>> factorial(-1)
        Traceback (most recent call last):
        ...
        ValueError: factorial: Must have n >= 0.

    Details:
        The algorithm used is a binary splitting method. See Section 10.2.3 of
        "Pi and the AGM" by Borwein and Borwein for information about this
        method.
    """
    if n < 0:
        raise ValueError("factorial: Must have n >= 0.")
    elif n in (0, 1):
        return 1

    prod = 1
    for k in xrange(1, n.bit_length()):
        lower = (n >> k) + 1
        upper = (n >> (k - 1)) + 1

        if lower % 2 == 0:
            lower += 1

        partial = 1
        for j in xrange(lower, upper, 2):
            partial *= j
        prod *= (partial**k)

    return prod << (n - bit_count(n))
예제 #3
0
 def test_bit_count(self):
     for k in xrange(20):
         self.assertTrue(bit_count(-k) == bit_count(k) == bin(k).count('1'))
예제 #4
0
 def test_bit_count(self):
     for k in xrange(20):
         self.assertTrue(bit_count(-k) == bit_count(k) == bin(k).count('1'))