Lua BitOp 提供5.1和5.2版本位操作運算 (跨平臺C語言實現 說明部分1)
Lua BitOp is a C extension module for Lua 5.1/5.2 which adds bitwise operations on numbers.
Features 特點:
支援的位運算子:
Supported functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap
16位 32位 64位操作平臺
Consistent semantics across 16, 32 and 64 bit platforms.
支援LUA Number的型別
Supports different lua_Number types: either IEEE 754 doubles, int32_t or int64_t.
執行的作業系統
Runs on Linux, *BSD, Mac OS X, Windows and probably anything else you can find.
Compatible with the built-in bitwise operations in LuaJIT 2.0.
It's as fast as you can get with the standard Lua/C API.
BitOp
Lua uses only a single number type which can be redefined at compile-time.
By default this is a double, i.e. a floating-point number with 53 bits of precision.
Operations in the range of 32 bit numbers (and beyond) are exact.
There is no loss of precision, so there is no need to add an extra integer number type.
Modern desktop and server CPUs have fast floating-point hardware — FP arithmetic is nearly the same speed as integer arithmetic.
Any differences vanish under the overhead of the Lua interpreter itself.
Even today, many embedded systems lack support for fast FP operations.
These systems benefit from compiling Lua with an integer number type (with 32 bits or more).
The different possible number types and the use of FP numbers cause some problems when defining bitwise operations on Lua numbers.
The following sections define the operational semantics and try to explain the rationale behind them.
LUA語言僅僅使用一種數字型別。並且可以在編譯前重新定義。
預設情況下,LUA使用Double型別作為LUA Number的實現。Double型別有53位精度。
操作32位範圍內的數字是精確的。所有,沒有必須增加額外的整數型別。
現在桌面和伺服器CPU都有很快操作float-point硬體。Float-point 速度和整數計算速度相當。
甚至在今天,許多嵌入式系統缺少對float-pointer型別支援。這些作業系統使用整數作為Lua Number來受益。
但是,使用Float-Point作為Lua Number型別導致位操作問題。
Input and Output Ranges
1、
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.
位操作符不能直接在Float-Point型別上面使用或者Float-Point型別的二進位制上面使用。
在使用Float-Point或者Float-Point二進位制時,必須把他們轉換換成整數。位操作完成後再轉換成Float-Point.
2、
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.
使用32位整數可以跨所有作業系統。
3、
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.
float型別提供24位精度。float不太適合作為位運算。同時,LUA BitOp不使用float作為Lua Number的實現。
4、
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.
位操作運算子把位模式看做無符號型別。(在右移動時,符號位沒有被忽略)
5、
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).
LUA Number型別必須是有符號型別同時被限制至少32位。如果重新定位LUA Number作為無符號型別將不能跨平臺。
所有位運算必須被定義為返回值為至少32位有符號型別。
6、
Hexadecimal literals are treated as unsigned numbers by the Lua parser before converting them to the Lua number type.
This means they can be out of the range of signed 32 bit integers if the Lua number type has a greater range.
E.g. 0xffffffff has a value of 4294967295 in the default installation, but may be -1 on embedded systems.
當LUA解析16進位制常量時,數值在被轉換成Lua Number前被認為無符號型別。
這就意味著返回值可能是超過32位有符號的範圍。例如:0xffffffff預設情況下位2^32,但是在嵌入式系統中可能為-1;
7、
It's highly desirable that hex literals are treated uniformly across systems when used in bitwise operations.
All bit operations accept arguments in the signed or the unsigned 32 bit range (and more, see below).
Numbers with the same underlying bit pattern are treated the same by all operations.
16進位制在所有平臺上使用位操作時必須被統一。所有位操作符文必須接受32位有符號型別或無符號型別。
LUA Number型別的所有位操作必須被統一對待。
Modular Arithmetic
Arithmetic operations on n-bit integers are usually based on the rules of modular arithmetic modulo 2n.
Numbers wrap around when the mathematical result of operations is outside their defined range.
This simplifies hardware implementations and some algorithms actually require this behavior (like many cryptographic functions).
E.g. for 32 bit integers the following holds: 0xffffffff + 1 = 0
Arithmetic modulo 232 is trivially available if the Lua number type is a 32 bit integer.
Otherwise normalization steps must be inserted.
Modular arithmetic should work the same across all platforms as far as possible:
1、
For the default number type of double, arguments can be in the range of ±2^51 and still be safely normalized across all platforms by taking their least-significant 32 bits.
The limit is derived from the way doubles are converted to integers.
2、
?The function bit.tobit can be used to explicitly normalize numbers to implement modular addition or subtraction.
E.g. bit.tobit(0xffffffff + 1) returns 0 on all platforms.
3、?The limit on the argument range implies that modular multiplication is usually restricted to multiplying already normalized numbers with small constants. FP numbers are limited to 53 bits of precision, anyway.
E.g. (2^30+1)2 does not return an odd number when computed with doubles.
Restricted and Undefined Behavior
The following rules are intended to give a precise and useful definition (for the programmer).
yet give the implementation (interpreter and compiler) the maximum flexibility and the freedom to apply advanced optimizations.
It's strongly advised not to rely on undefined or implementation-defined behavior.
下面規則主要為了使用者可以確定精度和使用者行為。同時直譯器和編譯器也沒有提供實現。這樣使用者可以擁有最大化的自由去提高優化。
All kinds of floating-point numbers are acceptable to the bitwise operations.
None of them cause an error, but some may invoke undefined behavior:
1、-0 is treated the same as +0 on input and is never returned as a result.
2、Passing ±Inf, NaN or numbers outside the range of ±251 as input yields an undefined result.
3、Non-integral numbers may be rounded or truncated in an implementation-defined way.
This means the result could differ between different BitOp versions, different Lua VMs, on different platforms or even between interpreted vs. compiled code
所有的Float-Point型別都可以接受位操作運算。但是偽操作運算不會引起操作,但是位操作運算的結果是不確定的。
1、-0和+0都可以作為引數,但是不能作為返回值。
2、解析 ±Inf, NaN 時超過2^51位返回結果將是未定義的。
Avoid passing fractional numbers to bitwise functions. Use math.floor() or math.ceil() to get defined behavior.
當為了避免位操作法時Float-Point型別時,可以通過math.floor() or math.ceil() 來獲取整數部分來實現定義的行為。