整数のビット値を確認する

over view

整数値を32ビットの二進表記に変換するユーザ関数。十進法表記の整数を二進法表記の整数に変換するユーザ関数ではないので注意。

string uuRefer2Bit(integer num);
  • integer num … ビット値を参照する整数。十進法(−2147483648 〜 2147483647)または十六進法(0x00000000 〜 0xFFFFFFFF)で指定。
  • 戻り値は string 型(4桁ごとの半角スペース区切り表記)

example

  1. 正の数は、最上位ビットがゼロの「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
  2. 負の数は、最上位ビットが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
  3. 正の最大に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);
    }
  4. 絶対値の等しい正の数と負の数の和はゼロである。このことは、二進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]
  5. 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
  6. ビット演算子の勉強に使うと良いかもしれない。
    uuRefer2Bit(1|2|4);
    // -> 0000 0000 0000 0000 0000 0000 0000 0111
     
    uuRefer2Bit(7<<1);
    // -> 0000 0000 0000 0000 0000 0000 0000 1110
  7. 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
  8. コレの謎も理解できるはず 1)
    ~llListFindList(list src, list test) // と
    llListFindList(list src, list test) != -1 // は同意

code

※ いずれのユーザ関数も同じ結果を返します(下にいくほど高速)

  1. 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;
    }
  2. 2010-11-24:ビット演算を少し理解
    string uuRefer2Bit(integer num){
        string result;
        integer i;
        for (i=0; i<32; i++){
            if ((i+1)%4){
                result = (string)(num&1) + result;
            }else{
                result = " " + (string)(num&1) + result;
            }
            num = num>>1;
        }
        return result;
    }
  3. 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 反転の方が高速
最終更新: 2010年11月29日 04 : 32 by arz Nitely
http://arzNitely.com/lsl/user_function/uurefer2bit/index.html

Copyright 2007-2010 ©arzNitely.com all right reserved

www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0