Skip to content

Commit

Permalink
Merge pull request #9647 from JuliaLang/cjh/fix-9618
Browse files Browse the repository at this point in the history
Fix #9618
  • Loading branch information
jiahao committed Jan 18, 2015
2 parents ad489ed + b41ff44 commit 20e7818
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
18 changes: 15 additions & 3 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ function isqrt(x::BigInt)
return z
end

function ^(x::BigInt, y::UInt)
function ^(x::BigInt, y::Culong)
z = BigInt()
ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, y)
return z
Expand All @@ -373,8 +373,20 @@ function bigint_pow(x::BigInt, y::Integer)
if y<0; throw(DomainError()); end
if x== 1; return x; end
if x==-1; return isodd(y) ? x : -x; end
if y>typemax(UInt); throw(DomainError()); end
return x^uint(y)
if y>typemax(Culong)
x==0 && return x

#At this point, x is not 1, 0 or -1 and it is not possible to use
#gmpz_pow_ui to compute the answer. Note that the magnitude of the
#answer is:
#- at least 2^(2^32-1) ≈ 10^(1.3e9) (if Culong === UInt32).
#- at least 2^(2^64-1) ≈ 10^(5.5e18) (if Culong === UInt64).
#
#Assume that the answer will definitely overflow.

throw(OverflowError())
end
return x^convert(Culong, y)
end

^(x::BigInt , y::BigInt ) = bigint_pow(x, y)
Expand Down
5 changes: 5 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2126,3 +2126,8 @@ end
#Issue #5570
@test map(x -> int(mod1(uint(x),uint(5))), 0:15) == [5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

# Issue #9618: errors thrown by large exponentiations
@test_throws DomainError big(2)^-(big(typemax(UInt))+1)
@test_throws OverflowError big(2)^(big(typemax(UInt))+1)
@test 0==big(0)^(big(typemax(UInt))+1)

0 comments on commit 20e7818

Please sign in to comment.