Skip to content

Commit

Permalink
Add bitrotate function (issue #11592) (#33937)
Browse files Browse the repository at this point in the history
  • Loading branch information
anaveragehuman authored Feb 21, 2020
1 parent d8b2209 commit eac7411
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ New library functions
* `include` now accepts an optional `mapexpr` first argument to transform the parsed
expressions before they are evaluated ([#34595]).
* New function `bitreverse` for reversing the order of bits in a fixed-width integer ([#34791]).
* New function `bitrotate(x, k)` for rotating the bits in a fixed-width integer ([#33937]).

New library features
--------------------
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ export
big,
binomial,
bitreverse,
bitrotate,
bswap,
cbrt,
ceil,
Expand Down
29 changes: 29 additions & 0 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,35 @@ for to in BitInteger_types, from in (BitInteger_types..., Bool)
end
end

## integer bitwise rotations ##

"""
bitrotate(x::Base.BitInteger, k::Integer)
`bitrotate(x, k)` implements bitwise rotation.
It returns the value of `x` with its bits rotated left `k` times.
A negative value of `k` will rotate to the right instead.
!!! compat "Julia 1.5"
This function requires Julia 1.5 or later.
```jldoctest
julia> bitrotate(UInt8(114), 2)
0xc9
julia> bitstring(bitrotate(0b01110010, 2))
"11001001"
julia> bitstring(bitrotate(0b01110010, -2))
"10011100"
julia> bitstring(bitrotate(0b01110010, 8))
"01110010"
```
"""
bitrotate(x::T, k::Integer) where {T <: BitInteger} =
(x << ((sizeof(T) << 3 - 1) & k)) | (x >>> ((sizeof(T) << 3 - 1) & -k))

# @doc isn't available when running in Core at this point.
# Tuple syntax for documentation two function signatures at the same time
# doesn't work either at this point.
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Base.denominator
Base.:(<<)
Base.:(>>)
Base.:(>>>)
Base.bitrotate
Base.:(:)
Base.range
Base.OneTo
Expand Down
16 changes: 16 additions & 0 deletions test/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,22 @@ end
end
end
end

@testset "bit rotations" begin
val1 = 0b01100011
@test 0b00011011 === bitrotate(val1, 3)
@test 0b01101100 === bitrotate(val1, -3)
@test val1 === bitrotate(val1, 0)

for T in Base.BitInteger_types
@test val1 === bitrotate(val1, sizeof(T) * 8) === bitrotate(val1, sizeof(T) * -8)
end

val2 = 0xabcd
@test 0x5e6d == bitrotate(val2, 3)
@test 0xb579 == bitrotate(val2, -3)
end

@testset "widen/widemul" begin
@test widen(UInt8(3)) === UInt16(3)
@test widen(UInt16(3)) === UInt32(3)
Expand Down

0 comments on commit eac7411

Please sign in to comment.