The operators themselves
The bitwise operators in JS are
They represent the standard bitwise operations present in various programming languages.
The corresponding MDN page is full of helpful examples on the topic.
The only thing I want to remark on the operators themselves is that in JS we have two distinct operators for
sign-propagating right shift (
<<) or zero-fill right shift (
So the bitwise operators work on integers the way they do in other languages as well.
The MDN page is not super clear on how operands are converted to integers.
0.1 & 0.5 computed for example?
We need to consider the language specification for that.
Bitwise operators are defined in section 12.12 of the EcmaScript 2017 language specification.
How operands have to be evaluated is defined by the semantics section 12.12.32.
It looks like both operands are converted to a 32 bit integer using the operation
By going to its specification, we find the following definition:
- Let number be ? ToNumber(argument).
- If number is , , , , or , return .
- Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
- Let int32bit be modulo .
- If int32bit , return int32bit ; otherwise return int32bit.
So we see that bitwise operators do not let us access bits of the underlying representation at all. Instead operands are mapped to 32 bit integers whose bits are (conceptually) used for the operation. Let’s verify that the algorithm above does not change values from the 32 bit two’s complement range, so we get the expected behavior of bitwise operators.
The 32 bit integers run from to . Let be an arbitrary one of those. We already have an integer, so steps 1 and 3 are doing nothing to it. Step 2 will return if , which satisfies our requirements. So we consider only and steps 4 and 5.
If step 4 and 5 will do nothing, because the highest possible value for is still smaller than and . However, a negative will be mapped to a positive one by the modulo operation in step 4. But because negative values are mapped to large positive values, step 5 reverts that. More precisely:
Therefore step 5 will return . So indeed, bitwise operations on 32 bit integer values will yield the same results as in languages that have 32 bit integers. We can learn two things from this, one useful and one rather useless:
Since the operation
ToNumbermaps anything (that I’ve tried so far) to a number, we can use bitwise operators not only on numbers but also strings or objects. This is the rather useless one, yup.