Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate nextpow2/prevpow2 #28304

Merged
merged 1 commit into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,8 @@ Deprecated or removed

* `sortrows`/`sortcols` have been deprecated in favor of the more general `sortslices`.

* `nextpow2`/`prevpow2` have been deprecated in favor of the more general `nextpow`/`prevpow` functions.

Command-line option changes
---------------------------

Expand Down
4 changes: 4 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,10 @@ end
@deprecate sortrows(A::AbstractMatrix; kws...) sortslices(A, dims=1, kws...)
@deprecate sortcols(A::AbstractMatrix; kws...) sortslices(A, dims=2, kws...)

# PR #28304
@deprecate nextpow2(x) nextpow(2, x)
@deprecate prevpow2(x) prevpow(2, x)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
2 changes: 0 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -297,15 +297,13 @@ export
muladd,
nextfloat,
nextpow,
nextpow2,
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also prevpow2?

nextprod,
numerator,
one,
oneunit,
powermod,
prevfloat,
prevpow,
prevpow2,
rad2deg,
rationalize,
real,
Expand Down
7 changes: 4 additions & 3 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor,
binomial, cmp, convert, div, divrem, factorial, fld, gcd, gcdx, lcm, mod,
ndigits, promote_rule, rem, show, isqrt, string, powermod,
sum, trailing_zeros, trailing_ones, count_ones, tryparse_internal,
bin, oct, dec, hex, isequal, invmod, prevpow2, nextpow2, ndigits0zpb,
bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb,
widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit,
hastypemax

Expand Down Expand Up @@ -634,10 +634,11 @@ function ndigits0zpb(x::BigInt, b::Integer)
end
end

# Fast paths for nextpow(2, x::BigInt)
# below, ONE is always left-shifted by at least one digit, so a new BigInt is
# allocated, which can be safely mutated
prevpow2(x::BigInt) = -2 <= x <= 2 ? x : flipsign!(ONE << (ndigits(x, base=2) - 1), x)
nextpow2(x::BigInt) = count_ones_abs(x) <= 1 ? x : flipsign!(ONE << ndigits(x, base=2), x)
_prevpow2(x::BigInt) = -2 <= x <= 2 ? x : flipsign!(ONE << (ndigits(x, base=2) - 1), x)
_nextpow2(x::BigInt) = count_ones_abs(x) <= 1 ? x : flipsign!(ONE << ndigits(x, base=2), x)

Base.checked_abs(x::BigInt) = abs(x)
Base.checked_neg(x::BigInt) = -x
Expand Down
53 changes: 13 additions & 40 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ function powermod(x::Integer, p::Integer, m::T) where T<:Integer
(m == 1 || m == -1) && return zero(m)
b = oftype(m,mod(x,m)) # this also checks for divide by zero

t = prevpow2(p)
t = prevpow(2, p)
r::T = 1
while true
if p >= t
Expand All @@ -309,43 +309,10 @@ end
# optimization: promote the modulus m to BigInt only once (cf. widemul in generic powermod above)
powermod(x::Integer, p::Integer, m::Union{Int128,UInt128}) = oftype(m, powermod(x, p, big(m)))

# smallest power of 2 >= x

"""
nextpow2(n::Integer)

The smallest power of two not less than `n`. Returns 0 for `n==0`, and returns
`-nextpow2(-n)` for negative arguments.

# Examples
```jldoctest
julia> nextpow2(16)
16

julia> nextpow2(17)
32
```
"""
nextpow2(x::Unsigned) = oneunit(x)<<((sizeof(x)<<3)-leading_zeros(x-oneunit(x)))
nextpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -nextpow2(unsigned(-x)) : nextpow2(unsigned(x)))

"""
prevpow2(n::Integer)

The largest power of two not greater than `n`. Returns 0 for `n==0`, and returns
`-prevpow2(-n)` for negative arguments.

# Examples
```jldoctest
julia> prevpow2(5)
4

julia> prevpow2(0)
0
```
"""
prevpow2(x::Unsigned) = one(x) << unsigned((sizeof(x)<<3)-leading_zeros(x)-1)
prevpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -prevpow2(unsigned(-x)) : prevpow2(unsigned(x)))
_nextpow2(x::Unsigned) = oneunit(x)<<((sizeof(x)<<3)-leading_zeros(x-oneunit(x)))
_nextpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -_nextpow2(unsigned(-x)) : _nextpow2(unsigned(x)))
_prevpow2(x::Unsigned) = one(x) << unsigned((sizeof(x)<<3)-leading_zeros(x)-1)
_prevpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -_prevpow2(unsigned(-x)) : _prevpow2(unsigned(x)))

"""
ispow2(n::Integer) -> Bool
Expand Down Expand Up @@ -387,8 +354,12 @@ julia> nextpow(4, 16)
See also [`prevpow`](@ref).
"""
function nextpow(a::Real, x::Real)
a <= 1 && throw(DomainError(a, "`a` must be greater than 1."))
x <= 0 && throw(DomainError(x, "`x` must be positive."))
# Special case fast path for x::Integer, a == 2.
# This is a very common case. Constant prop will make sure that a call site
# specified as `nextpow(2, x)` will get this special case inlined.
a == 2 && isa(x, Integer) && return _nextpow2(x)
a <= 1 && throw(DomainError(a, "`a` must be greater than 1."))
x <= 1 && return one(a)
n = ceil(Integer,log(a, x))
p = a^(n-1)
Expand Down Expand Up @@ -419,8 +390,10 @@ julia> prevpow(4, 16)
See also [`nextpow`](@ref).
"""
function prevpow(a::Real, x::Real)
a <= 1 && throw(DomainError(a, "`a` must be greater than 1."))
x < 1 && throw(DomainError(x, "`x` must be ≥ 1."))
# See comment in nextpos() for a == special case.
a == 2 && isa(x, Integer) && return _prevpow2(x)
a <= 1 && throw(DomainError(a, "`a` must be greater than 1."))
n = floor(Integer,log(a, x))
p = a^(n+1)
p <= x ? p : a^n
Expand Down
2 changes: 0 additions & 2 deletions doc/src/base/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ Base.gcd
Base.lcm
Base.gcdx
Base.ispow2
Base.nextpow2
Base.prevpow2
Base.nextpow
Base.prevpow
Base.nextprod
Expand Down
4 changes: 2 additions & 2 deletions stdlib/Random/src/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ randsubseq(A::AbstractArray, p::Real) = randsubseq(GLOBAL_RNG, A, p)
## rand Less Than Masked 52 bits (helper function)

"Return a sampler generating a random `Int` (masked with `mask`) in ``[0, n)``, when `n <= 2^52`."
ltm52(n::Int, mask::Int=nextpow2(n)-1) = LessThan(n-1, Masked(mask, UInt52Raw(Int)))
ltm52(n::Int, mask::Int=nextpow(2, n)-1) = LessThan(n-1, Masked(mask, UInt52Raw(Int)))

## shuffle & shuffle!

Expand Down Expand Up @@ -183,7 +183,7 @@ function shuffle!(r::AbstractRNG, a::AbstractArray)
@assert !has_offset_axes(a)
n = length(a)
@assert n <= Int64(2)^52
mask = nextpow2(n) - 1
mask = nextpow(2, n) - 1
for i = n:-1:2
(mask >> 1) == i && (mask >>= 1)
j = 1 + rand(r, ltm52(i, mask))
Expand Down
3 changes: 1 addition & 2 deletions test/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,13 @@ end
@test powermod(2, -2, -5) == -1
end
@testset "nextpow/prevpow" begin
@test nextpow2(3) == 4
@test nextpow(2, 3) == 4
@test nextpow(2, 4) == 4
@test nextpow(2, 7) == 8
@test_throws DomainError nextpow(0, 3)
@test_throws DomainError nextpow(3, 0)

@test prevpow2(3) == 2
@test prevpow(2, 3) == 2
@test prevpow(2, 4) == 4
@test prevpow(2, 5) == 4
@test_throws DomainError prevpow(0, 3)
Expand Down
23 changes: 12 additions & 11 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1909,20 +1909,21 @@ end
@test rem(typemin(Int),-1) == 0
@test mod(typemin(Int),-1) == 0
end
@testset "prevpow2/nextpow2" begin
@test nextpow2(0) == prevpow2(0) == 0
for i = -2:2
@test nextpow2(i) == prevpow2(i) == i
@testset "prevpow(2, _)/nextpow(2, _)" begin
for i = 1:2
@test nextpow(2, i) == prevpow(2, i) == i
end
@test nextpow2(56789) == -nextpow2(-56789) == 65536
@test prevpow2(56789) == -prevpow2(-56789) == 32768
for i = -100:100
@test nextpow2(i) == nextpow2(big(i))
@test prevpow2(i) == prevpow2(big(i))
@test nextpow(2, 56789) == 65536
@test_throws DomainError nextpow(2, -56789)
@test prevpow(2, 56789) == 32768
@test_throws DomainError prevpow(2, -56789)
for i = 1:100
@test nextpow(2, i) == nextpow(2, big(i))
@test prevpow(2, i) == prevpow(2, big(i))
end
for T in (Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64)
@test nextpow2(T(42)) === T(64)
@test prevpow2(T(42)) === T(32)
@test nextpow(2, T(42)) === T(64)
@test prevpow(2, T(42)) === T(32)
end
end
@testset "ispow2" begin
Expand Down