Common Lispの系譜を継ぐマイコン上のuLispをラズパイPico2上で練習中。今回は整数のビット演算系の関数を練習してみます。Common Lispではboole関数とlogで始まる関数どもで似た処理が可能。uLispではlogで始まる関数のみ存在します。その範囲であれば「概ね」差は見えにくいです。
※Lispと一緒 投稿順 index はこちら
※実機確認は Raspberry Pi Pico2で行ってます。
※使用させていただいとります uLisp のバージョンは 4.6b (Arm用)です。
※uLispとCommon Lispとの動作比較のために使わせていただいている処理系は以下です。
SBCL 2.2.2 (SBCL = Steel Bank Common Lisp )
整数ビット演算系の関数
今回練習してみるのは以下の関数どもです。
-
- logbitp、整数ビット取り出し
- logand、整数ビット論理積
- logior、整数ビット論理和
- logxor、整数ビット排他的論理和
- lognot、整数ビット反転
- ash、整数ビット算術シフト(左右)
2の補数表現の32ビット整数範囲で処理を行っている限り、Common Lisp上でもuLisp上でも上記の関数どもの挙動が異なることはないのではないかと推定してます。
差が見えてしまうのは32ビット整数範囲をはみ出してしまった場合です。Common Lispは大きな整数を扱えるので、知らないうちに32ビット整数範囲をはみ出してしまってもフツーに処理できてしまいます。一方 uLisp の場合、処理できる数は32ビット範囲です。ところが明らかに32ビット整数範囲でない16進数を記述しても、さも32ビット範囲に入っているかのように処理してくれちゃいます。エラーにもならず。お間抜け老人はちとやらかしそうな挙動ぜよ。。。
整数ビットの取り出し
logbitp関数は、第1引数にlsb側から数えたビット位置を指定することで第2引数のビットを真偽値として取り出すことができます。
ここは32ビット整数範囲内なので波風立ちませぬ。
整数ビットの論理反転
まずはCommon Lisp上で整数の反転処理をすると以下のようです。
最後、4つめ、16進で11桁もあるのが見えますかね。Common Lispではこういう数でも問題なく処理できます。
uLispでは32ビット範囲内に限られるハズなのですが、最後4つ目の16進整数表現も特にエラーなく受け入れてくれます。しかし、結果はCommon Lispの場合とは異なってます。どうも16進表現の下8桁をとりだして32ビットだと思い込もうとしているみたい。。。表記するときに桁をミスるとヤバいぜ。
整数ビットのAND、OR、XOR
まあ32ビット整数範囲に収まっているならば平穏無事。
整数ビットの算術シフト
シフトは第2引数(シフトのビット数)の符号を変えることで左右両方できますが、算術シフトのみです。よって右論理シフトは算術シフトした後にANDとる感じ? まずは Common Lisp。
プログラム内で数を表記するときにうっかり桁数をミスるとヤバいぜ。