0

Accorting to this answer's comment, I would like to use Unit8Array to achieve the same thing:

var bin = parseInt('1000', 2); //=8

I mean:

inputs are:

length = 4
digits = [1,0,0,0]

and after some TypedArray magic the output will be:

8

Lets see a concrete example with (2 bits length):

counts = {};
var a = [[0,1],[0,0],[0,1],[0,0],[0,0],[1,1]]; 
for(var i in a){
  var id = parseInt(a[i].join(''), 2);
  if(!++counts[id])counts[id] = 1;
}
console.log(counts); //{0: 3, 1: 2, 3: 1} 

my notes are here.

Community
  • 1
  • 1
  • Why would a TypedArray be useful here? – alex Aug 31 '13 at 10:34
  • it is (must be) faster –  Aug 31 '13 at 10:34
  • Can you please step back a bit and explain what you want to do? Maybe `Uint8Array` is not really part of the best solution here. You seem to want to use an array (a sequence of 8-bit unsigned integers) to convert a binary representation to a single 8-bit uint (where does the array come into play?). Working with single bits is usually done efficiently with bitshifting (`<<` and `>>`). – Jo Are By Aug 31 '13 at 10:59
  • OK I extend my question. –  Aug 31 '13 at 11:07
  • 1
    it still makes no sense. The only feature a typed array gives you that may be of use is the ability to "cast" an array of other types (e.g. UInt32) into a byte array. None of that helps with your ASCII binary conversion - a raw "binary" array is not remotely the same thing as a string of binary digits, it's unfortunate that some people use the word "binary" to differentiate "raw" data from "human readable" data. – Alnitak Aug 31 '13 at 12:21
  • @Alnitak So there is no basic way to cast typed array to int? –  Aug 31 '13 at 12:59
  • Sure there is, but without knowing what problem _exactly_ you're trying to solve (it appears to be something to do with converting _ASCII_ base 2 into a number) I don't see how it's going to help. – Alnitak Aug 31 '13 at 14:03

3 Answers3

0

Are you trying to get this parseInt(string, radix)

radix An integer that represents the radix of the above mentioned string.

Not sure, is like this somewhat you expect

var x = new Uint8Array([1,0,0,0]);
var a = x[0].toString()+x[1].toString()+x[2].toString()+x[3].toString();
console.log(parseInt(a, 2));
console.log(a.length);
Praveen
  • 55,303
  • 33
  • 133
  • 164
  • May I know the reason for the conversion? – Praveen Aug 31 '13 at 10:49
  • the returned integer will be an 'id' for possibility matrix, e.g.: possibility matrix is:[sun is shining,I'm happy], id 0 (0,0) means: sun is not shining and I'm unhappy, id 1 (0,1) means: sun is not shining and I'm happy, etc... until id=3 –  Aug 31 '13 at 11:01
  • i don't want a conversion to string, only to int –  Aug 31 '13 at 11:04
0

Is this useful?

var a = 1 << 3; // shift the bits of 1 (0001) 3 places: 1000
if (a == 8) {
    // this block will execute
}

Another example:

var i,
    result = 0,
    len = 4,
    bits = [1, 0, 0, 0];

for (i = 0; i < len; ++i) {
    result = (result << 1) + bits[i];
}

alert(result);

Keep in mind, parseInt is probably faster than this.

Jo Are By
  • 3,293
  • 1
  • 11
  • 11
0

If you want more speed, handle allready the ids as integers, not array, and have bit changed with & and | operations :

 counts = {};
 var a = [1,0,1,0,0,3]; 
 for(var i=0; i<a.length; i++ ){
    var c = counts[a[i]] || 0 ;
    counts[a[i]]= c+1 ;
 }
 console.log(counts); // { 0: 3,  1: 2, 3: 1 }

to set the k-th bit :

id |=  1 << k;

to clear the k-th bit :

id &= !(1 << k);

to swap the k-th bit :

id ^= (1 << k);

to read the k-th bit :

bitK = (id >> k ) & 1;

So you might write small functions to do those operations, with a 99% chance they will get inlined by the javascript engine, it will be much faster than array handling + parseInt.
You might even write this code directly. Maybe in some case you will be able to cache 1 << k, but anyway, shift instructions have a very little cost.

Another advantage is that you can handle several tests in a single instruction, for instance :

var setRequiredMask   = ( 1<<3 |  1<<5 ) ;   // to test if bits 3 and 5 set
var clearRequiredMask = ( 1<<2 | 1 <<4 ) ;   // to test if bit 2 and 4 cleared
var someRequiredMask  = ( 1<<0 | 1 <<6 ) ;   // to test if either bit 0 or bit 6 to be set

var satisfyConditions = ((id & setRequiredMask) == setRequiredMask) && 
                         ((id & !clearRequiredMask) ==0 ) &&
                            (id & someRequiredMask) ;

Here we trade 7 access to memory to quite the same number of boolean operations.
If this test is used in a loop to filter an array, the speed gain is huge.

In the same way you can set / clear / swap several bits in a single instruction, test if one condition set is included in the other, test if they are orthogonal, .... all in a very fast way.

Only limit is that you can handle no more than 32 possibilities with this method.

Then you can store the ids in a typed a typed array, depending on the max number of possibilities, use only a Int8Array or a Int32Array, but i am not sure the gain in performance will be that interesting compared to [].

Syntax :

var arr = new Int8Array( _length_ );

or

var arr = new Int32Array( _length_ );
GameAlchemist
  • 18,995
  • 7
  • 36
  • 59