= rshift(j, 5)
p[jx] = band(p[jx], rol(-2, j))
end
end
end
io.write(string.format("Found %d primes up to %d\n", count, m))
<
Lua BitOp is quite fast. This program runs in less than 90 milliseconds on a 3
GHz CPU with a standard Lua installation, but performs more than a million
calls to bitwise functions. If you're looking for even more speed, check out
|lua-luajit|.
------------------------------------------------------------------------------
Caveats *lua-bit-caveats*
Signed Results ~
Returning signed numbers from bitwise operations may be surprising to
programmers coming from other programming languages which have both signed and
unsigned types. But as long as you treat the results of bitwise operations
uniformly everywhere, this shouldn't cause any problems.
Preferably format results with `bit.tohex` if you want a reliable unsigned
string representation. Avoid the `"%x"` or `"%u"` formats for `string.format`. They
fail on some architectures for negative numbers and can return more than 8 hex
digits on others.
You may also want to avoid the default number to string coercion, since this
is a signed conversion. The coercion is used for string concatenation and all
standard library functions which accept string arguments (such as `print()` or
`io.write()`).
Conditionals ~
If you're transcribing some code from C/C++, watch out for bit operations in
conditionals. In C/C++ any non-zero value is implicitly considered as `true`.
E.g. this C code: >c
if (x & 3) ...
<
must not be turned into this Lua code: >lua
if band(x, 3) then ... -- wrong!
<
In Lua all objects except `nil` and `false` are considered `true`. This
includes all numbers. An explicit comparison against zero is required in this
case: >lua
if band(x, 3) ~= 0 then ... -- correct!
Comparing Against Hex Literals ~
Comparing the results of bitwise operations (signed numbers) against hex
literals (unsigned numbers) needs some additional care. The following
conditional expression may or may not work right, depending on the platform
you run it on: >lua
bit.bor(x, 1) == 0xffffffff
<
E.g. it's never true on a Lua installation with the default number type. Some
simple solutions:
Never use hex literals larger than 0x7fffffff in comparisons: >lua
bit.bor(x, 1) == -1
<
Or convert them with bit.tobit() before comparing: >lua
bit.bor(x, 1) == bit.tobit(0xffffffff)
<
Or use a generic workaround with bit.bxor(): >lua
bit.bxor(bit.bor(x, 1), 0xffffffff) == 0
<
Or use a case-specific workaround: >lua
bit.rshift(x, 1) == 0x7fffffff
<
==============================================================================
OPERATIONAL SEMANTICS AND RATIONALE *lua-bit-semantics*
Input and Output Ranges ~
*lua-bit-io-ranges*
Bitwise operations cannot sensibly be applied to FP numbers (or their
underlying bit patterns). They must be converted to integers before operating
on them and then back to FP numbers.
It's desirable to define semantics that work the same across all platforms.
This dictates that all operations are based on the common denominator of 32
bit integers. The `float` type provides only 24 bits of precision. This makes it
unsuitable for use in bitwise operations. Lua BitOp refuses to compile against
a Lua installation with this number type.
Bit operations only deal with the underlying bit patterns and generally ignore
signedness (except for arithmetic right-shift). They are commonly displayed
and treated like unsigned numbers, though.
But the Lua number type must be signed and may be limited to 32 bits. Defining
the result type as an unsigned number would not be cross-platform safe. All
bit operations are thus defined to return results in the range of signed 32
bit numbers (converted to the Lua number type).