【HSP】ビット単位の 読み出し 書き込み モジュール【修正版】

【HSP】ビット単位の 読み出し 書き込み モジュール【修正版】

※補足:さらに高速化 (C++に移植してプラグイン化。DLL化)→https://archive.kerupani129.net/blog/posts/【hsp】ビット単位の-読み出し-書き込み-モジュール-2/
修正というか1から作り直したんですが…。
前回のより速度がかなり上がってると思います。
あと、今回のモジュールでは、32bit数値の範囲内でのみ使用できます。
後ろや前でデータがはみ出した場合やエラー処理等は一切していないので、そういう使い方をするとバグります。
速度をできるだけ上げるためです。すいません。

//// ビット操作モジュール
#module "bit_module"
// モジュール初期化
// bit_module_init
#deffunc bit_module_init
dim s256,1
return
// バッファに1bit書き込み
// bpoke p1,p2,p3
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~31 : バッファのインデックス(Bit単位)
// p3=0~1 : バッファに書き込む値
; switch 使うと処理時間がめっちゃ長くなる
; else なしで if だけでやると遅くなる
; bit演算のみで書き込みしても少し遅い
#deffunc bpoke var _var,int _index,int _value
if _value {
_var|=1<<_index
} else {
_var&=1<<_index^0xFFFFFFFF
}
return
// バッファから1bit読み出し
// val = bpeek(p1,p2)
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~31 : バッファのインデックス(Bit単位)
#defcfunc bpeek var _var,int _index
return _var>>_index&1
// バッファに2bit書き込み
// bpoke2 p1,p2,p3
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~30 : バッファのインデックス(Bit単位)
// p3=0~3 : バッファに書き込む値
; 一つずつ bpoke すると遅い
; if や switch 使うと処理時間がめっちゃ長くなる
#deffunc bpoke2 var _var,int _index,int _value
_var=3<<_index^0xFFFFFFFF&_var|(_value<<_index)
return
// バッファから2bit読み出し
// val = bpeek2(p1,p2)
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~30 : バッファのインデックス(Bit単位)
#defcfunc bpeek2 var _var,int _index
return _var>>_index&3
// バッファに4bit書き込み
// bpoke4 p1,p2,p3
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~28 : バッファのインデックス(Bit単位)
// p3=0~15 : バッファに書き込む値
#deffunc bpoke4 var _var,int _index,int _value
_var=15<<_index^0xFFFFFFFF&_var|(_value<<_index)
return
// バッファから4bit読み出し
// val = bpeek4(p1,p2)
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~28 : バッファのインデックス(Bit単位)
#defcfunc bpeek4 var _var,int _index
return _var>>_index&15
// バッファに任意サイズのbit列書き込み
// bpokeex p1,p2,p3,p4
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~31 : バッファのインデックス(Bit単位)
// p2=1~32 : 書き込むサイズ(1bit単位)
// p4=0~0xFFFFFFFF : バッファに書き込む値
#deffunc bpokeex var _var,int _index,int _size,int _value
_var=(1<<_size)-1<<_index^0xFFFFFFFF&_var|(_value<<_index)
return
// バッファから任意サイズのbit列読み出し
// val = bpeekex(p1,p2,p3)
// p1=変数 : バッファを割り当てた変数名 (配列なしint型)
// p2=0~31 : バッファのインデックス(Bit単位)
// p3=1~32 : 読み出すサイズ(1bit単位)
#defcfunc bpeekex var _var,int _index,int _size
return _var>>_index&((1<<_size)-1)
// メモリブロックのクリア (1bit単位)
// bitset p1,p2,p3,p4
// p1=変数 : 書き込み先の変数 (配列なしint型)
// p2=0~1 : クリアする値(1bit)
// p3=1~32 : クリアするサイズ(1bit単位)
// p4=0~31 : 書き込み先の変数メモリオフセット(1bit単位)
#deffunc bitset var _var,int _value,int _size,int _index
if _value {
_var|=(1<<_size)-1<<_index
} else {
_var&=(1<<_size)-1<<_index^0xFFFFFFFF
}
return
// 整数を2進数(文字列)に変換
// bitstr p1,p2
// p1=変数 : 結果を返す変数
// p2 : 変換元の値
#deffunc bitstr var _var,int _value
memexpand _var,64 ; 本当は32
repeat 8
s256=_value>>(cnt<<2)&15
s256=s256<<24|s256<<15|s256<<6|s256>>3
lpoke _var,7-cnt<<2,s256&0x01010101|0x30303030
loop
return
#global
bit_module_init

//// サンプル
a=0b11001110
b=""
bitstr b,a : mes "a=0b"+b // 2進数に変換
bpoke a,0,0b1 // 書き込み (右から1つ目に1)
bitstr b,a : mes "a=0b"+b // 2進数に変換
bpoke2 a,6,0b00 // 書き込み (右から8,7つ目に00)
bitstr b,a : mes "a=0b"+b // 2進数に変換
bpoke4 a,2,0b1100 // 書き込み (右から6,5,4,3つ目に1100)
bitstr b,a : mes "a=0b"+b // 2進数に変換
mes "右から3つ目の値="+bpeek(a,2) // 読み出し
mes "右から6,5つ目の値="+bpeek2(a,4) // 読み出し
mes "右から5~2つ目の値="+bpeek4(a,1) // 読み出し
bpokeex a,24,7,0b1111111 // 書き込み (右から31~25つ目に00)
bitstr b,a : mes "a=0b"+b // 2進数に変換
mes "右から30~24つ目の値="+bpeekex(a,23,7) // 読み出し
bitset a,0,16,16 // クリア
bitstr b,a : mes "a=0b"+b // 2進数に変換
bitset a,1,16,0 // クリア
bitstr b,a : mes "a=0b"+b // 2進数に変換

各命令のおよその処理時間 (私の環境で) は

1bit 読み書きともに0.0000004秒
2bit 読み書きともに0.0000004秒
4bit 読み0.0000004秒 書き0.0000006秒
任意指定 読み0.0000006秒 書き0.0000008秒
クリア (埋める) 0.0000005秒
2進数 (文字列) に変換 0.00001秒

です。(& | ^ << >> らのビット演算は約0.0000001秒)
やっぱり文字列関連は遅くなりますね~。
まあ表示しないということであればかなり早いと思います。
ほとんどビット演算のみで処理を行っていますので。
repeat loop ですら、文字列に変換するところでしか使用していません。
ビット演算って、応用すればゲームの作成とかでも意外に役に立つものなので、これでさらに使いやすくなると思います。
ではまたいつか。
↓クリック (投票) お願いします~
bit ビット 操作 演算 計算 算出 読み 書き 込み 出し 入力 出力 モジュール サンプル スクリプト ソース 2 4 8 16 32 64 128 256 進数 進法


「【HSP】ビット単位の 読み出し 書き込み モジュール【修正版】」への2件のフィードバック

  1. おお、たしかに使うときには便利そうですね@@!!
    HSPで不向きなことを可能にするなんてことはとても有用です。
    十分な速度ですよ。いいですねぇ。

  2. どうもありがとうございます!!
    本当はCとかでライブラリ作ってやったほうが高速化できるかもしれませんが…。

コメントは受け付けていません。