Skip to content

Commit

Permalink
Ensure rising_factorial(::Int,::Int) detects overflows (#1453)
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin authored Oct 3, 2023
1 parent ae4d543 commit 6a8e2d2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/generic/Misc/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ julia> rising_factorial(4, 2)
function rising_factorial(x::RingElement, n::Integer)
n < 0 && throw(DomainError(n, "Argument must be non-negative"))
n == 0 && return one(x)
n == 1 && return x
if x isa Integer
return reduce(Base.checked_mul, x+i-1 for i in 1:Int(n))
end
return prod(x+i-1 for i in 1:Int(n))
end

Expand All @@ -73,14 +77,18 @@ julia> rising_factorial2(x, 1)
julia> rising_factorial2(x, 2)
(x^2 + x, 2*x + 1)
julia> rising_factorial2(4,2)
julia> rising_factorial2(4, 2)
(20, 9)
```
"""
function rising_factorial2(x::RingElement, n::Integer)
n < 0 && throw(DomainError(n, "Argument must be non-negative"))
n == 0 && return (one(x), zero(x))
n == 1 && return (x, one(x))
f, F = rising_factorial2(x, Int(n)-1)
# use product rule: [(x+n-1)*f(x)]' = (x+n-1)'*f(x) + (x+n-1)*f'(x)
if x isa Integer
return Base.checked_mul(x+n-1, f), f + Base.checked_mul(x+n-1, F)
end
return (x+n-1)*f, f + (x+n-1)*F
end
6 changes: 6 additions & 0 deletions test/misc-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@
@test_throws ErrorException evaluate(:(x + x^2 + f(x)), Dict(:x => 1))
@test_throws ErrorException evaluate((Expr(:x)), Dict(:y => 1))
end

@testset "rising_factorial" begin

@test_throws OverflowError rising_factorial(10,30)
@test_throws OverflowError rising_factorial2(10,30)
end

0 comments on commit 6a8e2d2

Please sign in to comment.