Last active
August 29, 2015 14:06
-
-
Save dapangmao/4569e69379eb21ed0b25 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from doctest import testmod | |
import math | |
def factorial(n): | |
"""Return the factorial of n, an exact integer >= 0. | |
If the result is small enough to fit in an int, return an int. | |
Else return a long. | |
>>> [factorial(n) for n in range(6)] | |
[1, 1, 2, 6, 24, 120] | |
>>> [factorial(long(n)) for n in range(6)] | |
[1, 1, 2, 6, 24, 120] | |
>>> factorial(30) | |
265252859812191058636308480000000L | |
>>> factorial(30L) | |
265252859812191058636308480000000L | |
>>> factorial(-1) | |
Traceback (most recent call last): | |
... | |
ValueError: n must be >= 0 | |
>>> factorial(30.1) | |
Traceback (most recent call last): | |
... | |
ValueError: n must be exact integer | |
>>> factorial(30.0) | |
265252859812191058636308480000000L | |
It must also not be ridiculously large: | |
>>> factorial(1e100) | |
Traceback (most recent call last): | |
... | |
OverflowError: n too large | |
""" | |
if not n >= 0: | |
raise ValueError("n must be >= 0") | |
if math.floor(n) != n: | |
raise ValueError("n must be exact integer") | |
if n+1 == n: # catch a value like 1e300 | |
raise OverflowError("n too large") | |
result = 1 | |
factor = 2 | |
while factor <= n: | |
result *= factor | |
factor += 1 | |
return result | |
testmod() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment