Skip to content

Commit

Permalink
Merge pull request JuliaLang#13912 from JuliaLang/nl/checked_abs
Browse files Browse the repository at this point in the history
Add checked_abs() methods for unsigned ints and BigInt
  • Loading branch information
hayd committed Nov 8, 2015
2 parents 3f74f34 + 837e7a6 commit df3cd41
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
1 change: 1 addition & 0 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ isprime(x::BigInt, reps=25) = ccall((:__gmpz_probab_prime_p,:libgmp), Cint, (Ptr
prevpow2(x::BigInt) = x.size < 0 ? -prevpow2(-x) : (x <= 2 ? x : one(BigInt) << (ndigits(x, 2)-1))
nextpow2(x::BigInt) = x.size < 0 ? -nextpow2(-x) : (x <= 2 ? x : one(BigInt) << ndigits(x-1, 2))

Base.checked_abs(x::BigInt) = abs(x)
Base.checked_add(a::BigInt, b::BigInt) = a + b
Base.checked_sub(a::BigInt, b::BigInt) = a - b
Base.checked_mul(a::BigInt, b::BigInt) = a * b
Expand Down
18 changes: 14 additions & 4 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,29 @@ typemin(typeof(x))`, `abs(x) == x`, not `-x` as might be expected.
"""
abs(x::Signed) = flipsign(x,x)

"""
Base.checked_abs(x)
The absolute value of `x`, with overflow error trapping where applicable.
For types for which no overflow can happen during `abs`, this is equivalent
to `abs(x)`.
"""
function checked_abs end

"""
Base.checked_abs(x::Signed)
The absolute value of `x`, with signed integer overflow error trapping.
`checked_abs` will throw an `OverflowError` when `x == typemin(typeof(x))`.
Otherwise `checked_abs` behaves as `abs`, though the overflow protection may
impose a perceptible performance penalty.
For signed integers, throws an `OverflowError` when `x == typemin(typeof(x))`.
Otherwise, behaves as `abs`, though the overflow protection may impose a perceptible
performance penalty.
"""
function checked_abs{T<:Signed}(x::T)
x == typemin(T) && throw(OverflowError())
abs(x)
end

checked_abs(x::Unsigned) = abs(x)

~(n::Integer) = -n-1

unsigned(x::Signed) = reinterpret(typeof(convert(Unsigned,zero(x))), x)
Expand Down
6 changes: 6 additions & 0 deletions test/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ for T in SItypes
@test_throws OverflowError checked_abs(typemin(T))
end

for T in UItypes
@test checked_abs(one(T)) == one(T)
end

@test checked_abs(BigInt(-1)) == BigInt(1)

# Checked operations on UInt128 are currently broken
# FIXME: #4905

Expand Down

0 comments on commit df3cd41

Please sign in to comment.