Return types of factorial and reduce


#1

I guess these are very silly questions, but I can’t find the rationale for
factorial(::Int32) → Int64, factorial(::UInt64) → UInt64 but factorial(::UInt32) → Int64 (why not UInt64?)

Moreover lcm(::UInt16, ::Int64) and lcm(::UInt32, ::Int64) both return Int64, while
reduce(lcm, UInt16(1), Int64[4]) → Int64 but reduce(lcm, UInt32(1), Int64[4]) → UInt64.
I guess there is some type widening happening, but why?


#2

That’s a good question. This is the code.

factorial(n::Union{Int8,UInt8,Int16,UInt16,Int32,UInt32}) =
 factorial(Int64(n))

I agree that

factorial(n::Union{Int8,Int16,Int32}) =
 factorial(Int64(n))
factorial(n::Union{UInt8,UInt16,UInt32}) =
 factorial(UInt64(n))

looks more reasonable. But, I can’t think of a practical reason for choosing either one.


#3

yeah, I’ve inspected the code :wink:
the only rationale I can think of is that UInt can handle larger numbers, which doesn’t really help with the factorials (both are positive, limited to n=20), but may help in further integer computations. Which is why I think it would be desirable to keep the factorial of a n::T<:Unsigned in the Unsigned family… ?