Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Bit manipulation

Bit manipulation

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,057 posts)  Bio   Forum Administrator
Date Wed 24 Nov 2004 08:33 AM (UTC)

Amended on Thu 19 Apr 2007 04:03 AM (UTC) by Nick Gammon

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

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


17,222 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.