3.8 位运算

在计算机中,整数使用二进制数、位序列(零或一的数字)表示。从概念上讲,左边的位序列是无限的,最高有效位全为零或全为 1。按位运算会作用于此类序列的各个位。例如, 位移操作 会将整个序列向左或向右移动一个或多个位置。

Emacs Lisp 中的按位运算仅适用于整数。

Function:ash integer1 count ash(算术移位) 将integer1 中的位向左边移动count 位,如果count为负则向右移动。左移会在右边引入零位;右移则会丢弃最右边的位。视为等价的整数运算, ash将integer1乘以 2 的 count 次方,然后通过向下舍入将结果转换为整数。

以下是ash将位模式向左和向右移动一位的示例。这些示例仅显示二进制模式的低位;前导位都与所示的最高位一致。如您所见,左移一相当于乘以二,而右移一相当于除以二,然后向下舍入取整。

(ash 7 1) ⇒ 14 ;; Decimal 7 becomes decimal 14. …000111 ⇒ …001110

(ash 7 -1) ⇒ 3 …000111 ⇒ …000011

(ash -7 1) ⇒ -14 …111001 ⇒ …110010

(ash -7 -1) ⇒ -4 …111001 ⇒ …111100

以下是向左或向右移动两位的示例:

              ;         binary values

(ash 5 2) ; 5 = …000101 ⇒ 20 ; = …010100 (ash -5 2) ; -5 = …111011 ⇒ -20 ; = …101100 (ash 5 -2) ⇒ 1 ; = …000001 (ash -5 -2) ⇒ -2 ; = …111110

Function:lsh integer1 count lsh,是logic shift的缩写,将integer1左移count位,如果count为负,则右移,使用 0 补位。如果 count为负,则integer1必须是 fixnum 或正的 bignum。此外,lsh 将 fixnum 连减两次 most-negative-fixnum ,将其处理为为无符号数字。这种古怪的行为可以追溯到 Emacs 只支持 fixnums 的时候。现在使用 ash 是更好的选择。

lsh的行为和ash很像,但当 integer1和 count1均为负时,以下的例子仅出现在这些特殊情况下。这些示例假定使用 30 位 fixnums。

             ;      binary values

(ash -7 -1) ; -7 = …111111111111111111111111111001 ⇒ -4 ; = …111111111111111111111111111100 (lsh -7 -1) ⇒ 536870908 ; = …011111111111111111111111111100 (ash -5 -2) ; -5 = …111111111111111111111111111011 ⇒ -2 ; = …111111111111111111111111111110 (lsh -5 -2) ⇒ 268435454 ; = …001111111111111111111111111110

Function:logand &rest ints-or-markers 此函数将参数进行按位与操作。

例如,使用 4 位二进制数,13 和 12 按位 与 结果为 12:1101 与 1100 按位 与 的 1100。在这两个二进制数中,最左边的两位都是 1,因此返回值的最左边的两位都是 1。但是,对于最右边的两位,其中一个参数是 0,因此返回值的最右边两位都是 0。

因此,

(logand 13 12) ⇒ 12 如果logand未传递任何参数,则返回值 -1。这个是一个logand的单位数字,因为它的二进制表示完全由 1 组成。如果只传递一个参数,则返回该参数。

               ;        binary values

(logand 14 13) ; 14 = …001110 ; 13 = …001101 ⇒ 12 ; 12 = …001100

(logand 14 13 4) ; 14 = …001110 ; 13 = …001101 ; 4 = …000100 ⇒ 4 ; 4 = …000100

(logand) ⇒ -1 ; -1 = …111111

Function:logior &rest ints-or-markers 该函数对参数进行按位或运算。如果没有参数,则结果为 0,这是此操作的恒定元素。如果只传递一个参数,则返回该参数。

               ;        binary values

(logior 12 5) ; 12 = …001100 ; 5 = …000101 ⇒ 13 ; 13 = …001101

(logior 12 5 7) ; 12 = …001100 ; 5 = …000101 ; 7 = …000111 ⇒ 15 ; 15 = …001111

Function:logxor &rest ints-or-markers 此函数将参数按位异或。如果没有参数,则结果为 0,这是此操作的恒定元素。如果只传递一个参数,则返回该参数。

               ;        binary values

(logxor 12 5) ; 12 = …001100 ; 5 = …000101 ⇒ 9 ; 9 = …001001

(logxor 12 5 7) ; 12 = …001100 ; 5 = …000101 ; 7 = …000111 ⇒ 14 ; 14 = …001110

Function:lognot integer 此函数将参数按位补码。结果和整数 -1 等价。

(lognot 5) ⇒ -6 ;; 5 = …000101 ;; becomes ;; -6 = …111010

Function:logcount integer 该函数返回整数的汉明权重:在那些的二进制表示的数量的整数。如果integer为负数,则返回其二进制补码表示中的零位数。结果总是非负的。

(logcount 43) ; 43 = …000101011 ⇒ 4 (logcount -43) ; -43 = …111010101 ⇒ 3

最后更新于