Suppose I wrote the codes like this following:
console.log((5/3)|0)
The result is 1.
However why? In my mind, |0
means +0
. But why can it cancel off the fractional part?
Can anyone give me a full understanding of that by showing its inner binary digits and how can I get that result step by step?
Here, the operator |
is bitwise OR, and involves analyzing the bits of that float the computer internally stores. This is because all floats are really expressed as 32 bits.
The value 0
has all 32 bits equal to 0
. A 1
or 0
bit OR 0
will still be 1
, 0
respectively, so all 32 bits remain the same.
Normally, all JS numbers are doubles (64-bit floating point numbers). Beware that before the bitwise OR is completed, the JS compiler will convert the floating-point operands into its signed int form temporarily, meaning that it could result in a different value, notably the truncating of the decimal part. After the bitwise operation is done, JS will convert it back to floating-point numbers.
Here is an example of how a float value is truncated to a signed int after bitwise OR:
var x = 100/3.0;
console.log(x); // outputs 33.333333333333336
console.log(x|0); // outputs 33 (no decimal)
There is a Mozilla documentation about the Javascript bitwise operators.
"The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format."
Step by step, the bits are (let them be single-precision floats for brevity, JS decimals are doubles):
100 / 3: 0 10000100 0000101 01010101 01010101
100 / 3
is casted to 32-bit int form before bitwise OR, yielding integer 3333 : 0000 0000 0000 0000 0000 0000 0010 0001
0 : 0000 0000 0000 0000 0000 0000 0000 0000
33 | 0 : 0000 0000 0000 0000 0000 0000 0010 0001
yielding integer 33 again.