Skip to content

Commit

Permalink
Merge pull request JuliaLang#14436 from eschnett/eschnett/avoid-int12…
Browse files Browse the repository at this point in the history
…8-try

Avoid expensive try-catch for Int128 division
  • Loading branch information
jakebolewski committed Dec 22, 2015
2 parents f1ae025 + 86c7bc8 commit 65937f4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 30 deletions.
36 changes: 6 additions & 30 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,46 +376,22 @@ if WORD_SIZE == 32
end

function div(x::Int128, y::Int128)
try
Int128(div(BigInt(x),BigInt(y)))
catch e
isa(e, InexactError) && throw(DivideError())
rethrow()
end
(x == typemin(Int128)) & (y == -1) && throw(DivideError())
Int128(div(BigInt(x),BigInt(y)))
end
function div(x::UInt128, y::UInt128)
try
UInt128(div(BigInt(x),BigInt(y)))
catch e
isa(e, InexactError) && throw(DivideError())
rethrow()
end
UInt128(div(BigInt(x),BigInt(y)))
end

function rem(x::Int128, y::Int128)
try
Int128(rem(BigInt(x),BigInt(y)))
catch e
isa(e, InexactError) && throw(DivideError())
rethrow()
end
Int128(rem(BigInt(x),BigInt(y)))
end
function rem(x::UInt128, y::UInt128)
try
UInt128(rem(BigInt(x),BigInt(y)))
catch e
isa(e, InexactError) && throw(DivideError())
rethrow()
end
UInt128(rem(BigInt(x),BigInt(y)))
end

function mod(x::Int128, y::Int128)
try
Int128(mod(BigInt(x),BigInt(y)))
catch e
isa(e, InexactError) && throw(DivideError())
rethrow()
end
Int128(mod(BigInt(x),BigInt(y)))
end

<<( x::Int128, y::Int) = y == 0 ? x : box(Int128,shl_int(unbox(Int128,x),unbox(Int,y)))
Expand Down
16 changes: 16 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,22 @@ end
@test signed(cld(typemax(UInt),typemin(Int)>>1)) == -3
@test signed(cld(typemax(UInt),(typemin(Int)>>1)+1)) == -4

# Test exceptions and special cases
for T in (Int8,Int16,Int32,Int64,Int128, UInt8,UInt16,UInt32,UInt64,UInt128)
@test_throws DivideError div(T(1), T(0))
@test_throws DivideError fld(T(1), T(0))
@test_throws DivideError cld(T(1), T(0))
@test_throws DivideError rem(T(1), T(0))
@test_throws DivideError mod(T(1), T(0))
end
for T in (Int8,Int16,Int32,Int64,Int128)
@test_throws DivideError div(typemin(T), T(-1))
@test_throws DivideError fld(typemin(T), T(-1))
@test_throws DivideError cld(typemin(T), T(-1))
@test rem(typemin(T), T(-1)) === T(0)
@test mod(typemin(T), T(-1)) === T(0)
end

# Test return types
for T in (Int8,Int16,Int32,Int64,Int128, UInt8,UInt16,UInt32,UInt64,UInt128)
z, o = T(0), T(1)
Expand Down

0 comments on commit 65937f4

Please sign in to comment.