Skip to content

Commit 81623fa

Browse files
anaveragehumanKristofferC
authored andcommitted
Add bitrotate function (issue #11592) (#33937)
1 parent e0f5238 commit 81623fa

File tree

5 files changed

+48
-0
lines changed

5 files changed

+48
-0
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ New library functions
5656
* `include` now accepts an optional `mapexpr` first argument to transform the parsed
5757
expressions before they are evaluated ([#34595]).
5858
* New function `bitreverse` for reversing the order of bits in a fixed-width integer ([#34791]).
59+
* New function `bitrotate(x, k)` for rotating the bits in a fixed-width integer ([#33937]).
5960

6061
New library features
6162
--------------------

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ export
221221
big,
222222
binomial,
223223
bitreverse,
224+
bitrotate,
224225
bswap,
225226
cbrt,
226227
ceil,

base/int.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,35 @@ for to in BitInteger_types, from in (BitInteger_types..., Bool)
452452
end
453453
end
454454

455+
## integer bitwise rotations ##
456+
457+
"""
458+
bitrotate(x::Base.BitInteger, k::Integer)
459+
460+
`bitrotate(x, k)` implements bitwise rotation.
461+
It returns the value of `x` with its bits rotated left `k` times.
462+
A negative value of `k` will rotate to the right instead.
463+
464+
!!! compat "Julia 1.5"
465+
This function requires Julia 1.5 or later.
466+
467+
```jldoctest
468+
julia> bitrotate(UInt8(114), 2)
469+
0xc9
470+
471+
julia> bitstring(bitrotate(0b01110010, 2))
472+
"11001001"
473+
474+
julia> bitstring(bitrotate(0b01110010, -2))
475+
"10011100"
476+
477+
julia> bitstring(bitrotate(0b01110010, 8))
478+
"01110010"
479+
```
480+
"""
481+
bitrotate(x::T, k::Integer) where {T <: BitInteger} =
482+
(x << ((sizeof(T) << 3 - 1) & k)) | (x >>> ((sizeof(T) << 3 - 1) & -k))
483+
455484
# @doc isn't available when running in Core at this point.
456485
# Tuple syntax for documentation two function signatures at the same time
457486
# doesn't work either at this point.

doc/src/base/math.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Base.denominator
3232
Base.:(<<)
3333
Base.:(>>)
3434
Base.:(>>>)
35+
Base.bitrotate
3536
Base.:(:)
3637
Base.range
3738
Base.OneTo

test/int.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,22 @@ end
190190
end
191191
end
192192
end
193+
194+
@testset "bit rotations" begin
195+
val1 = 0b01100011
196+
@test 0b00011011 === bitrotate(val1, 3)
197+
@test 0b01101100 === bitrotate(val1, -3)
198+
@test val1 === bitrotate(val1, 0)
199+
200+
for T in Base.BitInteger_types
201+
@test val1 === bitrotate(val1, sizeof(T) * 8) === bitrotate(val1, sizeof(T) * -8)
202+
end
203+
204+
val2 = 0xabcd
205+
@test 0x5e6d == bitrotate(val2, 3)
206+
@test 0xb579 == bitrotate(val2, -3)
207+
end
208+
193209
@testset "widen/widemul" begin
194210
@test widen(UInt8(3)) === UInt16(3)
195211
@test widen(UInt16(3)) === UInt32(3)

0 commit comments

Comments
 (0)