Tech notes

Javascript, HTML, CSS

Apr 14, 2017 | javascript bitwise operators

Javascript bitwise operators and how to use them


The majority of javascript developers knows about bitwise operators and binary representations of numbers. However if you asked them how these operators can be used in the web development you rarely hear a clear answer. So was I until I started to use bitwise operators in one project where we had to grant and control different user roles on the webportal.

But let's start from the very beginning. If you familiar enough with bitwise operators and how they work you can skip to the practice part.

As you may know every number has it binary representation. Javascript has method .toString(2) (argument 2 means base) that allows to convert number from decimal to binary represantation. Also you can use parseInt('0100', 2) method to convert from binary number to decimal.

There are seven bitwise operators in Javascript. Each of this operator works only with binary representation of numbers. Operators with 2 operands (like a&b, a|b) work with pair of bits, where the first bit comes from first operand and the second bit comes from the same position of the second operand.

  1. Operator AND &

    Operator returns 1 only if both bits form pair are 1, otherwise returns 0.

    Decimal number Binary number
    4 0 1 0 0
    & &
    7 0 1 1 1
    4 0 1 0 0
  2. Operator OR |

    Operator returns 1 if at least one bit from pair is 1. In another words, operator returns 0 if both bits from pair are 0, otherwise returns 1.

    Decimal number Binary number
    4 0 1 0 0
    | |
    7 0 1 1 1
    7 0 1 1 1
  3. Operator NOT ~

    Returns the opposite bit. If there is 1 at the i position, result will contain 0 at the i position, if 0 result will contain 1.

    Decimal number Binary number
    9 0000 0000 0000 0000 0000 0000 0000 1 0 0 1
    ~ ~
    -10 1111 1111 1111 1111 1111 1111 1111 0 1 1 0

    Actually in Javascript ~n == -(n+1)

  4. Operator XOR ^

    Returns 1 only if the bits are different, otherwise returns 0.

    Decimal number Binary number
    5 0 1 0 1
    ^ ^
    7 0 1 1 1
    2 0 0 1 0
  5. Left shift (Zero fill) <<

    This operator pushes in from the right one or more zero bits, and the leftmost bits fall off

    Decimal number Binary number
    5 0 0 1 0 1
    5<<1 0 1 0 1 0

    In most cases left shift << n works the same way as multiply number by 2 n times. But you must remember that operators works with 32bit signed numbers, so 10000000000 << 1 will return -1474836480, not 20000000000.

  6. Signed right shift >>

    This is a sign preserving right shift. Copies of the leftmost bit are pushed in from the left, and the rightmost bits fall off:

    Decimal number Binary number
    5 0 0 1 0 1
    5 >> 1 0 0 0 1 0

    In most cases left shift >> n works the same way as divide number by 2 n times.

  7. Zero fill right shift >>>

    One or more zero bits are pushed in from the left, and the rightmost bits fall off. For the postitve numbers works the same as >> operator, because in both cases it pushes zero bits.

    Decimal number Binary number
    -9 1111 1111 1111 1111 1111 1111 1111 0111
    -9 >>> 2 = 1073741821 0011 1111 1111 1111 1111 1111 1111 1101

Practical use

Usually bitwise operators in javascript are used for masks/flags, rarer for work with numbers, RGB(A) values, communication over ports/sockets and for compression and encryption.

  1. Mask

    Let's imagine that we have different users on 1 webportal: admin, editor, author and guest. Understandable, that every role has different access level and different capabilities:

    Role Can Read Can Write Can Delete Can manage users
    Guest 1 0 0 0
    Editor 1 1 0 0
    Author 1 1 1 0
    Admin 1 1 1 1

    As you can see from this table every access can be represented as decimal number:

    • guest   = 1000 (base 2) = 8 (base 10)
    • editor = 1100 (base 2) = 12 (base 10)
    • author = 1110 (base 2) = 14 (base 10)
    • admin  = 1111 (base 2) = 16 (base 10)

    This approach gives us a lot of advantages. First of all it saves memory because we keep all information about granted capabilities in one decimal number, second it simplify the way we can check granted access.

    From the table above we can represent our accesses as a decimal numbers too:

    • If any role has access_manage, it should have 1 on the 1 position (reading from right to left). So we can represent aceess_manage = 0001 (base 2).
    • If any role has access_delete, it sholud have 1 on the 2 position (reading from right to left). So it is access_delete = 0010 (base 2).
    • access_edit = 0100
    • access_read = 1000

    So, if user has access with 1 on 1,2 and 3 position, we can say that he can read, edit and delete article.

    Maybe at first glance this approach seems to be difficult, but if you understand it once, you will notice how it helps to work with roles in easy and elegant way. The only thing you should remember while working with mask, that JavaScript works only with 32 bit numbers.

  2. Work with RGB(A)

    RGBA is one of the color model, with extra alpha channel, which is normally used for opacity. Color can be represented as a single 32-bit unsigned integer that has the alpha sample in the highest 8 bits, followed by the red sample, green sample and finally the blue sample in the lowest 8 bits. Normally we set color in the CSS, smth like background-color:rgba(255,0,0,0.3);, but when you work for example with HTML5 canvas element, you might have to work with color right inside javascript. And bitwise operators definetly will help you here.

  3. Work with numbers and creative solutions

    Some developers prefer to use bitwise operators for rounding numbers. Technically it will work and sometimes it will be faster than Math.floor() or Math.round() But there are some problems in this approach. Let me show you:

    Probably you will remember all these problems and use bitwise operators only when they will work safely, but why don't you use Math.floor() or Math.round()?

    Also several times I saw bitwise operators used for elegant solution of interview questions. Like swap two values, without using additional variable:

    It might work good enough for demostrating your skills in the interview, but in real life it would cause additional problems. How long will junior developer from your team understand the following code:

    In another words bitwise operators give us an amazing force to operate with numbers, but we should use it wisely to keep our code clean and maintainable.


Back to blog