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

Add ror and rol functions for rotating bits #33937

Merged
merged 1 commit into from
Feb 21, 2020
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
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
StefanKarpinski marked this conversation as resolved.
Show resolved Hide resolved
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