Looking at the following examples, it looks like `Math.floor(x)`

is equivalent to `x | 0`

, for `x >= 0`

. Is that really true? If yes, why? (or how `x | 0`

is calculated?)

```
x = -2.9; console.log(Math.floor(x) + ", " + (x | 0)); // -3, -2
x = -2.3; console.log(Math.floor(x) + ", " + (x | 0)); // -3, -2
x = -2; console.log(Math.floor(x) + ", " + (x | 0)); // -2, -2
x = -0.5; console.log(Math.floor(x) + ", " + (x | 0)); // -1, 0
x = 0; console.log(Math.floor(x) + ", " + (x | 0)); // 0, 0
x = 0.5; console.log(Math.floor(x) + ", " + (x | 0)); // 0, 0
x = 2; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 2.3; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 2.9; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 3.1; console.log(Math.floor(x) + ", " + (x | 0)); // 3, 3
```

This can be useful to perform integer division in Javascript: `(5 / 3) | 0`

rather than `Math.floor(5 / 3)`

.

Bitwise operators convert numbers to a 32-bit sequence. So the alternatives you’re suggesting will only work with positive signed 32-bit floats, i.e. numbers from `0`

to `+2,147,483,647`

(`2^31-1`

).

```
Math.floor(2147483646.4); // 2147483647
2147483646.4 | 0; // 2147483647
// but…
Math.floor(2147483648.4); // 2147483648
2147483648.4 | 0; // -2147483648
```

Another difference: if `x`

is not a number, the result of `x | 0`

might be different than that of `Math.floor(x)`

.

```
Math.floor(NaN); // NaN
NaN | 0; // 0
```

Other than that, the result should be similar to that of `Math.floor()`

, as long as a positive number is used.

Here are some more examples + performance tests: http://jsperf.com/rounding-numbers-down

As per ECMAScript spec, §11.10 Binary Bitwise Operators:

```
Semantics
The production A : A @ B, where @ is one of the bitwise operators in the productions
above, is evaluated as follows:
1. Let lref be the result of evaluating A.
2. Let lval be GetValue(lref).
3. Let rref be the result of evaluating B.
4. Let rval be GetValue(rref).
5. Let lnum be ToInt32(lval).
6. Let rnum be ToInt32(rval).
7. Return the result of applying the bitwise operator @ to lnum and rnum. The result
is a signed 32 bit integer.
```

This is how `x | y`

is calculated:
`x`

and `y`

are parsed to `Int32`

and then apply the `|`

operator to them.

Bitwise operations in JS are 32bit, that is the float is first "cast" into an "int".

`"2.6" | 0 = 2`

suggests that `parseInt`

is being called.

The vertical bar is the bitwise-or operator. Since the bits of 0 are all zero, `x|0`

is in theory a no-op. But in order to evaluate it the operands must be integers, so `x`

must be converted from floating point into an integer first. The conversion is made by eliminating the fractional part, so yes, for some x >= 0 we have `x|0`

== `Math.floor(x)`

.

Note that the result depends on the size and signness of the internal integer type. For example you get:

```
2147483648|0 == -2147483648 // 0x80000000
Math.pow(2,32)|0 == 0 // the lowest 32 bits are all 0
```

(x | 0) removes the bits after the ".", so we can get the next true relation:

```
x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;
```

x >> 0 has the same effect as x | 0, so :

```
x >> 0 = x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;
```

©2020 All rights reserved.