Module F-5·16 min read

AND/OR/XOR/shift operations, bit flags for permissions and feature toggles, and fast arithmetic tricks.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module F-5 — Bit Manipulation: Flags, Permissions, and Fast Math

What this module covers: Every number in your program is already a sequence of bits — this module is about working with that sequence directly instead of through the abstraction of arithmetic. It covers the core bitwise operators, how a single integer can store dozens of independent boolean flags, and the handful of bit tricks that show up in permission systems, feature flags, and performance-sensitive code.


Binary, Briefly

Every integer in memory is a sequence of bits — 1s and 0s. The number 13 is 1101 in binary: reading right to left, that's 1 + 0 + 4 + 8 = 13 (each position worth double the one before it, starting at 1). You don't need to convert by hand often, but recognizing that an integer is just a fixed-width row of switches is the entire mental model this module builds on.

typescript

The Bitwise Operators

Five operators work directly on the bit representation, comparing or shifting bit-by-bit rather than treating the number as a single value:

typescript

Analogy: Think of AND, OR, and XOR as three different ways of comparing two rows of light switches, position by position. AND: a light turns on only if both switches at that position are on. OR: on if either is on. XOR: on only if they disagree — one on, one off.

XOR is the one worth sitting with, because its "only when they disagree" property is what makes it useful for toggling: XOR-ing a bit with 1 flips it, and XOR-ing a bit with 0 leaves it unchanged — which is exactly the mechanic bit flags rely on next.


Bit Flags: One Integer, Many Booleans

Instead of storing five separate boolean fields, you can pack up to 32 independent true/false facts into a single integer, one per bit position — commonly called a bitmask.

typescript

Each permission gets its own bit position (1 << 0, 1 << 1, 1 << 2...), so combining them with | never overwrites another flag — they occupy entirely separate positions in the same integer. Checking with & isolates just that one bit; every other bit is masked out to zero, so the comparison only ever reflects the flag you asked about.

Why this matters in production: a role/permission system with a handful of booleans stored as five separate boolean columns costs five columns, five reads, and five separate comparisons every time you check "can this user do X." As a single integer, storage is one column, and checking any combination of permissions is a single bitwise comparison — no matter how many flags you add, later, without a schema migration for each one.


Feature Flags as Bits

The same pattern shows up for feature toggles — a single integer field on a user or tenant record can represent "which experimental features are enabled for this account," checked and updated exactly like the permission bits above:

typescript

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.