# Return types of factorial and reduce

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?

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.

yeah, I’ve inspected the code
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… ?

2 Likes