4

How does 5.5 | 0 === 5 work?

Is | 0 in this context the bitwise OR I suspect it to be? If so, why does it cut off everything after the point?

tckmn
  • 52,184
  • 22
  • 101
  • 145
ben
  • 4,697
  • 4
  • 24
  • 51
  • @Cristy in this case, I'm not sure it's a duplicate, because code that actually looks like that is probably not really trying to simply do a "floor" operation. That's effectively what's happening, of course. – Pointy Jan 20 '14 at 21:39

3 Answers3

11

Bitwise operators always coerce operands to 32-bit integers.

The operation is interpreted as

5.5 | (0 === 5)

which is

5.5 | false

which is coerced to

5.5 | 0

Now the 5.5 is converted to a 32-bit integer, so we have

5 | 0

which is 5.

The relational operators bind more tightly than the bitwise operators which can be confusing. If you want to compare the result of a bitwise operator (unlike, say, an addition or multiplication), you have to parenthesize explicitly.

Pointy
  • 371,531
  • 55
  • 528
  • 584
  • Ha, what a coincidence :) Is "Bitwise operators always coerce operands to 32-bit integers" true in general i.e. for other languages too? – ben Jan 20 '14 at 21:38
  • Good catch, I had assumed OP was talking about `5.5 | 0` yielding `5` as a result and had just phrased it badly. – p.s.w.g Jan 20 '14 at 21:42
  • @user2820379 Some languages do this, but many do not. More strongly typed languages like C# don't even define the bitwise operators on non-integer types. e.g. `"foo"|"bar"` results in a compiler error. – p.s.w.g Jan 20 '14 at 21:44
4

The | performs operator is a bitwise OR operation, implicitly converting each operand to an 32-bit integer. As Pointy notes, 5.5 | 0 === 5 is parsed as 5.5 | (0 === 5), which evaluates to 5.5 | false.

According to the specification:


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.

And since X | 0X for any integer, it is effectivly just removing any fractional part of the number.

Community
  • 1
  • 1
p.s.w.g
  • 136,020
  • 27
  • 262
  • 299
4

It doesn't equal true, it just doesn't equal false.

5.5 | 0 === 5 

returns

5
PW Kad
  • 14,816
  • 7
  • 47
  • 82
  • Operator precedence. `(5.5 | 0) === 5` returns true – Yuriy Galanter Jan 20 '14 at 21:36
  • That's only because `0 === 5` is false, is coerced to `0`, and then `5.5 | 0` is `5`. – tckmn Jan 20 '14 at 21:37
  • @YuriyGalanter The expression `5.5 | 0 === 5` returns `5` for me, while `(5.5 | 0) === 5` returns `true`. I think we need to confirm which expression we're/the question is talking about. – ajp15243 Jan 20 '14 at 21:39
  • @ajp15243 the `===` operator is higher-precedence than `|`, so the comparison is carried out first. – Pointy Jan 20 '14 at 21:40
  • @Pointy I understand that. What I'm pointing out is that the OP's question was about the expression without `( )`, while Yuriy seems to be trying to make a point with the expression that includes `( )`, which is obviously a different expression and not necessarily what is being asked about. If there's a point here with the `( )` expression, I'm not seeing it. – ajp15243 Jan 20 '14 at 21:42
  • @ajp15243 ah OK, right. Questions like this make me really wonder who's typing in code like this :) – Pointy Jan 20 '14 at 21:48
  • @Pointy lol Agreed. After re-reading, I think I may now see the point Yuriy was trying to make, and I think my confusion, plus other comments around this question, are because people are interpreting what was typed in the question in subtly different ways. – ajp15243 Jan 20 '14 at 21:50
  • "It doesn't equal true". Well, `5` **is** truthy. ;-) – RobG Jan 21 '14 at 00:03
  • @robg Truthy !== true, as 5 !== true, but because 5 !== false, it results on true – PW Kad Jan 21 '14 at 18:13