lua-users home
lua-l archive

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

Andy Stark wrote:

> Does the type that supports bitwise ops actually have to be the number
> type at all? Perhaps the solution is to extend the string type to allow it
> to behave as a non-textual sequence of bytes.

I have done something very similar with a package I call 'bstring' (bit
string). Unfortunately I never got around to adding the operators, but I
have found it to be useful with bnot, bxor, etc. Bstrings operate like
strings (positive or negative indexes, starting at 1), but the values
they represent are strings of bits, not characters. In a lot of ways,
they behave like normal strings limited to '0' and '1' characters. I
have not updated the package to use the 5.1 module system. Perhaps I can
take that as a challenge and post it on LuaForge.

If you are interested, please let me know off-line and I'll send you the
C source. I have found this code to be EXTREMELY useful in my line of
work (communications). I can manipulate data interactively and write
quick functions to encode and decode messages to see where my C/C++/Ada
code is failing.

Here's some of the interface:

-- These create new bstring objects:
-- C/Lua   Name
--  L  function    -- Argument types select one of...
--  L  function bstring.newdata(binary_string,bit_count)
--  L  function bstring.newtext(ascii_01_string)
--  L  function bstring.newword(word,bits)

-- If 'self' is a bstring, these return a new bstring with the result:
--  L  function bstring.rep(bit_or_bs,])
--  C  function self:band(bs)   -- missing bits are assumed to be 0.
--  C  function self:bor(bs)
--  C  function self:bxor(bs)
--  C  function self:bnot()
--  C  function self:sub(i[,j])         -- 1-based index, negatives ok
--  C  function self:concat(bs/s/n)     -- overload for '..'
--  C  function self:find(bs[,errors])  -- returns start, stop, errors
--  C  function self:zeroinsert([threshold])
--  C  function self:zerodelete([threshold]) -- returns bs, abort_index
--  C  function self:transpose(rows,columns)
--  C  function self:golayencode([options])
--  C  function self:golaydecode([options])  -- returns bs, errors

-- Then there are these:
--  C  function self:equals(other)  -- true if same length/contents
--  C  function self:len()
--  C  function self:data()       -- string data bytes
--  C  function self:bit(index)   -- 0/1/nil for bit at index
--  C  function self:word(i[,j])  -- number at range of indexes
--  C  function self:crc(polynomial,shifter) -- see C code

-- These are useful for examining a bstring object's content:
--  C  function self:tostring() -- return ASCII 0/1 string
--  L  function self:hex()      -- return string with hex escape seqs
--  L  function self:fhex()     -- return formatted hex data string
--  L  function self:dumphex()  -- print(self:fhex())
--  L  function self:bin()      -- return string with ASCII 0/1's
--     function self:fbin()     -- return formatted binary text string
--     function self:dumpbin()  -- print(self:fbin())

-- Each iterator returns indicated item plus indexes of first
-- and last bits in the original bstring, or nil when original
-- bstring is exhausted. Each of these functions returns a
-- function which is the iterator:
--  L  function self:bits()     -- iter() returns next single 0/1
--  L  function self:words()    -- iter(n) returns next n bits as number
--  L  function self:chars([char-width-in-bits])
--                     iter(n) returns next n characters as string
--  L  function self:bstrings()
--                     iter(n) returns next n bits as bstring

> I think the advantages of this approach are that it is easily extended and
> it doesn't force the user to choose between floating point numerics and
> useful bitwise ops.

True, but then eventually you'd have to convert back into a useful
number. There's no getting around the fact that the problem is the lack
of distinction between integer types and floating point types - and the
difference in the behavior of their operators. Sure, this could be done
in some C glue code, but I know for my own applications I would love to
have both - integers for bit twiddling and floating point for
statistics, etc.

No doubt, integer division with math.floor() sucks. The authors will
never add an integer type to the language for the reasons they've
mentioned many times: you can roll your own. It is very unlikely that
you need the speed inside Lua - you'll do time-critical operations
directly in C anyway. So why clutter up the language with another type?

The only thing I could see helping that would possibly be acceptable
would be the definition of the four basic operations - negation, and,
or, and xor. Too bad the keywords 'not', 'and', and 'or' already have
too many (IMHO, clumsy) uses for numbers, otherwise they'd be perfect.

At one point I created a partial Lua mapping to the GMP (GNU Multiple
Precision) library - at least the MPZ portion. That works very well,
too, but I have found it useful only for playing around in number theory
- like testing the counter-examples to Fermat's Last Theorem in the
Simpson's episode "Homer in 3D". I love the way Lua makes it easy to do
these sorts of extensions.


Doug Rogers - ICI - V:703.893.2007x220