Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The bitwise Left Shift (<<) operator shifts the binary representation of its first operand to the left by the number of bits specified by its second operand. Zero bits are shifted in from the right. The internal execution mechanics and limits of this operation depend strictly on whether the operands are of type Number or BigInt.
operand1 << operand2

Execution Mechanics: Number Operands

When evaluating standard JavaScript Number types, the engine performs the following sequence of internal conversions:
  1. Operand Truncation: operand1 is converted to a 32-bit signed integer using Two’s complement representation. Any fractional components or values exceeding the 32-bit boundary are truncated.
  2. Shift Masking: operand2 is converted to an unsigned 32-bit integer. JavaScript then applies a bitwise AND mask of 0x1F (31) to this value. This ensures the shift amount is strictly between 0 and 31 bits. For example, shifting by 33 is evaluated as shifting by 1.
  3. Bit Manipulation: The 32-bit representation of operand1 is shifted left by the masked value of operand2. Excess bits shifted off to the left are discarded.
  4. Return Type: The result is evaluated and returned as a standard JavaScript Number representing the new 32-bit signed integer.

Execution Mechanics: BigInt Operands

When evaluating BigInt types, the operator leverages arbitrary precision. Both operands must be BigInt values; mixing Number and BigInt throws a TypeError.
  1. No Truncation: operand1 is not bound by the 32-bit limit. It retains its full precision, and no bits are discarded from the left during the shift.
  2. No Shift Masking: operand2 is not masked by modulo 32. It dictates the exact number of bits to shift, allowing for bit manipulation well beyond the standard 32-bit limit. If operand2 is negative, the operation evaluates as a right shift (>>), effectively shifting the bits to the right by the absolute value of operand2.
  3. Return Type: The result is evaluated and returned as a BigInt.

Mathematical Equivalence

Mathematically, a << b is equivalent to a×2ba \times 2^b.
  • For Number operands, this equivalence only holds if all of the following conditions are met:
    1. a is an integer within the 32-bit signed integer range. Any fractional components are truncated before the shift (e.g., 1.5 << 1 evaluates to 2, whereas 1.5×21=31.5 \times 2^1 = 3). Values exceeding the 32-bit boundary are truncated to their lower 32 bits before the shift operation begins.
    2. b is an integer between 0 and 31 inclusive. Fractional values are truncated during internal conversion (e.g., 1 << 1.5 evaluates to 2, not 2.8282.828). Negative values or values 32\ge 32 are masked by modulo 32 (e.g., 1 << -1 masks to a shift of 31, yielding -2147483648, not 0.50.5).
    3. The result does not overflow. The resulting value must fit within the 32-bit signed integer limit (231-2^{31} to 23112^{31}-1). If an overflow occurs, the sign bit may flip, resulting in a negative number.
  • For BigInt operands, this equivalence holds universally for any integer b. The type dynamically scales to accommodate larger values without overflowing. If b is negative, the operation mirrors mathematical division by powers of two (with flooring applied), effectively acting as a right shift.

Syntax Visualization

// --- Number Operands 

// Example 1: Standard Left Shift
let a = 9;         // Binary: 00000000000000000000000000001001
let res1 = a << 2; // Binary: 00000000000000000000000000100100
console.log(res1); // Output: 36

// Example 2: Shift Masking (Modulo 32 behavior)
let b = 1;
let res2 = b << 33; // 33 & 31 = 1. Equivalent to: 1 << 1
console.log(res2);  // Output: 2

// Example 3: Fractional Operands (Breaks mathematical equivalence)
console.log(1.5 << 1); // Output: 2 (1.5 is truncated to 1. 1 * 2^1 = 2)
console.log(1 << 1.5); // Output: 2 (1.5 is truncated to 1. 1 * 2^1 = 2)

// Example 4: Negative Shift Amounts
let c = 1;
console.log(c << -1);  // Output: -2147483648 (-1 & 31 = 31. Equivalent to: 1 << 31)

// Example 5: 32-bit Overflow
let d = 1073741824; // Binary: 01000000000000000000000000000000
let res5 = d << 1;  // Binary: 10000000000000000000000000000000 (Sign bit flipped)
console.log(res5);  // Output: -2147483648


// --- BigInt Operands 

// Example 6: BigInt Left Shift (No 32-bit truncation or masking)
let e = 1n;
let res6 = e << 33n; // Shifts exactly 33 bits, no masking applied
console.log(res6);   // Output: 8589934592n

// Example 7: BigInt Arbitrary Precision (No overflow)
let f = 1073741824n;
let res7 = f << 1n;  // Scales dynamically, sign bit does not flip
console.log(res7);   // Output: 2147483648n

// Example 8: BigInt Negative Shift (Evaluates as Right Shift)
let g = 4n;
console.log(g << -1n); // Output: 2n (Equivalent to 4n >> 1n)
Master JavaScript with Deep Grasping Methodology!Learn More