I noticed the following behaviour on my system (julia 1.8): the
factorial of negative integers
x disagrees when
BigInt. Is this a bug or expected behaviour? I also compare to the
gamma function below (from
x = -1
factorial(big(x)) # gives 0 as result (???)
factorial(x) # ERROR: DomainError with -1
gamma(x+1) # Inf
gamma(big(x+1)) # Inf
# expected behaviour for a positive integer
x = 5
factorial(big(x)) # 120
factorial(x) # 120
gamma(x+1) # 120.0
gamma(big(x+1)) # 120.0
It definitely seems intentional given the source code
factorial(x::BigInt) = isneg(x) ? BigInt(0) : MPZ.fac_ui(x) but I can’t imagine why.
The code as it is was written in this commit to move things into a MPZ module and first shows up in the 0.7 release. However, the step of returning
BigInt(0) for negative integers predates that, seems to go back as far as 0.1.
One can view this factorial as an empty product, in which case it makes sense to return 1.
EDIT: Ah sorry, it returns 0. In this case, a way to make sense is to consider this is the product of the integers from 1 to n=-1, which is indeed 0.
ERROR: DomainError with -1:
`n` must not be negative.
@ ./combinatorics.jl:18 [inlined]
@ Base ./combinatorics.jl:27
 top-level scope
Surely, the same logic should apply to both
hmm yes, it could, but in this definition
factorial(0) should evaluate to
0? This is in contrast to the common definition
factorial(0) = 1 which is also the current implementation.
In any case, I was surprised by
factorial(big(-1)) = 0 and would have expected the same error message as for
@mlanghinrichs You’re right. Well seen. The result should be
NaN or something like that.
It seem like a bug, and someone should likely make a PR for it to error.
It contradicts what you get from the Roman factorial, one extension for integers I never heard of:
It also contradicts the gamma function (for nonintegers), that i.e. also contradicts Roman factorials.
Since we have the gamma function available (not in Base), there’s no need to have that extension, and the output of the Roman factorial are no longer integers for n <= -2 so it’s not a type stable function, and it seems odd to add that extension just down to -2, i.e. for only two more values -1 and -2…
I reported this issue on GitHub as a potential bug (see here).