3

Anyone able to explain what "|" and the value after does? I know the output for 0 creates sets of 13, the numbers, 3, 2, 1, 0. But what about | 1, or | 2.

var i = 52;
while(i--) {
    alert(i/13 | 0);
}
Jon
  • 428,835
  • 81
  • 738
  • 806
bcm
  • 5,470
  • 10
  • 59
  • 92

4 Answers4

4

It is the bitwise OR operator. There is both an explanation and an example over at MDC. Since doing bitwise OR with one operand being 0 produces the value of the other operand, in this case it does exactly nothing rounds the result of the division down.

If it were written | 1 what it would do is always print odd numbers (because it would set the 1-bit to on); specifically, it would cause even numbers to be incremented by 1 while leaving odd numbers untouched.

Update: As the commenters correctly state, the bitwise operator causes both operands to be treated as integers, therefore removing any fraction of the division result. I stand corrected.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • @Jon It rounds down the result of i/13, isn't that something? – bcm Apr 04 '11 at 00:09
  • @bcm that's because bitwise math can only take place on integers. The bitwise OR isn't responsible for the rounding down - as Jon says that's effectively a no-op – Gareth Apr 04 '11 at 00:10
  • The bitwise operator *is* responsible for the truncation - it forces the LHS to be reduced to an integer, then compared to the RHS (which must be zero in this case), then returned. – RobG Apr 04 '11 at 00:16
  • 1
    Interresting trick... Using side effects hides the purpose of the code, so using `Math.floor` instead would be preferrable to make the code more maintainable. – Guffa Apr 04 '11 at 00:18
  • @Guffa I think if I were using it often enough, it would be understood at first glance and then maintainable :) – bcm Apr 04 '11 at 00:21
  • @Guffa, `Math.floor` isn't *exactly* the same though, when it comes to negative numbers. `Math.floor` is defined as rounding to the *lower* integer. – David Tang Apr 04 '11 at 00:21
  • @RobG: No, the bitwise operator is not responsible for the truncation. The truncation is a side effect of how the values are converted to accomodate what the operators can use as operands. – Guffa Apr 04 '11 at 00:21
  • @Box9: Good point, although the more consistent result from `Math.floor` may actually be desirable. – Guffa Apr 04 '11 at 00:26
  • @Guffa, @bcm: I think `Math.floor` is much preferable -- it *makes the intent clear*. (ab)Using `|` like this was unfamiliar to at least one developer with experience in JS and a fair number of other languages as well. ;) – Jon Apr 04 '11 at 00:40
  • @Jon it looks like it's rounding towards 0, c-style, which is how it was probably implemented – yingted Apr 04 '11 at 01:36
2

This is a clever way of accomplishing the same effect as:

Math.floor(i/13);

JavaScript developers seem to be good at these kinds of things :)

In JavaScript, all numbers are floating point. There is no integer type. So even when you do:

 var i = 1;

i is really the floating point number 1.0. So if you just did i/13, you'd end up with a fractional portion of it, and the output would be 3.846... for example.

When using the bitwise or operator in JavaScript, the runtime has to convert the operands to 32 bit integers before it can proceed. Doing this chops away the fractional part, leaving you with just an integer left behind. Bitwise or of zero is a no op (well, a no op in a language that has true integers) but has the side effect of flooring in JavaScript.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
1

It's a bitwise operator. Specifically the OR Bitwise Operator.

What it basically does is use your var as an array of bits and each corresponding bit is with eachother. The result is 1 if any of them is 1. And 0 if both are 0.

Example:

24 = 11000

10 = 1010

The two aren't of equal length so we pad with 0's

24 = 11000

10 = 01010


26 = 11010

24 | 10 = 26

Best way to learn this is to readup on it.

Khez
  • 10,172
  • 2
  • 31
  • 51
0

That is the bitwise OR. In evaluating the expression, the LHS is truncated to an integer and returned, so | is effecively the same as Math.floor().

RobG
  • 142,382
  • 31
  • 172
  • 209