Skip to content

Commit

Permalink
add bitrotate (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthias314 authored Sep 16, 2024
1 parent deb17db commit 45f80a5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/BitIntegers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module BitIntegers

import Base: &, *, +, -, <, <<, <=, ==, >>, >>>, |, ~, AbstractFloat, add_with_overflow,
bitrotate,
bitstring, bswap, checked_abs, count_ones, div, flipsign, isodd, leading_zeros,
mod, mul_with_overflow, ndigits0zpb, peek, promote_rule, read, rem, signed,
sub_with_overflow, trailing_zeros, typemax, typemin, unsigned, write, xor
Expand Down Expand Up @@ -358,6 +359,12 @@ end
@inline <<( x::UBI, y::Int) = 0 <= y ? x << unsigned(y) : x >> unsigned(-y)
@inline >>>(x::UBI, y::Int) = 0 <= y ? x >>> unsigned(y) : x << unsigned(-y)

function bitrotate(x::T, k::Integer) where {T<:XBI}
l = (sizeof(T) << 3) % UInt
k::UInt = mod(k, l)
(x << k) | (x >>> (l-k))
end

count_ones( x::XBI) = Int(ctpop_int(x))
leading_zeros( x::XBI) = Int(ctlz_int(x))
trailing_zeros(x::XBI) = Int(cttz_int(x))
Expand Down
16 changes: 16 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,22 @@ end
end


@testset "bit rotations" begin
for X in XInts
x = X(24)
l = 8*sizeof(X)
@test bitrotate(x, 2) == 4*x
@test bitrotate(x, l-1) == div(x, 2)
x = rand(X)
for k in (0, UInt8(13), UInt32(371), Int16(-123), Int64(-1072), BigInt(-21330))
y = @inferred bitrotate(x, k)
@test y isa X && bitrotate(y, k) == bitrotate(x, 2*k)
k isa Signed && @test bitrotate(y, -k) == x
end
end
end


@testset "arithmetic operations" begin
for (X, Y) in TypeCombos
T = promote_type(X, Y)
Expand Down

0 comments on commit 45f80a5

Please sign in to comment.