Programming

Logic Gates for Beginners: AND, OR, NOT and a Binary Adder

The basic gates and their truth tables, then a real circuit that adds binary numbers, built from gates in Python and tested against every possible input.

Modern Age Coders Team
Modern Age Coders Team September 28, 2026
7 min read
Logic gates for beginners: symbols for the AND, OR and NOT gates

Every calculation a computer does, from adding two numbers to running a game, comes down to billions of tiny switches called transistors, wired together into logic gates. A logic gate takes one or two inputs that are either 1 (on, true) or 0 (off, false) and produces a single output according to a simple rule. Put enough of them together and you get arithmetic, memory and, eventually, a whole processor.

This guide covers the basic gates and their truth tables, then builds something real from them: a circuit that adds binary numbers. Every gate and circuit is written in Python and tested, including an adder checked against all 256 possible pairs of 4-bit numbers. Logic gates are part of GCSE, IGCSE and Class 11 computer science, and this is a good way to understand them rather than just memorise the tables.

The basic gates

  • AND: the output is 1 only if both inputs are 1. "I will go out if it is sunny AND I have finished my homework."
  • OR: the output is 1 if at least one input is 1. "The alarm sounds if the door OR the window opens."
  • NOT: one input, and the output is the opposite. 1 becomes 0 and 0 becomes 1.
  • XOR (exclusive OR): the output is 1 if the inputs are different. "Either one, but not both."

A truth table lists every possible combination of inputs and the output for each. With two inputs there are only four combinations, so a whole gate fits in four rows. Python's &, | and ^ operators work on 0s and 1s exactly like AND, OR and XOR:

gates.py
from itertools import product

def AND(a, b): return a & b
def OR(a, b):  return a | b
def NOT(a):    return 1 - a
def XOR(a, b): return a ^ b

print(" A B | AND OR XOR")
for a, b in product([0, 1], repeat=2):
    print(f" {a} {b} |  {AND(a, b)}   {OR(a, b)}   {XOR(a, b)}")
Output
A B | AND OR XOR
 0 0 |  0   0   0
 0 1 |  0   1   1
 1 0 |  0   1   1
 1 1 |  1   1   0
Truth tables for AND, OR, XOR and NOT: AND outputs 1 only for inputs 1 and 1; OR outputs 1 unless both inputs are 0; XOR outputs 1 when the inputs differ; NOT flips its single input
Four rows describe a two-input gate completely.

The same logic appears in every programming language as and, or and not in if statements. Boolean logic is named after George Boole, who described this algebra of true and false in the mid-1800s. In 1937, Claude Shannon showed that electrical switching circuits could carry it out, which is the idea every digital computer is built on.

Adding two bits: the half adder

Here is where gates become arithmetic. In binary, adding two single bits gives: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, and 1 + 1 = 10 (that is 2, written as a 0 with a 1 carried). Look at the two output columns: the sum bit is 1 exactly when the inputs differ, which is XOR, and the carry is 1 only when both are 1, which is AND.

Half adder circuit: inputs A and B feed an XOR gate producing the sum bit and an AND gate producing the carry bit; 1 plus 1 gives sum 0 carry 1
Two gates are enough to add two bits.

That pair of gates is called a half adder. It is "half" because it cannot accept a carry coming in from the column to its right. A full adder fixes that by using two half adders and an OR gate, so it adds three bits: A, B and the incoming carry.

Adding whole numbers: the ripple-carry adder

Line up four full adders, one per column, and pass each carry to the next column on the left, exactly like column addition on paper. The code below builds this adder from nothing but AND, OR and XOR, then checks it against Python's own addition for every pair of numbers from 0 to 15:

adder.py
def AND(a, b): return a & b
def OR(a, b):  return a | b
def XOR(a, b): return a ^ b

def half_adder(a, b):
    return XOR(a, b), AND(a, b)                  # (sum bit, carry)

def full_adder(a, b, carry_in):
    s1, c1 = half_adder(a, b)
    s2, c2 = half_adder(s1, carry_in)
    return s2, OR(c1, c2)

def add_4bit(x, y):
    """Add two 4-bit numbers using only the gates above."""
    carry, result = 0, 0
    for i in range(4):                           # rightmost bit first
        bit, carry = full_adder((x >> i) & 1, (y >> i) & 1, carry)
        result |= bit << i
    return result, carry

total, overflow = add_4bit(6, 7)
print(f"0110 + 0111 = {total:04b} (that is 6 + 7 = {total}), carry out {overflow}")

total, overflow = add_4bit(9, 8)
print(f"1001 + 1000 = {total:04b} with carry out {overflow}: 17 does not fit in 4 bits")

wrong = [(x, y) for x in range(16) for y in range(16)
         if add_4bit(x, y)[0] + 16 * add_4bit(x, y)[1] != x + y]
print(f"checked all 256 pairs of 4-bit numbers: {len(wrong)} wrong")
Output
0110 + 0111 = 1101 (that is 6 + 7 = 13), carry out 0
1001 + 1000 = 0001 with carry out 1: 17 does not fit in 4 bits
checked all 256 pairs of 4-bit numbers: 0 wrong
Ripple-carry addition of 6 (0110) and 7 (0111): each column's full adder produces a sum bit and passes its carry left, giving 1101, which is 13
The carry ripples from right to left, one full adder at a time.

6 + 7 comes out as 1101, which is 13, and all 256 pairs are correct. The second example shows overflow: 9 + 8 = 17 needs 5 bits, so a 4-bit adder keeps only 0001 and sets the carry-out flag. Real processors add 64-bit numbers with faster designs than this, but the building blocks are the same gates.

ℹ️

Overflow is a real bug

When a result is too big for the number of bits available, it wraps around. That is why many programming languages have maximum values for whole numbers. Python hides this by growing its numbers automatically, but languages like C, Java and many games do not, which occasionally causes famous glitches such as scores or counters wrapping back to zero or to a negative number.

NAND: one gate to build them all

A NAND gate (NOT AND) outputs 0 only when both inputs are 1. Remarkably, every other gate can be built from NAND gates alone, which makes it a universal gate. That matters in practice, because chip makers can build whole circuits from one very efficient design.

nand.py
from itertools import product

def NAND(a, b):
    return 1 - (a & b)

# Every other gate, built from NAND alone
def NOT(a):    return NAND(a, a)
def AND(a, b): return NOT(NAND(a, b))
def OR(a, b):  return NAND(NOT(a), NOT(b))
def XOR(a, b):
    n = NAND(a, b)
    return NAND(NAND(a, n), NAND(b, n))

ok = all(AND(a, b) == (a & b) and OR(a, b) == (a | b) and XOR(a, b) == (a ^ b)
         for a, b in product([0, 1], repeat=2)) and NOT(0) == 1 and NOT(1) == 0
print("NOT, AND, OR and XOR built only from NAND:", "all correct" if ok else "WRONG")
Output
NOT, AND, OR and XOR built only from NAND: all correct
Every gate built from NAND alone: NOT needs 1 NAND gate, AND needs 2, OR needs 3 and XOR needs 4
Our construction; circuit designers sometimes find cheaper ones.

NOT is a NAND with both inputs joined together. AND is NAND followed by NOT. OR uses NOT on each input, then NAND. XOR takes four NANDs. The code tests every one against its truth table. NOR (NOT OR) is also universal.

Exam tips

  1. Learn the rules, not just the tables. "AND needs both, OR needs at least one, XOR needs exactly one" lets you rebuild any table in seconds.
  2. Work through circuits one gate at a time, writing the output of each gate before moving on. Add a column to the truth table for each intermediate result.
  3. Count the rows: 2 inputs means 4 rows, 3 inputs means 8, n inputs means 2n.
  4. Know the symbols used by your exam board, and the notation for expressions such as A AND (NOT B).

A computer is billions of switches following three simple rules. Everything else is how they are wired together.

How we teach it

Logic gates reward a principle on our how we teach page: tracing line by line until every step can be predicted. Working through a circuit gate by gate, writing each output before moving on, is exactly that. Learning by building helps too: a working adder made from gates makes binary arithmetic concrete. Our GCSE computer science tutoring runs one to one or in small groups of 5 to 10.

Frequently asked questions

Logic gates are tiny circuits that take one or two inputs, each 0 or 1, and produce an output by a fixed rule. AND, OR and NOT are the basic ones. Combined in large numbers, they let computers do arithmetic and make decisions.

A table listing every possible combination of inputs to a gate or circuit, and the output for each. A two-input gate has 4 rows; a circuit with n inputs has 2 to the power n rows.

OR outputs 1 if at least one input is 1, including when both are. XOR outputs 1 only when the inputs are different, so it gives 0 when both inputs are 1.

A half adder uses an XOR gate for the sum bit and an AND gate for the carry. Full adders also accept an incoming carry, and chaining one per bit, passing each carry to the next, adds whole binary numbers.

Because any other logic gate, and therefore any digital circuit, can be built using only NAND gates. NOR gates are universal too.

Yes. GCSE computer science specifications from the major exam boards include logic gates, truth tables and simple logic circuits, and they also appear in IGCSE and Class 11 CBSE and ICSE computer science.

In modern chips, each gate is made from a few transistors, microscopic electronic switches. A modern processor contains billions of transistors.

Modern Age Coders Team

About Modern Age Coders Team

Expert educators making coding and maths clear for ages 6 to 67.

Keep exploring Modern Age Coders

More from the blog

Free resources

From the blog

Start here

Ask Misti AI
Chat with us
Enroll Watch Class Priority Demo Enrol Book a Demo Watch Class WhatsApp Book demo today