lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Klaus Ripke wrote:
> Would be nice to agree on common semantics,
> which should apply regardless of whether a function or operator is used.

I've previously posted a patch with a minimal set of 4 functions:

Quoting myself:

  y = math.bitor(x1, x2)

  y = math.bitand(x1 [, x2])   x2 = -1 if omitted (i.e. tobit)

  y = math.bitxor(x1 [, x2])   x2 = -1 if omitted (i.e. bitnot)

  y... = math.bitfield(x, start [, len] ...)
    'start' is the bit position relative to the lsb (bit 0)
    It's a right/left shift for a positive/negative 'start'.
    It's a pure shift if 'len' is omitted.
    Otherwise the result is masked to 'len' valid bits.


  bitand(120.123)                     --> 120
  bitxor(120)                         --> -121
  bitor(0x5aff, 0xa5f0)               --> 0xffff
  bitand(0x5aff, 0xa5f0)              --> 0x00f0
  bitxor(0x5aff, 0xa5f0)              --> 0xff0f
  bitfield(0x345678, 8)               --> 0x3456
  bitfield(0x345678, -8)              --> 0x34567800
  bitfield(0x345678, 8, 8)            --> 0x56
  bitfield(0x345678, -8, 8)           --> 0x7800
  bitfield(0x345678, 3, 10)           --> 0x2cf
  bitfield(0x345678, 0,8, 8,8, 16,8)  --> 0x78 0x56 0x34

But maybe the names should be shorter (band, bor, bxor, ...).
Adding some aliases (bnot, bshift) would come at minimal cost.

Especially the bitfield function solves many practical problems
(shifting, extraction and creation of bitfields). Of course it's
not amenable to be implemented as an operator.

The precision of bit operations is limited by the minimum
precision of lua_Number and lua_Integer (ptrdiff_t). The
practical limit is usually at least 32 bits (only 24 bits when
lua_Number is a float). Bit operations work fine with negative
numbers and may produce negative numbers, too.

> > probably not so easy when one use local bor = bitlib.bor anywhere.
> didn't check right now, but IIRC Mike's JIT can catch those.

Yep, this is no problem. You can pass around the function as
often as you want and it's still recognized and inlined.

There's hardly any speed difference between inlined functions vs.
true operators with LuaJIT. Inlining bitwise functions would be
trivial -- but only if the set of functions is standardized!

Note that the main speed disadvantage of functions vs. operators
(around 5x) in interpreted Lua is due to the call frame setup and
teardown overhead. One way to speed this up would be to add
"frameless" C functions which operate in the frame of the caller.
Especially trivial functions (math.*) would benefit a lot.

It would also settle the operator vs. function discussion (as far
as performance is concerned).