gauche.bitvector
- ビットベクタユーティリティ ¶このモジュールは、ビットベクタを扱う多くの操作を提供します。
このモジュールの手続きと組み込みのビットベクタ手続きは、SRFI-178のスーパーセットに
なっています (srfi.178
- ビットベクタライブラリ参照)。
Gaucheはビットベクタを組み込みでサポートしていますが、コアで提供されるのは ごく基本的な手続きのみです(ビットベクタ参照)。 このモジュールではビットベクタに対する包括的な操作を提供します。
[SRFI-178]{gauche.bitvector
}
長さlengthのビットベクタを作り、その内容をfを繰り返し呼ぶことで
埋めて行きます。fはseed …に与えられた引数の数よりひとつ多い
引数を取り、同じ数の戻り値を返します。まず、fはインデックスおよびseed …
を引数として呼び出され、戻り値の最初の値(それはビット、すなわち0, 1, 真偽値のいずれかでなければなりません)がビットベクタのインデックス位置の値にセットされます。
次のfは、新たなインデックスおよび残りの戻り値を引数として呼び出されます。
これがlength回繰り返されます。
bitvector-unfold
はビットを左から右に、
bitvector-unfold-right
は右から左に埋めて行きます。
(use math.prime) (bitvector-unfold (^[index n] (values (small-prime? n) (+ n 1))) 20 0) ⇒ #*00110101000101000101 (bitvector-unfold-right (^[index n] (values (small-prime? n) (+ n 1))) 20 0) ⇒ #*10100010100010101100
註: この手続きはvector-unfold
のプロトコルに準じています (scheme.vector
- R7RSベクタ参照)。
他のunfold
のプロトコルとは異なることに注意してください (scheme.list
- R7RSリスト参照)。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの、順序を逆にしたものを新に作って返します。
省略可能なstartとend引数は入力の範囲を制限します。
(bitvector-reverse-copy #*10110011100011110000 4 16) ⇒ #*111100011100
[SRFI-178]{gauche.bitvector
}
全ての引数はビットベクタでなければなりません。全てのビットベクタをつなげたビットベクタを
新たに作って返します。
[SRFI-178]{gauche.bitvector
}
引数はビットベクタのリストでなければなりません。
その全てのビットベクタをつなげたビットベクタを新にたに作って返します。
[SRFI-178]{gauche.bitvector
}
引数の総数は3の倍数でなければなりません。それぞれの三つ組は、
ビットベクタと、そのビットベクタに対する開始インデックス、終了インデックスです。
それぞれのビットベクタの、インデックスで指定される範囲を抜き出したものを
つなげたビットベクタを新たに作って返します。
(bitvector-append-subbitvectors #*11100011 2 6 #*01010101 3 8) ⇒ #*100010101
[SRFI-178]{gauche.bitvector
}
bvが空のビットベクタなら#t
を、空でないビットベクタなら#f
を返します。
bvがビットベクタでなければエラーが投げられます。
[SRFI-178]{gauche.bitvector
}
全ての引数はビットベクタでなければなりません。
全てのビットベクタが同じ長さ、同じ内容なら#t
を、そうでなければ#f
を返します。
引数が0個もしくは1個の場合は#t
を返します。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの最初から/終わりのnビットを切り出した新たなビットベクタを
返します。bvの長さがnより小さければエラーが投げられます。
Gaucheではジェネリックな(subseq bv 0 n)
で最初のnビットを
切り出すこともできます (gauche.sequence
- シーケンスフレームワーク参照)。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの最初から/終わりのnビットを取り除いた新たなビットベクタを
返します。bvの長さがnより小さければエラーが投げられます。
Gaucheではジェネリックな(subseq bv n)
で最初のnビットを
取り除いたビットベクタを得ることもできます (gauche.sequence
- シーケンスフレームワーク参照)。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvをnビットごとの切片に切り分け、
それぞれを新たなビットベクタにしたもののリストを返します。
bvがnの倍数でなければ、最後のビットベクタはnビット未満になります。
[SRFI-178]{gauche.bitvector
}
状態値を受け渡しながら、konsをビットベクタの各要素に適用してゆきます。
knilは最初の状態値です。
konsは(kons state e1 e2 …)
のように
呼び出されます。ここでe1 e2 … は引数の各ビットベクタの対応する
要素を取り出したものです (/int
の手続きでは0/1、/bool
の手続きでは
#f
/#t
)。
これはscheme.vector
モジュールのvector-fold
と同じ引数順です
(scheme.vector
- R7RSベクタ)。
(リストについてのfold
手続きではkons手続きの最後の引数として
状態値が渡されることに注意してください。リストをたどる手続き参照)。
引数の全てのビットベクタは同じ長さでなければなりません。 そうでなければエラーが投げられます。
[SRFI-178]{gauche.bitvector
}
手続きfを与えられたビットベクタから取り出したビットに対して適用し、
その結果を新たなビットベクタにまとめて返します。
(bitvector-map/int logand #*10101 #*00111) ⇒ #*00101
引数の全てのビットベクタは同じ長さでなければなりません。 そうでなければエラーが投げられます。
[SRFI-178]{gauche.bitvector
}
手続きfを与えられたビットベクタから取り出したビットに対して適用し、
その結果をbv1に破壊的代入します。
これらの手続きは未定義値を返します。呼び出し側はbv1への副作用を使わなければ なりません。言い換えれば、これらの手続きは線形更新手続きではありません。
引数の全てのビットベクタは同じ長さでなければなりません。 そうでなければエラーが投げられます。
[SRFI-178]{gauche.bitvector
}
手続きfを与えられたビットベクタから取り出したビットに対して適用し、
その結果をリストに集めて返します。
引数の全てのビットベクタは同じ長さでなければなりません。 そうでなければエラーが投げられます。
{gauche.bitvector
}
ビットベクタbvの要素のうち、それがvalとビットとして
一致するもの (#t
か1
なら真と一致、#f
か0
なら偽と一致)
について、それぞれそのインデックスを引数に手続きfを呼びます。結果は
インデックスの小さい順にリストに集められて返されます。
下の例はビットベクタのビットが真であるインデックスのリストを返します。
(bitvector-value-map-index->list identity #*10011 #t) ⇒ (0 3 4)
[SRFI-178]{gauche.bitvector
}
与えられたビットベクタの各ビットに対してfを適用します。fの結果は捨てられます。
引数の全てのビットベクタは同じ長さでなければなりません。 そうでなければエラーが投げられます。
(bitvector-for-each/int print #*11100 #*01110 #00111)
⇒ prints
100
110
111
011
001
{gauche.bitvector
}
bvの各ビットを最初から走査し、そのビットがvalとビットとして一致したものについて、
そのインデックスを引数にfを呼び出します。fの結果は捨てられます。
(bitvector-value-for-each-index print #*1101111010 #f)
⇒ prints
2
7
9
上のbitvector-value-map-index->list
も参照。
[SRFI-178]{gauche.bitvector
}
二つのビットベクタbv1、bv2に共通するプレフィクスまたはサフィックスの
長さを返します。
(bitvector-prefix-length #*1100101001 #*110001101) ⇒ 4 (bitvector-suffix-length #*1100101001 #*110001101) ⇒ 2
[SRFI-178]{gauche.bitvector
}
引数はどちらもビットベクタでなければなりません。
needleがhaystackのプレフィックスまたはサフィックスになっている時に
#t
を、そうでなければ#f
を返します。
(bitvector-prefix? #*101 #*1010100) ⇒ #t (bitvector-prefix? #*101 #*1000110) ⇒ #f (bitvector-suffix? #*110 #*1000110) ⇒ #t (bitvector-suffix? #*110 #*1010100) ⇒ #f
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの長さがlen未満であれば、
長さがlenになるまでbvの先頭もしくは末尾にbitを付加した
ビットベクタを作って返します。bvの長さがlenより大きな場合は
長さlenになるまでbvの先頭もしくは末尾のビットを削ったビットベクタを
作って返します。lenがbvの長さと同じなら、bvのコピーが
返されます。
(bitvector-pad 1 #*00010 10) ⇒ #*1111100010 (bitvector-pad-right 1 #*00010 10) ⇒ #*0001011111 (bitvector-pad 1 #*0100011 3) ⇒ #*011 (bitvector-pad-right 1 #*0100011 3) ⇒ #*010
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの先頭、末尾、あるいは両方から、連続するbitをできる限り
除いたビットベクタを新たに作って返します。
(bitvector-trim 0 #*000101000) ⇒ #*101000 (bitvector-trim-right 0 #*000101000) ⇒ #*000101 (bitvector-trim-both 0 #*000101000) ⇒ #*101
[SRFI-178]{gauche.bitvector
}
ビットベクタbvのi番目とj番目のビットを入れ替えます。
戻り値は未定義です。
インデックスが範囲外であればエラーが投げられます。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvのビット順を破壊的に反転します。
省略可能なstart/endが与えられた場合は、
それらのインデックスで指定される範囲内だけが変更対象となります。
戻り値は未定義です。
[SRFI-178]{gauche.bitvector
}
(bitvector-copy! to start (bitvector-reverse-copy from start end))
と意味的に同じですが、より効率が良いかもしれません。
戻り値は未定義です。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容を整数0または1のリスト、あるいは真偽値のリストとして
返します。最初の2つの手続きは左から、reverse-
のつく2つの手続きは
右からビットを取ります。省略可能なstart/end引数は
取り出すビットの範囲を指定します。
(bitvector->list/int #*010011000111 2 10) ⇒ (0 0 1 1 0 0 0 1) (reverse-bitvector->list/int #*010011000111 2 10) ⇒ (1 0 0 0 1 1 0 0)
[SRFI-178]{gauche.bitvector
}
list->bitvector
(ビットベクタ参照)と似ていますが、
ビットを右から左に詰めてゆきます。
(reverse-list->bitvector '(1 0 #f #f #t #t)) ⇒ #*110001
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容を整数0または1のベクタ、あるいは真偽値のベクタとして
返します。最初の2つの手続きは左から、reverse-
のつく2つの手続きは
右からビットを取ります。省略可能なstart/end引数は
取り出すビットの範囲を指定します。
[SRFI-178]{gauche.bitvector
}
ベクタvecを新たなビットベクタに変換します。vecの要素は
0、1、あるいは真偽値でなければなりません。
最初の手続きはビットを左から右に同じ順で、reverse-
のつく手続きは
逆順で詰めてゆきます。
省略可能なstart/end引数はvecから取り出すビットの範囲を指定します。
(vector->bitvector #(0 0 1 1 #t #f #t #t) 2 7) ⇒ #*11101 (reverse-vector->bitvector #(0 0 1 1 #t #f #t #t) 2 7) ⇒ #*10111
[SRFI-178]{gauche.bitvector
}
ビットベクタと正確な非負整数とを相互変換します。
bvの最初(最左)のビットは、整数の最下位のビットに対応することに注意してください。
(bitvector->integer #*1000) ⇒ 1 (bitvector->integer #*0001) ⇒ 8
SRFI-151のbits->list
等は最下位ビットから順にビットをリストにするので、
それと一貫性があります(scheme.bitwise
- R7RSビット演算参照)。
integer->bitvector
はさらに省略可能なlen引数で、
引数の整数nの最下位から何ビット目までを取るかを指定できます。
省略時は(integer-length n)
の値が使われます
(基本的なビット演算参照)。
(integer->bitvector 11) ⇒ #*1101 (integer->bitvector 11 8) ⇒ #*11010000
{gauche.bitvector
}
それぞれ、整数0か1を生成するジェネレータと真偽値を生成するジェネレータを返します。
値はビットベクタbvの左から右へと取られます。
省略可能なstart/end引数はvecから取り出すビットの範囲を指定します。
(generator->list (bitvector->int-generator #*10111000)) ⇒ (1 0 1 1 1 0 0 0)
これらの名前はGaucheの名前付けと一貫性があります。
SRFI-178ではこれらを
make-bitvector/int-generator
およびmake-bitvector/bool-generator
と呼んでいます。
ジェネレータについて詳しくはgauche.generator
- ジェネレータを参照してください。
[SRFI-178]{gauche.bitvector
}
これらは省略可能引数を取らないことを除いて、
それぞれbitvector->int-generator
およびbitvector->bool-generator
と同じです。SRFI-178で定義されました。
{gauche.bitvector
}
ビットベクタbvのうち、値がvalと一致するビットのインデックスを
左から右への順番で生成するジェネレータを返します。
valは0, 1, #f
, #t
のいずれかでなければなりません。
省略可能なstart/end引数はvecから取り出すビットの範囲を指定します。
これは、ビットベクタをビットマップとして使い、 ビットがセットされている/されていない要素について何かする、といった場合に便利です。
(generator->list (bitvector->index-generator #*101110001 1)) ⇒ (0 2 3 4 8)
[SRFI-178]{gauche.bitvector
}
与えられたビットを蓄積し、最後にビットベクタを作って返すアキュムレータを返します。
(let ((a (make-bitvector-accumulator))) (a 1) (a 0) (a 0) (a 1) (a 1) (a (eof-object))) ⇒ #*10011
アキュムレータについて詳しくはscheme.generator
- R7RSジェネレータを参照してください。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの各ビットを反転したビットベクタを返します。
線形更新版のbitvector-not!
は、結果を作るために
bvを破壊的に変更するかもしれません。
(bitvector-not #*10100) ⇒ #*01011
[SRFI-178]{gauche.bitvector
}
与えられたビットベクタの各ビット間に指定の演算を施した結果を要素とするビットベクタを
返します。引数のビットベクタは全て同じ長さでなければなりません。
線形更新版(名前に!
がついているもの)は、
結果を作るためにbv1を破壊的に変更するかもしれません。
3つ以上のビットベクタが与えられた場合、xorとeqv操作は左結合的に行われます。すなわち:
(bitvector-xor a b c) ≡ (bitvector-xor (bitvector-xor a b) c) (bitvector-eqv a b c) ≡ (bitvector-eqv (bitvector-eqv a b) c)
[SRFI-178]{gauche.bitvector
}
bv1とbv2の対応する各ビットに演算を施した結果をビットベクタにして返します。
bv1とbv2は同じ長さでなければなりません。
nand : (not (and bv1 bv2)) nor : (not (or bv1 bv2) andc1 : (and (not bv1) bv2) andc2 : (and bv1 (not bv2)) orc1 : (or (not bv1) bv2) orc2 : (or bv1 (not bv2))
線形更新版(名前に!
がついているもの)は、
結果を作るためにbv1を破壊的に変更するかもしれません。
[SRFI-178]{gauche.bitvector
}
bvを左にcountビットシフトした、bvと同じ長さのビットベクタを
返します。countが負の場合は-countビット右にシフトします。
あふれたビットは捨てられます。空き部分のビットはbitで埋められます。
(bitvector-logical-shift #*101100111000 4 1) ⇒ #*001110001111 (bitvector-logical-shift #*101100111000 -4 0) ⇒ #*000010110011
[SRFI-178]{gauche.bitvector
}
bv中のビットで、bitと一致するものの数を返します。
[SRFI-178]{gauche.bitvector
}
bv中の、iビット目からbitがいくつ連続しているか、その数を返します。
(bitvector-count-run 1 #*11111111100 0) ⇒ 9
[SRFI-178]{gauche.bitvector
}
各ビットベクタは同じ長さでなければなりません。
同じ長さのビットベクタを次のように構成して返します。
結果のkビット目は、bv-ifのkビット目が#t
(1)であれば
bv-thenのkビット目、そうでなければbv-elseのkビット目と
同じになります。
[SRFI-178]{gauche.bitvector
}
bv中で一番左にあるbitのインデックスを返します。
bv中にbitが無ければ-1
を返します。
(bitvector-first-bit 1 #*0010011) ⇒ 2 (bitvector-first-bit 0 #*1111111) ⇒ -1
以下の手続きは、ビットベクタの startビット目(含む)からendビット目(含まない)までの部分について 操作するものです。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvのstartビット目からendビット目までのいずれかに
1のビットがあれば#t
を、そうでなければ#f
を返します。
Gaucheの組み込み手続きを使って
(bitvector-any-value? bv 1 start end)
とした場合と同じです
(ビットベクタ参照)。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvのstartビット目からendビット目までのすべてが
1であれば#t
を、そうでなければ#f
を返します。
Gaucheの組み込み手続きを使って
(bitvector-every-value? bv 1 start end)
とした場合と同じです
(ビットベクタ参照)。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容のうち、
startビット目からendビット目までのすべてがクリアされた、
あるいはセットされたビットベクタをそれぞれ返します。
線形更新版は結果を作るためにbvを破壊的に変更するかもしれません。
(bitvector-field-clear #*10010010101001 2 7) ⇒ #*10000000101001 (bitvector-field-set #*10010010101001 2 7) ⇒ #*10111110101001
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容のうち、
startビット目からendビット目までを、
from-bvの内容で置き換えたビットベクタを返します。
from-bvの長さは少なくともend-startだけなければなりません。 from-bvがそれより長い場合、余分なビットは無視されます。
線形更新版は結果を作るためにbvを破壊的に変更するかもしれません。
(bitvector-field-replace #*10010010101001 #*110011 2 8) ⇒ #*10110011101001
下のbitvector-field-replace-same
も参照のこと。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容のうち、startビット目からendビット目までを、
from-bvのstartビット目からendビット目までで置き換えたものを返します。
from-bvの長さはendより大きくなければなりません。
線形更新版は結果を作るためにbvを破壊的に変更するかもしれません。
(bitvector-field-replace-same #*10010010101001 #*11001100 2 8) ⇒ #*10001100101001
上のbitvector-field-replace
も参照のこと。
[SRFI-178]{gauche.bitvector
}
ビットベクタbvの内容のうち、startビット目からendビット目までが
countビットだけ右にローテートされた内容に置き換えられているものを返します。
countが負なら、その絶対値分だけ左にローテートします。
(bitvector-field-rotate #*001100110011 1 4 8) ⇒ #*001101100011 (bitvector-field-rotate #*001100110011 -1 4 8) ⇒ #*001110010011