0

I'm using some code in JS and I bumped into these (unrelated) expressions:

1) var r = (d + Math.random() * 16) % 16 | 0;

2) return c === 'x' ? r : (r & 0x3 | 0x8);

I read some about bitwise operators but it does not help in this context. Can somebody explain (preferably step-by-step) how do they work ? How this two expressions are logically evaluated and run ?

Thanks in advance.

Huqe Dato
  • 235
  • 1
  • 16
  • IT IS NOT a duplicate, I was asking for a concrete case/example! Your link is to a general lesson. – Huqe Dato Jun 07 '17 at 20:30
  • 1
    The first seems to just be a trick to truncate the number. `(2.34 | 0) === 2`. The second looks quite normal... what specifically are you having trouble understanding there? – user94559 Jun 07 '17 at 20:30
  • 2
    There are many questions about bitwise operators here on SO and [across the internet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators). Please include what you have gleaned from that research you've done. Otherwise this question is "read this code for me". I mean you could just take each operation, make it a separate line, and debug each one to see what it does. – Heretic Monkey Jun 07 '17 at 20:30
  • Note that the duplicate is useful to understand `r & 0x3 | 0x8` it doesn't doesn't seem to cover `... | 0` which is just a hacky substitute for `Math.floor`. – apsillers Jun 07 '17 at 20:31
  • The second example looks more like a ternary operator – j08691 Jun 07 '17 at 20:32
  • ... Otherwise this question is "read this code for me". Exactly, if you are kind... – Huqe Dato Jun 07 '17 at 20:32
  • 1
    Do you have a basic understanding of binary representation? Not asking to be condescending, just trying to get a grasp of what kind of answer you are looking for. – 01010011 01000010 Jun 07 '17 at 20:33
  • 5
    Misusing the website and hoping someone kind is willing to satiate you doesn't exactly shield you from those trying to enforce the rules. In some cases someone may answer a question of this broad nature, however you shouldn't be surprised at the closure votes and rule-reminders. – Tyler Roper Jun 07 '17 at 20:33
  • `| 0` is a “type annotation” for an integer in JavaScript. – Sebastian Simon Jun 07 '17 at 20:33
  • 2
    Right, either this is a duplicate, or it is off-topic. – Stephan Bijzitter Jun 07 '17 at 20:34
  • No, I don't know much about binary representation... only basics. – Huqe Dato Jun 07 '17 at 20:35
  • 1
    `r & 0x3` produces a number composed only least-significant and next-least-significant bits (i.e., the `1`- and `2`-value positions in the binary representation) of `r`; it will either by binary `00`, `01`, `10`, or `11` (i.e., 1, 2, 3, or 4). The following `| 0x8` also sets the fourth bit (i.e., the `8`-value bit) to `1`. Exactly what part of that isn't clear based on the duplicate suggested? (Not a rhetorical question -- expressing what's different about your question versus the information already supplied in the proposed duplicate is necessary to understand and answer your question.) – apsillers Jun 07 '17 at 20:35

2 Answers2

1

Basically you could do a brute-force approach and look which values are returned in an object, one for c === '' and c === 'x'.

function x() {
    var r = (d + Math.random() * 16) % 16 | 0;  // the last or returns an integer value
    return c === 'x' ? r : (r & 0x3 | 0x8);
}

var d = 0,  // does not matter, because of % operator
    c = '',
    i,
    values = {},
    v;

for (i = 0; i < 1e6; i++) {
    v = x();
    values[v] = values[v] || 0;
    values[v]++;
}
console.log(values);

values = {};
c = 'x';
for (i = 0; i < 1e6; i++) {
    v = x();
    values[v] = values[v] || 0;
    values[v]++;
}
console.log(values);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Just wanted to point out, that `d` matters. If `d === undefined` you will get a different result. – Alex Pakka Jun 07 '17 at 20:49
  • @AlexPakka, i was assuming that `d` contains a numerical value. – Nina Scholz Jun 07 '17 at 20:50
  • Valid assumption, but then `| 0` at the end of line 1 would not make any sense. I have two theories: it was an interview question or the developer of this code wanted to confuse a future maintainer as much as possible. – Alex Pakka Jun 07 '17 at 20:54
  • 1
    @AlexPakka, it looks like that is part of generating a UUID/GUID. [source1](https://jsfiddle.net/briguy37/2MVFd/), [source2](https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript) – Nina Scholz Jun 07 '17 at 21:00
  • @NinaSholz wow. Vielen Dank für den Hinweis! I feel better now that I did not help anyone to cheat. – Alex Pakka Jun 07 '17 at 21:09
  • @AlexPakka, guys, it was a piece of an exam I've failed today.... :( – Huqe Dato Jun 07 '17 at 21:17
1

First statement has almost nothing to do with bitwise operators. It simply means:

  • assign random number between 0 and 15 to r, but if variable d is undefined, give me 0. It uses math fact that modulo 16 of any number gives you a result in [0..15] range and bitwise OR with 0 is an identity operation with one exception. JavaScript logic of handling undefined dictates that without | 0 when d is undefined you will get NaN as a result in r.

Second statement does use bitwise operators.

  • x & 0x03 is the same as x BITWISE_AND 0011 and it returns lowest 2 bits of x. x | 0x8 always sets 4th bit. So, c will be a 10.. where dots are the lowest 2 bits of r. Of course, it will happen only if c is a string and equals x.

I strongly suggest you read https://www.w3schools.com/js/js_bitwise.asp and do some experimentation.

Alex Pakka
  • 9,466
  • 3
  • 45
  • 69