Next: Math Functions, Previous: Rounding Operations, Up: Numbers [Contents][Index]
コンピューターの中では、整数はビット(bit: 0か1の数字)のシーケンスである2進数で表されます。ビット演算は、そのようなシーケンスの中の個々のビットに作用します。たとえばシフト(shifting)はシーケンス全体を1つ以上左または右に移動して、移動されたのと同じパターンを再現します。
Emacs Lispのビット演算は整数だけに適用されます。
lsh
はlogical
shiftの略で、integer1のビットを左にcount個シフトする。countが負なら右にシフトし、シフトにより空きになったビットには0がセットされる。countが負ならlsh
は左端(最上位)に0をシフトするので、integer1が負の場合でも正の結果が生成される。これと対照的なのが以下で説明するash
である。
以下はlsh
でビットパターンの位置を1つ左にシフトする例である。ここでは下位8ビットの2進パターンだけを表示しており、残りのビットはすべて0である。
(lsh 5 1) ⇒ 10 ;; 10進の5が10進の10になる 00000101 ⇒ 00001010 (lsh 7 1) ⇒ 14 ;; 10進の7は10進の14になる 00000111 ⇒ 00001110
この例が示すように、ビットパターンを左に1シフトすると、生成される数は元の数の2倍になる。
ビットパターンを左に2シフトすると、以下の結果が生成される(8ビット2進数):
(lsh 3 2)
⇒ 12
;; 10進の3が10進の12になる
00000011 ⇒ 00001100
一方、右に1シフトすると以下のようになる:
(lsh 6 -1)
⇒ 3
;; 10進の6は10進の3になる
00000110 ⇒ 00000011
(lsh 5 -1)
⇒ 2
;; 10進の5は10進の2になる
00000101 ⇒ 00000010
例で明らかなように右に1シフトすることにより、正の整数の値が2で除され下方に丸められる。
関数lsh
は他のEmacs
Lisp算術関数と同様、オーバーフローをチェックしないので、左にシフトすることにより上位ビットが捨てられ、その数の符号が変化するかもしれない。たとえば30ビットの実装では、536,870,911を左にシフトすると-2が生成されます。
(lsh 536870911 1) ; 左シフト
⇒ -2
2進ではこの引数は以下のようになる:
;; 10進の536,870,911
0111...111111 (全部で30ビット)
これを左にシフトすると以下のようになる:
;; 10進の-2
1111...111110 (全部で30ビット)
ash
(算術シフト(arithmetic
shift))は、integer1の中のビット位置を左にcountシフトする。countが負なら右にシフトする。
ash
はlsh
と同じ結果を与えるが、例外はinteger1とcountがいずれも負の場合である。この場合、lsh
は左にできる空きビットに0、ash
は1を置く。
したがってash
でビットパターンの位置を右に1シフトすると以下のようになる:
(ash -6 -1) ⇒ -3
;; 10進の-6は10進の-3になる
1111...111010 (30 bits total)
⇒
1111...111101 (30 bits total)
対照的に、lsh
でビットパターンの位置を1右にシフトすると以下のようになる:
(lsh -6 -1) ⇒ 536870909
;; 10進の-6は10進の536,870,909になる
1111...111010 (30 bits total)
⇒
0111...111101 (30 bits total)
他にも例を示す:
; 30ビットの2進数 (lsh 5 2) ; 5 = 0000...000101 ⇒ 20 ; = 0000...010100
(ash 5 2) ⇒ 20 (lsh -5 2) ; -5 = 1111...111011 ⇒ -20 ; = 1111...101100 (ash -5 2) ⇒ -20
(lsh 5 -2) ; 5 = 0000...000101 ⇒ 1 ; = 0000...000001
(ash 5 -2) ⇒ 1
(lsh -5 -2) ; -5 = 1111...111011 ⇒ 268435454 ; = 0011...111110
(ash -5 -2) ; -5 = 1111...111011 ⇒ -2 ; = 1111...111110
この関数は引数のビットのANDをリターンする。すべての引数のn番目のビットが1の場合に限り、結果のn番目のビットが1となる。
たとえば13と12では、4ビット2進数を使用すると1101と1100のビットANDは1100を生成する。この2進数ではいずれも左の2ビットがセット(つまり1)されているので、リターンされる値の左2ビットがセットされる。しかし右の2ビットにたいしては少なくとも1つの引数でそのビットが0なので、リターンされる値の右2ビットは0になる。
したがって、
(logand 13 12) ⇒ 12
logand
に何も引数も渡さなければ、値-1がリターンされる。-1を2進数で表すとすべてのビットが1なので、-1はlogand
にたいする単位元(identity
element)である。
; 30ビット2進数 (logand 14 13) ; 14 = 0000...001110 ; 13 = 0000...001101 ⇒ 12 ; 12 = 0000...001100
(logand 14 13 4) ; 14 = 0000...001110 ; 13 = 0000...001101 ; 4 = 0000...000100 ⇒ 4 ; 4 = 0000...000100
(logand)
⇒ -1 ; -1 = 1111...111111
この関数は、引数のビット単位の包含的ORをリターンする。少なくとも1つの引数でn番目のビットが1なら、結果のn番目のビットが1になる。引数を与えなければ、結果はこの処理にたいする単位元である0となる。logior
に渡す引数が1つだけならその引数がリターンされる。
; 30ビット2進数 (logior 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 13 ; 13 = 0000...001101
(logior 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 15 ; 15 = 0000...001111
この関数は、引数のビット単位の排他的ORをリターンする。n番目のビットが1であるような引数の数が奇数個の場合のみ、結果のn番目のビットが1となる。引数を与えなければ、結果はこの処理の単位元である0となる。logxor
に渡す引数が1つだけならその引数がリターンされる。
; 30ビット2進数 (logxor 12 5) ; 12 = 0000...001100 ; 5 = 0000...000101 ⇒ 9 ; 9 = 0000...001001
(logxor 12 5 7) ; 12 = 0000...001100 ; 5 = 0000...000101 ; 7 = 0000...000111 ⇒ 14 ; 14 = 0000...001110
この関数は引数のビット単位の補数(bitwise complement)をリターンする。integerのn番目のビットが0の場合に限り、結果のn番目のビットが1になり、その逆も成り立つ。
(lognot 5) ⇒ -6 ;; 5 = 0000...000101 (全部で30ビット) ;; becomes ;; -6 = 1111...111010 (全部で30ビット)
Next: Math Functions, Previous: Rounding Operations, Up: Numbers [Contents][Index]