Skip to content

Instantly share code, notes, and snippets.

@ggcrunchy
Created January 24, 2020 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggcrunchy/2122165d326ab22c53cfca0db5945dd1 to your computer and use it in GitHub Desktop.
Save ggcrunchy/2122165d326ab22c53cfca0db5945dd1 to your computer and use it in GitHub Desktop.
Integer division using "bitwise ops", long division approach instead of iterated subtraction
-- Tested on repl.it
local N = 8 -- or 16, etc. Could also adapt for fixed point
local lshift = math.ldexp
local HighBitMask = lshift(1, N - 1)
local function Div (a, b)
local acc, result = 0, 0
local mask = HighBitMask -- one-hot mask
for _ = 1, N do
result = 2 * result -- left shift
-- will be 0 on first pass
-- avoids over-shift at end
if a >= mask then -- bit set?
a = a - mask -- clear bit (since using >= operator)
acc = acc + 1 -- or in 1 bit
end
if acc >= b then
acc = acc - b
result = result + 1 -- or in 1 bit
end
acc = 2 * acc -- left shift
mask = .5 * mask -- right shift
end
return result
end
local NN = 0
local function Print (a, b)
if NN < 100 then
print("Discrepancy at", a, ", ", b)
NN = NN + 1
end
end
local floor = math.floor
for a = 0, 255 do
for b = 1, 255 do
if Div(a, b) ~= floor(a / b) then
Print(a, b)
end
end
end
print(NN > 0 and "Finished with problems" or "OK!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment