Posted by
| Nick Gammon
Australia (23,057 posts) Bio
Forum Administrator |
Message
| The Lua language does not contain native support for bit-wise 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" (64-bit 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" (64-bit 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" (64-bit 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" (64-bit signed integers). The result is all arguments "and-ed" 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" (64-bit signed integers). The result is all arguments "or-ed" 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" (64-bit signed integers). The result is all arguments "exclusive or-ed" 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" (64-bit signed integer). The result is the ones-complement 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" (64-bit 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 64-bit 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 52-bit number (the default Lua number conversion will only go to 32-bit 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 64-bit 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 |
|