Factorial(big(-1))==0, bug or expected behaviour?

I noticed the following behaviour on my system (julia 1.8): the factorial of negative integers x disagrees when x is Int or BigInt. Is this a bug or expected behaviour? I also compare to the gamma function below (from SpecialFunctions).

x = -1
factorial(big(x)) # gives 0 as result (???)
factorial(x) # ERROR: DomainError with -1

using SpecialFunctions
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
1 Like

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.

3 Likes

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.

1 Like
julia> factorial(-1)
ERROR: DomainError with -1:
`n` must not be negative.
Stacktrace:
 [1] factorial_lookup
   @ ./combinatorics.jl:18 [inlined]
 [2] factorial(n::Int64)
   @ Base ./combinatorics.jl:27
 [3] top-level scope
   @ REPL[1]:1

julia> factorial(big(-1))
0

Surely, the same logic should apply to both

7 Likes

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 factorial(-1).

1 Like

@mlanghinrichs You’re right. Well seen. The result should be NaN or something like that.

Very interesting discussion: https://mathoverflow.net/questions/10124/the-factorials-of-1-2-3

2 Likes

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…

1 Like

I reported this issue on GitHub as a potential bug (see here).

4 Likes