Posted by
 Nick Gammon
Australia (23,057 posts) Bio
Forum Administrator 
Message
 The Lua language does not contain native support for bitwise manipulation of numbers (and, or, exclusive or etc.)
As a programmer, I feel uneasy if I can't do things like an 'exclusive or', so MUSHclient has a few simple extensions that permit that.
They are in the library (table) "bit". The following operations are supported:
 shr  shift right
This takes two arguments. Both are converted to "long long" (64bit unsigned integers). The first argument is shifted right the number of bits in the second argument.
eg.
print (bit.shr (1024, 6)) > 16
 ashr  arithmetic shift right
This takes two arguments. Both are converted to "long long" (64bit signed integers). The first argument is shifted right the number of bits in the second argument, however preserving the sign bit. You would use this to divide by a power of two, retaining the sign.
eg.
print (bit.ashr (1024, 6)) > 16
 shl  shift left
This takes two arguments. Both are converted to "long long" (64bit signed integers). The first argument is shifted left the number of bits in the second argument.
eg.
print (bit.shl (4, 6)) > 256
 band  bitwise "and"
This takes one or more arguments. All are converted to "long long" (64bit signed integers). The result is all arguments "anded" together bitwise.
eg.
print (bit.band (15, 7, 3)) > 3
 bor  bitwise "or"
This takes one or more arguments. All are converted to "long long" (64bit signed integers). The result is all arguments "ored" together bitwise.
eg.
print (bit.bor (1, 2, 8)) > 11
 xor  bitwise "exclusive or"
This takes one or more arguments. All are converted to "long long" (64bit signed integers). The result is all arguments "exclusive ored" together bitwise.
eg.
print (bit.xor (15, 1)) > 14
 neg  bitwise "negate" (ones complement)
This takes one argument. It is converted to an "long long" (64bit signed integer). The result is the onescomplement of the number (zero bits become one, one bits become zero).
eg.
print (bit.neg (1)) > 4294967294
 mod  integer "modulus"
This takes two arguments. Both are converted to "long long" (64bit signed integers). The result is the modulus (remainder) after dividing the first by the second.
eg.
print (bit.mod (16, 9)) > 7
 tostring  convert a number to a string in any base up to 36.
This takes a number, and converts it into a string to the given base, in uppercase. The base is optional and defaults to 10. The base can be in the range 2 to 36. Fractional parts are discarded, as the number is first converted to a 64bit number internally. Negative numbers are OK, and will be converted with a leading "" sign.
eg.
print (bit.tostring (45035996273, 16)) > A7C5AC471
This is similar to the standard Lua "tostring" function, except that it does not invoke metamethods (that is, the __tostring metamethod), and also allows you to specify a base, unlike the standard function.
 tonumber  convert a string in any base up to 36 to a number
This takes a string, and converts it into a number.
Unlike the standard Lua tonumber function this function will handle up to a 52bit number (the default Lua number conversion will only go to 32bit numbers).
eg.
print (bit.tonumber ("A7C5AC471", 16)) > 45035996273
The base is optional and defaults to 10. The base can be in the range 2 to 36. Fractional numbers are not supported, nor are numbers with exponents (eg. 10.24e15). For such numbers use the standard Lua "tonumber" function.
Because of limitations in the size of a floating point number, the maximum string value that can be converted is a 52 bit number, ie: hex FFFFFFFFFFFFF (decimal 4503599627370495).
Leading whitespace is skipped. After that, there can be an optional + or  sign.
The bitwise operations are now conducted after converting the internal "double" (floating point) Lua numbers into 64bit integers. Internally doubles are stored as 64 bits: 1 for sign, 11 for the exponent, and 52 for the mantissa. Their range is +/–1.7E308 with at least 15 digits of precision.
Since the mantissa of the double has 52 bits, the bitwise operations should be reliable to around 52 bits.
Also consider the "bc" (big number) library, described in this post:
http://www.gammon.com.au/forum/?id=7747
The bc library allows you to work with numbers of any precision (eg. 1000 decimal places).

 Nick Gammon
www.gammon.com.au, www.mushclient.com  Top 
