Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Javascript中创建位数组?_Javascript_Bitarray - Fatal编程技术网

如何在Javascript中创建位数组?

如何在Javascript中创建位数组?,javascript,bitarray,Javascript,Bitarray,在JavaScript中实现位数组的最佳方法是什么?我不知道位数组,但您可以使用新功能简化字节数组 抬头看。我在Chrome和Firefox中都使用过这些。最重要的是Uint8Array 要生成512个未初始化字节的数组,请执行以下操作: var arr = new UintArray(512); 并访问它(第六个字节): 对于node.js,使用(服务器端) 编辑: 要访问单个位,请使用位掩码 要在一的位置获取位,请执行num&0x1下面是我突然想到的一个: 更新-这个类的一些东西整天都在困

在JavaScript中实现位数组的最佳方法是什么?

我不知道位数组,但您可以使用新功能简化字节数组

抬头看。我在Chrome和Firefox中都使用过这些。最重要的是Uint8Array

要生成512个未初始化字节的数组,请执行以下操作:

var arr = new UintArray(512);
并访问它(第六个字节):

对于node.js,使用(服务器端)

编辑:

要访问单个位,请使用位掩码


要在一的位置获取位,请执行
num&0x1

下面是我突然想到的一个:

更新-这个类的一些东西整天都在困扰着我-它不是基于大小的-创建一个具有N个插槽/位的位数组是一个两步操作-实例化,调整大小。使用可选的第二个参数将类更新为基于大小,用于使用数组值或基数为10的数值填充基于大小的实例

(摆弄它)

/*位数组数据类型*/
//建造师
函数位数组(大小,位){
//我们的位的专用字段数组
this.m_bits=新数组();
//.ctor-初始化为true/false数组或数值数组的副本
if(位和位长度){
对于(变量i=0;i此.m_位.length;i--){
这个.m_bits.pop();
}
}
}
}
/*位数组公共实例方法*/
//只读属性-位数
BitArray.prototype.getLength=函数(){返回this.m_bits.length;};
//访问器-在索引处获取位
BitArray.prototype.getAt=函数(索引){
if(索引<此.m_位长度){
返回这个.m_位[索引];
}
返回null;
};
//访问器-在索引处设置位
BitArray.prototype.setAt=函数(索引,值){
if(索引<此.m_位长度){
this.m_bits[index]=值?BitArray.\u ON:BitArray.\u OFF;
}
};
//调整位数组的大小(附加新的false/0索引)
BitArray.prototype.resize=函数(newSize){
var tmp=新数组();
对于(变量i=0;i=0;i--){
if(此.m_位[i]==位数组。_打开){
n+=数学功率(2,功率);
}
pow++;
}
返回n;
};
/*静态方法*/
//获取两位数组的并集
BitArray.getUnion=函数(bitArray1,bitArray2){
var len=BitArray.\u getLen(bitArray1,bitArray2,true);
var结果=新的位数组(len);
对于(变量i=0;i0);
返回新的位数组(bits.length,bits.reverse());
};
/*位数组专用静态常数*/
位数组。_ON=1;
位数组。_OFF=0;
/*位数组专用静态方法*/
//计算两位的交集
位数组。_intersect=函数(位1,位2){
返回bit1==BitArray.\u打开和bit2===BitArray.\u打开?BitArray.\u打开:BitArray.\u关闭;
};
//计算两位的并集
位数组。_union=函数(位1,位2){
返回bit1==BitArray.| | bit2===BitArray.|ON?BitArray._ON:BitArray._OFF;
};
//计算两位的差
位数组。_差=函数(位1,位2){
返回bit1==BitArray.\u打开和&bit2!==BitArray.\u打开?BitArray.\u打开:BitArray.\u关闭;
};
//获取两位数组的最长或最短(最小)长度
BitArray.\u getLen=函数(bitArray1,bitArray2,最小){
var l1=bitArray1.getLength();
var l2=bitArray2.getLength();
返回l1>l2?最小?l2:l1:最小?l2:l1;
};
感谢@Daniel Baulig要求从快速、肮脏到基于原型的重构。

提供了位数组实现,可以将不同的输入(十六进制字符串、字节数组等)转换为位数组

var byte = arr[5];
/* BitArray DataType */

// Constructor
function BitArray(size, bits) {
    // Private field - array for our bits
    this.m_bits = new Array();

    //.ctor - initialize as a copy of an array of true/false or from a numeric value
    if (bits && bits.length) {
        for (var i = 0; i < bits.length; i++)
            this.m_bits.push(bits[i] ? BitArray._ON : BitArray._OFF);
    } else if (!isNaN(bits)) {
        this.m_bits = BitArray.shred(bits).m_bits;

    }
    if (size && this.m_bits.length != size) {
        if (this.m_bits.length < size) {
            for (var i = this.m_bits.length; i < size; i++) {
                this.m_bits.push(BitArray._OFF);
            }
        } else {
            for(var i = size; i > this.m_bits.length; i--){
                this.m_bits.pop();
            }
        }
    }
}

/* BitArray PUBLIC INSTANCE METHODS */

// read-only property - number of bits 
BitArray.prototype.getLength = function () { return this.m_bits.length; };

// accessor - get bit at index 
BitArray.prototype.getAt = function (index) {
    if (index < this.m_bits.length) {
        return this.m_bits[index];
    }
    return null;
};
// accessor - set bit at index 
BitArray.prototype.setAt = function (index, value) {
    if (index < this.m_bits.length) {
        this.m_bits[index] = value ? BitArray._ON : BitArray._OFF;
    }
};

// resize the bit array (append new false/0 indexes) 
BitArray.prototype.resize = function (newSize) {
    var tmp = new Array();
    for (var i = 0; i < newSize; i++) {
        if (i < this.m_bits.length) {
            tmp.push(this.m_bits[i]);
        } else {
            tmp.push(BitArray._OFF);
        }
    }
    this.m_bits = tmp;
};

// Get the complimentary bit array (i.e., 01 compliments 10)
BitArray.prototype.getCompliment = function () {
    var result = new BitArray(this.m_bits.length);
    for (var i = 0; i < this.m_bits.length; i++) {
        result.setAt(i, this.m_bits[i] ? BitArray._OFF : BitArray._ON);
    }
    return result;
};

// Get the string representation ("101010") 
BitArray.prototype.toString = function () {
    var s = new String();
    for (var i = 0; i < this.m_bits.length; i++) {
        s = s.concat(this.m_bits[i] === BitArray._ON ? "1" : "0");
    }
    return s;
};

// Get the numeric value 
BitArray.prototype.toNumber = function () {
    var pow = 0;
    var n = 0;
    for (var i = this.m_bits.length - 1; i >= 0; i--) {
        if (this.m_bits[i] === BitArray._ON) {
            n += Math.pow(2, pow);
        }
        pow++;
    }
    return n;
};

/* STATIC METHODS */

// Get the union of two bit arrays
BitArray.getUnion = function (bitArray1, bitArray2) {
    var len = BitArray._getLen(bitArray1, bitArray2, true);
    var result = new BitArray(len);
    for (var i = 0; i < len; i++) {
        result.setAt(i, BitArray._union(bitArray1.getAt(i), bitArray2.getAt(i)));
    }
    return result;
};

// Get the intersection of two bit arrays 
BitArray.getIntersection = function (bitArray1, bitArray2) {
    var len = BitArray._getLen(bitArray1, bitArray2, true);
    var result = new BitArray(len);
    for (var i = 0; i < len; i++) {
        result.setAt(i, BitArray._intersect(bitArray1.getAt(i), bitArray2.getAt(i)));
    }
    return result;
};

// Get the difference between to bit arrays
BitArray.getDifference = function (bitArray1, bitArray2) {
    var len = BitArray._getLen(bitArray1, bitArray2, true);
    var result = new BitArray(len);
    for (var i = 0; i < len; i++) {
        result.setAt(i, BitArray._difference(bitArray1.getAt(i), bitArray2.getAt(i)));
    }
    return result;
};

// Convert a number into a bit array
BitArray.shred = function (number) {
    var bits = new Array();
    var q = number;
    do {
        bits.push(q % 2);
        q = Math.floor(q / 2);
    } while (q > 0);
    return new BitArray(bits.length, bits.reverse());
};

/* BitArray PRIVATE STATIC CONSTANTS */
BitArray._ON = 1;
BitArray._OFF = 0;

/* BitArray PRIVATE STATIC METHODS */

// Calculate the intersection of two bits 
BitArray._intersect = function (bit1, bit2) {
    return bit1 === BitArray._ON && bit2 === BitArray._ON ? BitArray._ON : BitArray._OFF;
};

// Calculate the union of two bits 
BitArray._union = function (bit1, bit2) {
    return bit1 === BitArray._ON || bit2 === BitArray._ON ? BitArray._ON : BitArray._OFF;
};

// Calculate the difference of two bits 
BitArray._difference = function (bit1, bit2) {
    return bit1 === BitArray._ON && bit2 !== BitArray._ON ? BitArray._ON : BitArray._OFF;
};

// Get the longest or shortest (smallest) length of the two bit arrays 
BitArray._getLen = function (bitArray1, bitArray2, smallest) {
    var l1 = bitArray1.getLength();
    var l2 = bitArray2.getLength();

    return l1 > l2 ? smallest ? l2 : l1 : smallest ? l2 : l1;
};
class bitArray {
  constructor(length) {
    this.backingArray = Array.from({length: Math.ceil(length/32)}, ()=>0)
    this.length = length
  }
  get(n) {
    return (this.backingArray[n/32|0] & 1 << n % 32) > 0
  }
  on(n) {
    this.backingArray[n/32|0] |= 1 << n % 32
  }
  off(n) {
    this.backingArray[n/32|0] &= ~(1 << n % 32)
  }
  toggle(n) {
    this.backingArray[n/32|0] ^= 1 << n % 32
  }
  forEach(callback) {
    this.backingArray.forEach((number, container)=>{
      const max = container == this.backingArray.length-1 ? this.length%32 : 32
      for(let x=0; x<max; x++) {
        callback((number & 1<<x)>0, 32*container+x)
      }
    })
  }
}
let bits = new bitArray(10)
bits.get(2) //false
bits.on(2)
bits.get(2) //true

bits.forEach(console.log) 
/* outputs:
false
false
true
false
false
false
false
false
false
false
*/

bits.toggle(2)

bits.forEach(console.log) 
/* outputs:
false
false
false
false
false
false
false
false
false
false
*/

bits.toggle(0)
bits.toggle(1)
bits.toggle(2)

bits.off(2)
bits.off(3)
bits.forEach(console.log) 
/* outputs:
true
true
false
false
false
false
false
false
false
false
*/
const bufferFromBinaryString = (binaryRepresentation = '01010101') =>
    Buffer.from(
        parseInt(binaryRepresentation, 2).toString(16), 'hex');
get(n) {
    return (this.backingArray[n/32|0] & 1 << n % 32) != 0
    // test of > 0 fails for bit 31
}

forEach(callback) {
    this.backingArray.forEach((number, container)=>{
        const max = container == this.backingArray.length-1 && this.length%32
            ? this.length%32 : 32;
            // tricky edge-case: at length-1 when length%32 == 0,
            // need full 32 bits not 0 bits
    for(let x=0; x<max; x++) {
        callback((number & 1<<x)!=0, 32*container+x) // see fix in get()
    }
})
Let's do an AND operation with 4 (000 0010)

0100 1011 & 0000 0010 => 0000 0010
0000 0010 >> 1 => 1
get(n) {
    return (this.backingArray[n/32|0] & 1 << n % 32) != 0
}
for (var i=0; i < 100; i++) {
  var ar = new bitArray(1000);
  
  ar.on(i);

  for(var j=0;j<1000;j++) {

    // we should have TRUE only at one position and that is "i". 
    // if something is true when it should be false or false when it should be true, then report it.

    if(ar.get(j)) {
      if (j != i) console.log('we got a bug at ' + i);
    } 

    if (!ar.get(j)) {
      if (j == i) console.log('we got a bug at ' + i);
    }
  }
}