I was checking out doctest and copied the factorial example to my editor. Since using recursion felt more functional programming, I felt like changing the example like this;
def factorial(n):
# ... omitted
if n+1 == n: # catch a value like 1e300
raise OverflowError("n too large")
if n == 0:
return 1
else:
return factorial(n - 1) * n
After this change, one of the tests failed;
Failed example:
factorial(30.0)
Expected:
265252859812191058636308480000000L
Got:
2.6525285981219103e+32
What is the reason of this difference?
Try running with
factorial(30)instead offactorial(30.0). floating point addition isn’t exact like integer addition, so you’ll start seeing errors after a while.Consider:
This is because you don’t have enough precision (bits) to store both of those numbers uniquely. (a typical python float has 64 bits meaning you have 2**64 unique combinations — somewhere around
1.84e19options. However, the maximum size for a python float issys.float_info.maxwhich is about1.8e308on most systems, so there is no way to store each integral value uniquely — especially when you consider that floats can hold a lot more than just integer values)Personally, I would just cast the value of n to an integer inside your factorial function since factorial is only defined for integers — possibly checking to make sure that
abs(int(n) - n) < 1e-5or something to that effect.