Skip to content

Commit 7820894

Browse files
committed
Add bitwise rotate functions
1 parent c4e2941 commit 7820894

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

bint.lua

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ wordbits = wordbits or 32
134134

135135
-- Memoize bint modules
136136
local memoindex = bits * 64 + wordbits
137-
if memo[memoindex] then return memo[memoindex] end
137+
if memo[memoindex] then
138+
return memo[memoindex]
139+
end
138140

139141
-- Validate
140142
assert(bits % wordbits == 0, 'bitsize is not multiple of word bitsize')
@@ -725,10 +727,10 @@ end
725727
-- Bitwise right shift words of a bint (in-place). Used only internally.
726728
function bint:_shrwords(n)
727729
if n < BINT_SIZE then
728-
for i=1,BINT_SIZE-n+1 do
730+
for i=1,BINT_SIZE-n do
729731
self[i] = self[i + n]
730732
end
731-
for i=BINT_SIZE-n,BINT_SIZE do
733+
for i=BINT_SIZE-n+1,BINT_SIZE do
732734
self[i] = 0
733735
end
734736
else
@@ -851,6 +853,34 @@ function bint.bwrap(x, y)
851853
end
852854
end
853855

856+
-- Rotate left integer x by y bits considering bints.
857+
-- @param x A bint or a lua integer.
858+
-- @param y Number of bits to rotate.
859+
function bint.brol(x, y)
860+
x, y = bint_assert_convert(x), bint_assert_tointeger(y)
861+
if y > 0 then
862+
return (x << y) | (x >> (BINT_BITS - y))
863+
elseif y < 0 then
864+
return x:bror(-y)
865+
else
866+
return x
867+
end
868+
end
869+
870+
-- Rotate right integer x by y bits considering bints.
871+
-- @param x A bint or a lua integer.
872+
-- @param y Number of bits to rotate.
873+
function bint.bror(x, y)
874+
x, y = bint_assert_convert(x), bint_assert_tointeger(y)
875+
if y > 0 then
876+
return (x >> y) | (x << (BINT_BITS - y))
877+
elseif y < 0 then
878+
return x:brol(-y)
879+
else
880+
return x
881+
end
882+
end
883+
854884
--- Truncate a number to a bint.
855885
-- Floats numbers are truncated, that is, the fractional port is discarded.
856886
-- @param x A number to truncate.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2282,7 +2282,7 @@ <h2 class="section-header "><a name="Fields"></a>Fields</h2>
22822282
</div> <!-- id="main" -->
22832283
<div id="about">
22842284
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
2285-
<i style="float:right;">Last updated 2020-07-10 09:41:24 </i>
2285+
<i style="float:right;">Last updated 2020-07-10 10:21:42 </i>
22862286
</div> <!-- id="about" -->
22872287
</div> <!-- id="container" -->
22882288
</body>

tests.lua

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
local function test(bits)
2-
local bint = require 'bint'(bits)
1+
local function test(bits, wordbits)
2+
local bint = require 'bint'(bits, wordbits)
33

44
local function assert_eq(a , b)
55
if a ~= b then --luacov:disable
@@ -340,6 +340,12 @@ local function test(bits)
340340
local function test_shr(x, y)
341341
assert_eq((bint(x) >> y):tointeger(), x >> y)
342342
end
343+
local function test_brol(x, y)
344+
assert_eq(bint(x):brol(y):tointeger(), (x << y) | (x >> (64 - y)))
345+
end
346+
local function test_bror(x, y)
347+
assert_eq(bint(x):bror(y):tointeger(), (x >> y) | (x << (64 - y)))
348+
end
343349
local function test_shlone(x)
344350
assert_eq(bint(x):_shlone():tointeger(), x << 1)
345351
end
@@ -355,6 +361,10 @@ local function test(bits)
355361
test_bwrap(x, y) test_bwrap(x, -y) test_bwrap(-x, y)
356362
test_shlone(x) test_shlone(y)
357363
test_shrone(x) test_shrone(y)
364+
if bits == 64 then
365+
test_brol(x, y)
366+
test_bror(x, y)
367+
end
358368
end
359369
test_ops(0, 0)
360370
test_ops(1, 0)
@@ -413,6 +423,10 @@ local function test(bits)
413423
test_ops( 524288, 19)
414424
test_ops(1048576, 20)
415425
test_ops(1048576, 100)
426+
assert_eq(bint.brol(1, -1), bint.mininteger())
427+
assert_eq(bint.bror(1, 1), bint.mininteger())
428+
assert_eq(bint.brol(bint.mininteger(), 1), bint(1))
429+
assert_eq(bint.bror(bint.mininteger(), -1), bint(1))
416430
end
417431

418432
do -- pow

0 commit comments

Comments
 (0)