整数のビット値を確認する
over view
整数値を32ビットの二進表記に変換するユーザ関数。十進法表記の整数を二進法表記の整数に変換するユーザ関数ではないので注意。
string uuRefer2Bit(integer num);
- integer num … ビット値を参照する整数。十進法(−2147483648 〜 2147483647)または十六進法(0x00000000 〜 0xFFFFFFFF)で指定。
- 戻り値は string 型(4桁ごとの半角スペース区切り表記)
example
- 正の数は、最上位ビットがゼロの「0000 0000 0000 0000 0000 0000 0000 0000」〜「0111 1111 1111 1111 1111 1111 1111 1111」で返る。
uuRefer2Bit(100); // -> 0000 0000 0000 0000 0000 0000 0110 0100 uuRefer2Bit(0x7FFFFFFF); // -> 0111 1111 1111 1111 1111 1111 1111 1111
- 負の数は、最上位ビットが1の「1111 1111 1111 1111 1111 1111 1111 1111」〜「1000 0000 0000 0000 0000 0000 0000 0000」で返る。
uuRefer2Bit(-1); // -> 1111 1111 1111 1111 1111 1111 1111 1111 uuRefer2Bit(-2147483648); // -> 1000 0000 0000 0000 0000 0000 0000 0000
- 正の最大に1を加えると、位が上がり最上位ビットが立ってしまう。この数は、二進ビット表記のルールの上では負の数扱いになってしまう。
uuRefer2Bit(2147483647); // -> 0111 1111 1111 1111 1111 1111 1111 1111 uuRefer2Bit(2147483647 + 1); // -> 1000 0000 0000 0000 0000 0000 0000 0000 uuRefer2Bit(-2147483648); // -> 1000 0000 0000 0000 0000 0000 0000 0000
// これは無限ループではなく、2,147,483,648回繰り返された後にループを抜ける for (i=0; i>=0; i++){ llSay(0, "in the loop : " + (string)i); }
- 絶対値の等しい正の数と負の数の和はゼロである。このことは、二進32ビット表記上では33ビット目が抜け落ちる性質を利用して実装されている。
uuRefer2Bit(11); // -> 0000 0000 0000 0000 0000 0000 0000 1011 uuRefer2Bit(-11); // -> 1111 1111 1111 1111 1111 1111 1111 0101 // [0000 0000 0000 0000 0000 0000 0000 1011] // +[1111 1111 1111 1111 1111 1111 1111 0101] // -------------------------------------------- // 1[0000 0000 0000 0000 0000 0000 0000 0000]
- 4 により、「ある自然数のビット反転値」と「ある自然数に負の符号を付けた値」とは 1 だけ異なる。
uuRefer2Bit(11); // -> 0000 0000 0000 0000 0000 0000 0000 1011 uuRefer2Bit(~11); // ビット反転値 // -> 1111 1111 1111 1111 1111 1111 1111 0100 uuRefer2Bit(-11); // 負の符号を付けた値 // -> 1111 1111 1111 1111 1111 1111 1111 0101
前者は互いを完全に補完し合い、後者は全てを無に戻す。その違いは、僅かに 1 でしかない。
// 0000 0000 0000 0000 0000 0000 0000 1011 // + 1111 1111 1111 1111 1111 1111 1111 0100 // ------------------------------------------- // 1111 1111 1111 1111 1111 1111 1111 1111
// 0000 0000 0000 0000 0000 0000 0000 1011 // + 1111 1111 1111 1111 1111 1111 1111 0101 // ------------------------------------------- // 0000 0000 0000 0000 0000 0000 0000 0000
- ビット演算子の勉強に使うと良いかもしれない。
uuRefer2Bit(1|2|4); // -> 0000 0000 0000 0000 0000 0000 0000 0111 uuRefer2Bit(7<<1); // -> 0000 0000 0000 0000 0000 0000 0000 1110
- bit() と連携すると、上記 6 は次のように書き表せる。
uuRefer2Bit(bit(1)|bit(10)|bit(100)); // -> 0000 0000 0000 0000 0000 0000 0000 0111 uuRefer2Bit(bit(111)<<1); // -> 0000 0000 0000 0000 0000 0000 0000 1110
- コレの謎も理解できるはず 1)。
~llListFindList(list src, list test) // と llListFindList(list src, list test) != -1 // は同意
code
※ いずれのユーザ関数も同じ結果を返します(下にいくほど高速)
- 2010-11-21:ビット演算の知識ゼロ
string uuRefer2Bit(integer num){ integer i; string result; integer bit; string max_bit; if (num < 0){ max_bit = "1"; num += 0x80000000; }else{ max_bit = "0"; } for (i=0; i<31; i++){ bit = num % 2; num /= 2; if ((i+1)%4){ result = (string)bit + result; }else{ result = " " + (string)bit + result; } } result = max_bit + result; return result; }
- 2010-11-25:処理時間を大幅に短縮
string uuRefer2Bit(integer num){ string result; integer bit; for (bit=0x80000000; bit; bit=(bit>>1)&0x7fffffff){ if (bit&0x11111110){ if (bit&num){ result += "1 "; }else{ result += "0 "; } }else if (bit&num){ result += "1"; }else{ result += "0"; } } return result; }
references
以下のページを参考にさせて頂きました。有益な資料をありがとうございました。
1)
bit 反転の方が高速