Bit.ror and bit.rshift difference?

I’m getting into bitwise operations, but google won’t help me. It makes quite a lot of sense to handle chords and scales with bit operations, easily inverting chords by bit shifting and whatnot.

What is the difference of bit.ror and bit.rshift? I tried to use bit.ror(n, 1) in the hopes that the very least significant bit would rotate to the most significant (16-bit?), which isn’t the case. Bit.ror(n,1) seems to omit the first bit just like rshift does, not really rotating at all. Maybe someone could clarify a bit?

PS. I figured a while loop using bit.ror would be a clever/simple way of identifying the position of the first bit being set.

Tried:

print(bit.ror(1,1))
-2147483648

and

print(bit.rshift(1,1))
0

Looks more like a 32-bit (signed) (not 16-bit) shift/rotate operation(?)

(If I wanted to detect if the first bit is set (i.e. if the number is odd or even) I’d probably ‘bit and’ the value with 1.)

print(bit.band(1,1))
1
print(bit.band(4,1))
0
print(bit.band(7,1))
1
print(bit.band(36,1))
0

(So long as the number is < 2147483648 as it seems to be signed.)

Thanks 4tey!

Yes, now it seems to work just fine. I’m pretty sure I had a brain bug yesterday.

Ahh… bit.band of course. Even simpler :slight_smile:

EDIT:
I did it like this… apparently there is a more compact way, using log 2, but I wanted to avoid that.

Summary
bit.firstone = function(val)

  if val == 0 then return 0 end
  
  local i, bin_i = 0, 1

  while bit.bor(val, bin_i) ~= val do
    i = i + 1
    bin_i = bit.lshift(1, i)
  end

  return i+1
end


for i = 1, 1024 do
 print(tostring(i) .. ": " .. bit.firstone(i))
end

Now, all I need is a way to bitrotate with only 12 bits as a “range”, which doesn’t seem trivial (?). In C++, I’ve heard they use bitfields for doing something like that.

Now, all I need is a way to bitrotate with only 12 bits as a “range”, which doesn’t seem trivial

If you’re only rotating right, my first instinct would be:

  1. AND with 0xfff to be doubly sure you only have your lower 12 bits (optional but good)
  2. Copy that to a temporary variable, and shift left by 12 bits
  3. OR both variables together
  4. Do your shifting/rotating with this new number
  5. AND with 0xfff again to clean up

I’m not sure how to do that in Lua exactly, but in plain English, for a 12 bit number e.g. 0x13c, steps 2 & 3 would turn that to 0x13c13c, then shifting right by e.g. 4 would get you 0x13c13, and then you can AND away the higher bits and get 0xc13. You may or may not need that temporary variable, it was mostly to make the explanation easier.

There are probably more efficient ways to do it but that’s what comes to mind first: rather than think of it as a need to rotate within a range, repeat your data and then enforce your range after the fact.

Thanks a lot! AND to the rescue. Yes, I’ll add modulo and make it possible to rotate both ways.