Skip to content
uupaa edited this page Apr 21, 2016 · 31 revisions

Namespace

Bit.js is located in global.WebModule.Bit. To invoke more easily, it can also be placed in global.UserAgent.

Bit.js の名前空間は global.WebModule.Bit です。 より手軽に呼び出せるように、global.Bit に配置することも可能です

API

  • Bit.n - 連続したnビットを取り出します
  • Bit.cnl - 連続している1ビットの数を左側(MSB)から数えます
  • Bit.cnr - 連続している1ビットの数を右側(LSB)から数えます
  • Bit.split8 - 8 bit分のビット列をビットパターンで切り出します
  • Bit.split16 - 16 bit分のビット列をビットパターンで切り出します
  • Bit.split24 - 24 bit分のビット列をビットパターンで切り出します
  • Bit.split32 - 32 bit分のビット列をビットパターンで切り出します
  • Bit.reverse8 - 8 bit 値の左右のビットを反転させた値を返します
  • Bit.reverse16 - 16 bit 値の左右のビットを反転させた値を返します
  • Bit.reverse32 - 32 bit 値の左右のビットを反転させた値を返します
  • Bit.popcnt - 1 のビットをカウントします
  • Bit.nlz - 先頭から 0 のビットが何個連続しているかカウントします
  • Bit.clz - Bit.nlz の alias です
  • Bit.ntz - 末尾から 0 のビットが何個連続しているかカウントします
  • Bit.ctz - Bit.ntz の alias です
  • Bit.dump - ビットパターンでビット列を切り出し、2進数の文字列に変換します
  • Bit.IEEE754 - IEEE754 における数値のビット表現を返します

Bit.n

Bit.n(value:UINT32, bitPattern:UINT32):UINT32 は、bitPattern で指定した連続したnビットを取り出しビットシフトした値を返します。

Bit.n(0x000000ff, 0b00000000000000000000000011111100) // -> 0x3f
Bit.n(0x000000ff, 0b00000000000000000000000011000000) // -> 0x03
Bit.n(0x0000ffff, 0b00000000000000000111111000000000) // -> 0x3f
Bit.n(0x0000ffff, 0b00000000000000001100000000000000) // -> 0x03
Bit.n(0xffffffff, 0b01111110000000000000000000000000) // -> 0x3f
Bit.n(0xffffffff, 0b11000000000000000000000000000000) // -> 0x03

Bit.cnl

Bit.cnl(bitPattern:UINT32):UINT8 は、1のビットが幾つ連続しているかを左方向(MSB)から検索して返します。戻り値は 0 〜 32 の値になります。

Bit.cnl(0x0)        // -> 0
Bit.cnl(0b11001110) // -> 2
//        ~~
Bit.cnl(0b11111100) // -> 6
//        ~~~~~~
Bit.cnl(0xffffffff) // -> 32
Bit.cnl(0b101)      // -> 1
//        ~

Bit.cnr

Bit.cnr(bitPattern:UINT32):UINT8 は、1のビットが幾つ連続しているかを右方向(LSB)から検索して返します。戻り値は 0 〜 32 の値になります。

Bit.cnr(0x0)        // -> 0
Bit.cnr(0b11001110) // -> 3
//            ~~~
Bit.cnr(0b11111100) // -> 6
//        ~~~~~~
Bit.cnr(0xffffffff) // -> 32
Bit.cnr(0b101)      // -> 1
//          ~

Bit.split

Bit.splitN(u32:UINT32, bitPattern:UINT8Array|Uint8Array):UINT32Array は、N bit 分のバイト列を bitPattern で切り出した値を格納した UINT32Array を返します。

N には 8〜32の数値が入ります。

bitPattern で切り出した値を配列の先頭から順番に格納します。

bitPattern には、切り出すビット数を配列 [ bitWidth , ...] の形で指定します。ビットの切り出しは左から右方向に行います。
bitWidth には 0 〜 32 の値を指定します。bitWidth の合計が 32 を超える部分は無効になります。

Bit.split32(0x12345678, [16,8,4,4]) の実行結果は以下のようになります。

Bit.split32(0x12345678, [16,8,4,4])
//            ~~~~                 -> split 16 bits
//                ~~               -> split  8 bits
//                  ~              -> split  4 bits
//                   ~             -> split  4 bits
// -> [0x1234, 0x56, 0x7, 0x8]
//         16     8    4    4  bit
// 8bitづつ切り出します
Bit.split32(0x12345678, [8,8,8,8])
// -> [0x12, 0x34, 0x56, 0x78]

// 先頭の12bit(0x123)と残り20bit(0x45678)を切り出します
Bit.split32(0x12345678, [12,20])
// -> [0x123, 0x45678]

// width に 0 を指定すると、戻り値に 0 を挿入する事ができます
Bit.split32(0x12345678, [0,8,0,8,0,8,0,8])
// -> [0, 0x12, 0, 0x34, 0, 0x56, 0, 0x78]

// width の合計値は最大 32 です。32 を越えた部分は無効になります
// bitPattern に [4,8,32] を指定すると [4,8,20] と同じ結果になります
Bit.split32(0x12345678, [4,8,32])
// -> [0x1, 0x23, 0x45678]

// [注意してください]
// Bit.split32 は u32 を常に 32bit で扱います
// 16bit の値(0x0000〜0xffff)を扱う場合は、Bit.split16 を使ってください。
Bit.split32(0x1234, [4,4,4,4])
// -> [0x1, 0x2, 0x3, 0x4] にはならず、[0x1234, 0x0, 0x0, 0x0, 0x0] になります
Bit.split16(0x1234, [4,4,4,4])
// -> [0x1, 0x2, 0x3, 0x4]

ES6 Destructuring Assignment と共に使用する

ES6 Destructuring Assignment と Bit.split を併用すると、より簡単に記述できます。

var [u16, u8a, u8b] = Bit.split32(0x00001234, [16, 8, 8]);
// u16 = 0x0000, u8a = 0x12, u8b = 0x34

Bit.reverse8

Bit.reverse8(u8:UINT8):UINT8 は、u8 の左右のビットを反転させた値を返します。

Bit.reverse8(0b00001111); // -> 0b11110000

Bit.reverse16

Bit.reverse16(u16:UINT16):UINT16 は、u16 の左右のビットを反転させた値を返します。

Bit.reverse16(0b0000000011100000); // -> 0b0000011100000000

Bit.reverse32

Bit.reverse32(u32:UINT32):UINT32 は、u32 の左右のビットを反転させた値を返します。

Bit.reverse32(0b00010001000100010001000100010001); // -> 0b10001000100010001000100010001000

Bit.popcnt

Bit.popcnt(u32:UINT32):UINT8 は、u32 に存在する 1 のビットをカウントします。

Bit.popcnt(0x6)    // -> 2
Bit.popcnt(0xff)   // -> 8


Bit.dump(0x6,  [32]) // -> "00000000000000000000000000000110(6)"
                                                         ~~  -> 1  2 

Bit.dump(0xff, [32]) // -> "00000000000000000000000011111111(ff)"
                                                    ~~~~~~~~ -> 1  8 

Bit.nlz

Bit.nlz(u32:UINT32):UINT8 は、u32 の先頭からみて、0 のビットが何個連続しているかカウントします。
Bit.nlz(0) は 32, Bit.nlz(0xffffffff) は 0 になります。

Bit.nlz(0x6) // -> 29

Bit.dump(0x6, [32]) // -> "00000000000000000000000000000110(6)"
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    -> 0  29 

Bit.ntz

Bit.ntz(u32:UINT32):UINT8 は、u32 の末尾からみて、0 のビットが何個連続しているかカウントします。
Bit.ntz(0) は 32, Bit.ntz(0xffffffff) は 0 になります。

Bit.ntz(0x6) // -> 1

Bit.dump(0x6, [32]) // -> "00000000000000000000000000000110(6)"
                                                          ~ -> 0  1 

Bit.dump

Bit.dump(u32:UINT32, bitPattern:UINT8Array|Uint8Array, verbose:Boolean = false):String は、 Bit.split32(u32, bitPattern)を実行した結果を、2進数の文字列に変換して返します。

bitPattern の書式は Bit.split を参照してください。

Bit.dump(0x12345678, [16,12,4])
// -> "0001001000110100, 010101100111, 1000",
       ~~~~~~~~~~~~~~~~
            16bits       ~~~~~~~~~~~~
                             12bits    ~~~~
                                       4bits

verbose を true にすると、先頭に u32 の値を追加し、bitPattern のそれぞれの値に、10進数と16進数の値を追加します。

Bit.dump(0x12345678, [16,12,4], true)
// -> "00010010001101000101011001111000(0x12345678), 0001001000110100(4660,0x1234), 010101100111(1383,0x567), 1000(8,0x8)"
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               u32                                   ~~~~~~~~~~~~~~~~
                                                          16bit                     ~~~~~~~~~~~~
                                                                                        12bit                 ~~~~
                                                                                                              4bit

Bit.IEEE754

Bit.IEEE754(num:Number, doublePrecision:Boolean = false):Uint32Array は、IEEE754 における num のビット表現を配列で返します。
doublePrecision が true なら倍精度(Double-precision)に、false なら単精度(Single-precision)になります。

Single-precision

単精度のビット表現です。戻り値は Uint32Array([IEEE754-Single-precision-format, 0x00]) になります。 配列の先頭要素にビット表現を格納し、次の32bitは0になります。

IEEE754 Single-precision floating-point format.

    sign exponent  fraction
     +-++--------++-----------------------+
     |0||00000000||00000000000000000000000|
     +-++--------++-----------------------+
      1      8               23 bits
      -  --------  -----------------------
      31 30    23  22                    0
var u32Array = Bit.IEEE754(0.15625);

Bit.dump(u32Array[0], [1, 8, 23]);
// -> "0, 01111100, 01000000000000000000000"

Bit.dump(u32Array[1], [32]);
// -> "00000000000000000000000000000000"

Double-precision

倍精度のビット表現です。戻り値は Uint32Array([上位32bit, 下位32bit]) になります。

IEEE754-Double-precision-format の上位32bit を配列の先頭要素に、下位32bit を次の要素に格納しています。

IEEE754 Double-precision floating-point format.

    sign exponent  fraction
     +-++--------++-----------------------+
     |0||0......0||0.....................0|
     +-++--------++-----------------------+
      1     11               52 bits
      -  --------  -----------------------
      63 62    52  51                    0
var u32Array = Bit.IEEE754(0.15625, true);

Bit.dump(u32Array[0], [1, 11, 20]);
// -> "0, 01111111100, 01000000000000000000"
//   sign exponent     fraction 20 bits (51 ~ 32)

Bit.dump(u32Array[1], [32]);
// -> "00000000000000000000000000000000"
//     fraction 32 bits (31 ~ 0)

sign と exponent を取り出すにはこのようにします

var u32Array = Bit.IEEE754(0.15625, true); 
var bitField = Bit.split32(u32Array[0], [1, 11]); // -> [0, 1020] [`0`, `01111111100`]