Why use large numbers directly in your code in javascript? - javascript

If you look at GA(google analytics), 268435455, 2147483647 will do bit operations with these numbers.
AirBnB Also use these numbers and bitwise operators: 3266489909, 2246822507, 3864292196.
example)
function n(e, t) {
return (65535 & e) * t + (((e >>> 16) * t & 65535) << 16) & 4294967295
}
function r(e) {
for (var t = e.length, r = 3432918353, o = 461845907, i = 0, u = void 0, a = t & -4, c = 0; c < a; c += 4) u = e.charCodeAt(c) | e.charCodeAt(c + 1) << 8 | e.charCodeAt(c + 2) << 16 | e.charCodeAt(c + 3) << 24, u = n(u, r), u = u << 15 | u >>> 17, u = n(u, o), i ^= u, i = i << 13 | i >>> 19, i = 5 * i + 3864292196 | 0;
switch (u = 0, t % 4) {
case 3:
u = e.charCodeAt(a + 2) << 16;
case 2:
u |= e.charCodeAt(a + 1) << 8;
case 1:
u |= e.charCodeAt(a), u = n(u, r), u = u << 15 | u >>> 17, u = n(u, o), i ^= u
}
return i ^= t, i ^= i >>> 16, i = n(i, 2246822507), i ^= i >>> 13, i = n(i, 3266489909), i ^= i >>> 16, i >>> 0
}
I am wondering why it works in this way.

268435455 is an odd composite number. It is composed of six distinct prime numbers multiplied together. It has a total of sixty-four divisors.
Prime factorization of 268435455:
3 × 5 × 29 × 43 × 113 × 127
According to wikipedia, the number 2147483647 is the eighth Mersenne prime, equal to 2^31 − 1. It is one of only four known double Mersenne primes. This is the maximum positive value for a 32-bit signed binary integer in computing. The nice part about the number is that 2,147,483,647 remained the largest known prime until 1867.
Similarly other numbers also have the relevant significance in computing.

The first two numbers are bitwise AND masks. Google Analytics is trying to extract a specific number of bits from a number:
00001111 11111111 11111111 11111111 = 268435455
01111111 11111111 11111111 11111111 = 2147483647
00001111 11100000 00000000 00000000 = 266338304
Essentially, it only wants bits where there is a 1 bit—it wants to ignore the 0 bits.It's part of their domain URL hash code.
Those other numbers are mathematical constants used in the hashing algorithm MurmurHash3. Basically they have been statistically generated to provide improved results in the hash function.
If they are not chosen at random (some constants are simply random primes), they are chosen to satisfy certain mathematical/probabilistic criteria. These numbers are often found by running some sort of simulation. In particular, these numbers appear to be derived from a Simulated annealing algorithm.

Related

Javascript get single bit

I have an integer and i want to check if a single bit is 0 or 1.
What is the best practise for doing that?
An example of what i'm doing at this moment:
const myInt = 8; // Binary in 32 Bit integer = 00000000000000000000000000001000
const myBit = myInt << 28 >>> 31; // 00000000000000000000000000000001
if (myBit === 1) {
//do something
}
But i think that this isn't the best methode for doing this.
Have you any better idea?
EDIT:
It is always the same bit i want to check, but the integer is different
myInt = 8+4; // 1100
n = 3;
(myInt >> n) & 0x1; // 1
n = 2;
(myInt >> n) & 0x1; // 1
n = 1;
(myInt >> n) & 0x1; // 0
n = 0;
(myInt >> n) & 0x1; // 0
general solution shifts your number by N bits to right, and applies bitmask, that leaves only last bit, all other are set to 0
I think you can use the bitwise AND
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
my32Bit = 123414123;
twoBy7 = 128;
//check the 7th bit
if (my32Bit & twoBy7) {
// should return 1 if the 7thbit is 1
}
You could take the bit and a left shift << with bitwise AND & operator.
var value = 10,
bit;
for (bit = 0; bit < 4; bit++) {
console.log(bit, !!(value & (1 << bit)));
}

Guidance to understand Base64 encoding algorithm

I found this algorithm on the net but I'm having a bit of trouble understanding exactly how it works. It encodes an Uint8Array to Base64. I would like to understand especially the sections under the comments "Combine the three bytes into a single integer" and "Use bitmasks to extract 6-bit segments from the triplet". I understood the concept of bit shifting used there, but can't understand what's its purpose in those two sections.
function base64ArrayBuffer(bytes) {
var base64 = ''
var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
var byteLength = bytes.byteLength
var byteRemainder = byteLength % 3
var mainLength = byteLength - byteRemainder
var a, b, c, d
var chunk
// Main loop deals with bytes in chunks of 3
for (var i = 0; i < mainLength; i = i + 3) {
// Combine the three bytes into a single integer
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
// Use bitmasks to extract 6-bit segments from the triplet
a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
b = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12
c = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6
d = chunk & 63 // 63 = 2^6 - 1
// Convert the raw binary segments to the appropriate ASCII encoding
base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
}
// Deal with the remaining bytes and padding
if (byteRemainder == 1) {
chunk = bytes[mainLength]
a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
// Set the 4 least significant bits to zero
b = (chunk & 3) << 4 // 3 = 2^2 - 1
base64 += encodings[a] + encodings[b] + '=='
} else if (byteRemainder == 2) {
chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4
// Set the 2 least significant bits to zero
c = (chunk & 15) << 2 // 15 = 2^4 - 1
base64 += encodings[a] + encodings[b] + encodings[c] + '='
}
return base64
}
The first step takes each group of 3 bytes in the input and combines them into a 24-bit number. If we call them x = bytes[i], y = bytes[i+1], and z = bytes[i+2], it uses bit-shifting and bit-OR to create a 24-bit integer whose bits are:
xxxxxxxxyyyyyyyyzzzzzzzz
Then it extracts these bits in groups of 6 to get 4 numbers. The bits of a, b, c, and d correspond this way:
xxxxxxxxyyyyyyyyzzzzzzzz
aaaaaabbbbbbccccccdddddd
Then for each of these 6-bit numbers, it indexes the encodings string to get a corresponding character, and concatenates them into the base64 result string.
At the end there are some special cases to deal with the last 1 or 2 bytes in the input if it wasn't a multiple of 3 bytes long.

What do the operators ">>" (double arrow) and "|" (single pipe) mean in JavaScript?

I saw this in some JS code:
index = [
ascii[0] >> 2,
((ascii[0] & 3) << 4) | ascii[1] >> 4,
((ascii[1] & 15) << 2) | ascii[2] >> 6,
ascii[2] & 63
];
I'd quite like to know what a lot of this means. Specifically ">>", a single pipe "|" and the "&" symbol on the last line?
Much appreciated!
x >> y means to shift the bits of x by y places to the right (<< to the left).
x | y means to compare the bits of x and y, putting a 1 in each bit if either x or y has a 1 in that position.
x & y is the same as |, except that the result is 1 if BOTH x and y have a 1.
Examples:
#left-shifting 1 by 4 bits yields 16
1 << 4 = b00001 << 4 = b10000 = 16
#right-shifting 72 by 3 bits yields 9
72 >> 3 = b1001000 >> 3 = b1001 = 9
#OR-ing
8 | 2 = b1000 | b0010 = b1010 = 10
#AND-ing
6 & 3 = b110 & b011 = b010 = 2
For more information, search Google for "bitwise operators".
>> is a right bitwise shift. It takes the bits and shifts them right n places1. For example, let's examine 35 >> 2:
35 = 100011 shift two places
001000 = 8
And indeed, 35 >> 2 == 8.
| is a bitwise OR. It takes each bit in each operand and ORs them together. You can envision it as a sort of binary addition, but you don't carry when both top and bottom are 1. For example, here's 5 | 3:
5 = 101
3 = 011
| -----
111 = 7
And indeed, 5 | 3 == 7.
Finally, & is a bitwise AND. It takes each bit in each operand, except instead of giving 1 if either one bit OR the other is one, it gives 1 if one bit AND the other are both one. For example, here's 5 & 3:
5 = 101
3 = 011
& -----
001 = 1
Try it out; 5 & 3 == 1.
Some other ones you might want to be aware of are <<, which is a left bitwise shift, and ^, which is an XOR (0 when both bits are the same, 1 if they're different).
1 Actually, it's n modulo 32. 1 >> 32 is 1. Not sure why.
The >> and << operators are a bitwise shift. For example,
11 = 00001011
11 << 3 = 01011000 = 88
It is worth noting that m << n = m * 2^n and m >> n = m / 2^n. This is sometimes used to do very efficient multiplication/division by powers of 2.
The & and | are bitwise and and or respectively.
11 = 00001011
28 = 00011100
11 & 28 = 00001000 = 8
11 = 00001011
28 = 00011100
11 | 28 = 00011111 = 31
While I'm at it, I should mention the ^ operator, which is not used for power, but for bitwise exclusive-or.
11 = 00001011
28 = 00011100
11 ^ 28 = 00010111 = 23
& (Bitwise AND)
| (Bitwise OR)
<< (Left shift)
>> (Sign-propagating right shift)
Examples (from https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators):
Bitwise and:
9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
Left shift (9 << 2 shifts bits of 9 in binary, 2 bits to the left):
9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
Looks like bitwise operators to me:
http://web.eecs.umich.edu/~bartlett/jsops.html
Edit: that ascii array was a dead give away... LOL

what is the difference between >> and >>> operators in JavaScript

Running the following JavaScript code shows 63 in both cases:
alert( 0xff >> 2 );
alert( 0xff >>> 2 );
What is the differences between >> and >>>? Their results seem to be equal.
>> is a bitwise operator, which shift the bits to the right. Any bits at the right are lost.
8 = 1000
^-->1
= 0000 = 0
>>> does the similar thing as >>, but it's unsigned, which means that it ranges from 0 to 232-1 instead of +/- 231-1.
To see the result of my first statement in action, let's use the bitwise operator to floor a number:
1.234 >> 0 = 1 // Ok, fraction lost
1.234 >>>0 = 1 // Ok, fraction lost
-1.23 >> 0 = -1 // Ok, fraction lost
-1.23 >>>0 = 4294967295 // (negative numbers are not within the range)
Math.pow(2,31) >> 0 = -2147483648 // 2^31 is out of range
Math.pow(2,31) >>> 0 = 2147483648
So, when the upper boundary of a range is exceeded, the calculation will continue at its lower range, and vice versa (eg <<). The following illustrates shows what happens when you use n = (n + 1) >> 0, and >>> 0, for n starting at the lowest boundary.
// Signed Unsigned
>> >>>
-2147483647 0
-2147483646 1
... ...
2147483646 4294967294
2147483647 4294967295
-2147483647 0
-2147483646 1
It is the Unsigned Right Shift Operator.
A few links:
Shift with zero fill
Shift with sign

Javascript unsigned short to signed short

I have the following code:
var v = [0xFF, 0xFF];
alert((v[0]<<8) | v[1]);
And it alerts 65535 (the max short value).
How can I treat this byte array as a signed short, and get the signed value of this array.
Assuming the higher bit is the sign:
var sign = v[0] & (1 << 7);
var i = ((v[0] & 0x7F) << 8) | v[1];
if (sign) {
i = -i;
}
http://jsfiddle.net/p4TQw/1/
If you use the Two's complement representation:
var i = (((v[0] << 8) | v[1]) << 16) >> 16);
The 16 bits left shift moves all bits to the left; and the arithmetic 16 bits right shift takes care of the sign while shifting. (Javascript uses 32 bits integers for shift operations.)
http://jsfiddle.net/p4TQw/3/

Categories

Resources