Invalid Date

Example

Let’s take a look at a single line of code from splitmix32, a pseudo-random number generator that operates on 32 bit values:

z = (z ^ (z >> 16)) * 0x85ebca6b;

Ignoring the number of theoretical aspects of why the algorithm is performing these operations — this is a fairly straightforward line of code in C, and maybe other languages that have adopted C semantics, like Rust. This code takes our variable z - in this case a 32 bit unsigned integer - and xors it with the value of z shifted right by 16 bits. We then multiply that by the value 0x85ebca6b.

In this example, let’s start with a value of z of 0xc0ffee51 - this line of code will set z to 0x4537ceba. This same line of code happens to be valid JavaScript - but running it against our initial value of 0xc0ffee51 gives us 0x20f51f3bb9a2ce00... a very different result.

There are several problems here: first, the right shift operator in JavaScript (>>) is an arithmetic right shift — or a signed right shift, which treats z as a two’s complement signed integer. What we want is the unsigned right shift operator (>>>). Next, the multiplication operator in JavaScript (*) operates on Numbers ,which are 64-bit IEEE 754 floating-point numbers. So multiplying two large 32-bit numbers can give you a number that is larger than 32 bits. Instead, we can look to [Math.imul](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul), which gives 32-bit multiplication with C-like semantics.

With those two corrections in mind, the same line of code in JavaScript becomes:

z = Math.imul((z ^ (z >>> 16)), 0x85ebca6b);

This is not a particularly complicated change, but it is a change, and a rather subtle one. If you’re accustomed to thinking about bitwise manipulation in terms of C semantics, it’s easy to get this wrong and when you do, it’s hard to find the problem.