2

I am working on parsing some binary files, I have them opened and in an ArrayBuffer.

In the particular file structure I am reading, there are a number of bits which are boolean and I can check whether they are checked with:

(flag & 1) != 0; // bit 0 
(flag & 2) != 0; // bit 1 
(flag & 4) != 0; // bit 2 

etc.

However, I am having trouble getting the values of the bits followed. They span over multiple bits (for example bits 4-6) and consist of an integer value from 0-7.

How are multiple bits read like that? I understand that this isn't as much of a JavaScript question than that of how bits and bitwise operators work.

2 Answers2

4

Assuming you want 4-6 bits from a byte like this:

76543210
 ^^^

You would construct a bit mask like this:

0x70

which means:

01110000

And then you would & that with the number and shift to right 4 times:

( byte & 0x70 ) >> 4
//Number between 0-7
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • In javascript, I would still always recommend shifting with >>> instead of >>. (In C, cast to unsigned before shifting). – selbie Dec 31 '11 at 12:08
  • @selbie I didn't mention this in my question, but if I've read the byte as Uint, it will be unsigned already? –  Dec 31 '11 at 12:11
  • the & already drops out potential sign bit, which is in position 31 – Esailija Dec 31 '11 at 12:12
  • There is no such thing as an "unsigned integer" in javascript. There is a "number" type, and that is it. So Mike, I'm not sure how you are reading a UINT in javascript. @Esailija - where is the behavior of & operator making the value unsigned referenced? Or is it just a side effect of javascript not really having an upper bound on number types? – selbie Dec 31 '11 at 12:19
  • @selbie, all numbers are converted to signed 32 bit integers (with exception >>>, converts to unsigned 32) in javascript before the bitwise operation. So if it was a signed 8 bit integer `-127`, it would be `0xFFFFFF81`before the & operation, and `0x0000000` after in that case. In any case, the sign bit is not persisted through the AND. – Esailija Dec 31 '11 at 12:23
  • In the example above, the sign-bit is not persisted, because you are masking it out with 0x00000070. Type "(0xffffffff & 0x80000000) >> 4" into the javascript console - you get a negative number. – selbie Dec 31 '11 at 13:08
  • @selbie yes I was referring to `& 0x70` as __the__ AND operation. Since sign bit is always in position 31, it doesn't persist through that. – Esailija Dec 31 '11 at 13:10
  • Right, that's my point. As a general rule, in javascript, use >>> so you don't have to think about if it's safe to assume if the sign-bit is getting masked out or not. – selbie Dec 31 '11 at 18:29
  • @Esailija Nice answer you got there. ```( byte & 0x70 ) >> 4``` I am curious how do you get a `byte` to be operated on by bitwise `&` operator in javascript? Bitwise operator always converts its operands into 32-bit numbers before operating. So I am not clear how would the above code work? – Gaurang Patel Mar 20 '17 at 07:18
2

Assuming the least significant bit is at position "0", and you want the 3-bit integer between bit positions 4-6.

var value = (flag >>> 4) & 0x0007;

In other words, right shift "flag" 4 bits to the right, such that bits 4-6 get shifted into positions 0-2. Then mask off just the last three bits (binary 111 = decimal 7).

selbie
  • 100,020
  • 15
  • 103
  • 173
  • 1
    I updated my answer below to use the javascript "unsigned shift" operator (>>>) instead of the more usual >> operator. Always a good idea in any language to make sure you are doing bit-shifting on unsigned types, because you might get a side-effect if the value being shifted is negative (1's imported on the left side instead of 0's). – selbie Dec 31 '11 at 12:05