Skip to content

Commit 056ecdb

Browse files
committed
ispow2(x) for non-Integer x
1 parent 2bd31a0 commit 056ecdb

File tree

7 files changed

+43
-2
lines changed

7 files changed

+43
-2
lines changed

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Standard library changes
9191
by passing a tuple for `dims`, and defaults to reversing all dimensions; there is also a multidimensional
9292
in-place `reverse!(A; dims)` ([#37367]).
9393
* The function `isapprox(x,y)` now accepts the `norm` keyword argument also for numeric (i.e., non-array) arguments `x` and `y` ([#35883]).
94+
* `ispow2(x)` now supports non-`Integer` arguments `x` ([#37635]).
9495
* `view`, `@view`, and `@views` now work on `AbstractString`s, returning a `SubString` when appropriate ([#35879]).
9596
* All `AbstractUnitRange{<:Integer}`s now work with `SubString`, `view`, `@view` and `@views` on strings ([#35879]).
9697
* `sum`, `prod`, `maximum`, and `minimum` now support `init` keyword argument ([#36188], [#35839]).

base/float.jl

+2
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,8 @@ function issubnormal(x::T) where {T<:IEEEFloat}
725725
(y & exponent_mask(T) == 0) & (y & significand_mask(T) != 0)
726726
end
727727

728+
ispow2(x::AbstractFloat) = !iszero(x) && frexp(x)[1] == 0.5
729+
728730
@eval begin
729731
typemin(::Type{Float16}) = $(bitcast(Float16, 0xfc00))
730732
typemax(::Type{Float16}) = $(Inf16)

base/intfuncs.jl

+13-2
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,9 @@ _prevpow2(x::Unsigned) = one(x) << unsigned((sizeof(x)<<3)-leading_zeros(x)-1)
368368
_prevpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -_prevpow2(unsigned(-x)) : _prevpow2(unsigned(x)))
369369

370370
"""
371-
ispow2(n::Integer) -> Bool
371+
ispow2(n::Number) -> Bool
372372
373-
Test whether `n` is a power of two.
373+
Test whether `n` is an integer power of two.
374374
375375
# Examples
376376
```jldoctest
@@ -379,8 +379,19 @@ true
379379
380380
julia> ispow2(5)
381381
false
382+
383+
julia> ispow2(4.5)
384+
false
385+
386+
julia> ispow2(0.25)
387+
true
388+
389+
julia> ispow2(1//8)
390+
true
382391
```
383392
"""
393+
ispow2(x::Number) = isreal(x) && ispow2(real(x))
394+
384395
ispow2(x::Integer) = x > 0 && count_ones(x) == 1
385396

386397
"""

base/rational.jl

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ typemin(::Type{Rational{T}}) where {T<:Integer} = unsafe_rational(T, zero(T), on
262262
typemax(::Type{Rational{T}}) where {T<:Integer} = unsafe_rational(T, one(T), zero(T))
263263

264264
isinteger(x::Rational) = x.den == 1
265+
ispow2(x::Rational) = (x.den == 1 && ispow2(x.num)) || (x.num == 1 && ispow2(x.den))
265266

266267
+(x::Rational) = unsafe_rational(+x.num, x.den)
267268
-(x::Rational) = unsafe_rational(-x.num, x.den)

test/complex.jl

+7
Original file line numberDiff line numberDiff line change
@@ -1187,3 +1187,10 @@ end
11871187

11881188
# complex with non-concrete eltype
11891189
@test_throws ErrorException complex(Union{Complex{Int}, Nothing}[])
1190+
1191+
@testset "ispow2" begin
1192+
@test ispow2(4+0im)
1193+
@test ispow2(0.25+0im)
1194+
@test !ispow2(4+5im)
1195+
@test !ispow2(7+0im)
1196+
end

test/floatfuncs.jl

+11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ end
4040
end
4141
end
4242

43+
@testset "ispow2" begin
44+
for T in (Float16,Float32,Float64,BigFloat)
45+
for x in (0.25, 1.0, 4.0, exp2(T(exponent(floatmax(T)))), exp2(T(exponent(floatmin(T)))))
46+
@test ispow2(T(x))
47+
end
48+
for x in (1.5, 0.0, 7.0, NaN, Inf)
49+
@test !ispow2(T(x))
50+
end
51+
end
52+
end
53+
4354
@testset "round" begin
4455
for elty in (Float32, Float64)
4556
x = rand(elty)

test/rational.jl

+8
Original file line numberDiff line numberDiff line change
@@ -594,3 +594,11 @@ end
594594
@test -1//5 * 0x3//0x2 == 0x3//0x2 * -1//5 == -3//10
595595
@test -2//3 * 0x1 == 0x1 * -2//3 == -2//3
596596
end
597+
598+
599+
@testset "ispow2" begin
600+
@test ispow2(4//1)
601+
@test ispow2(1//8)
602+
@test !ispow2(3//8)
603+
@test !ispow2(0//1)
604+
end

0 commit comments

Comments
 (0)