back to blog
The Hidden Math Behind Everyday Code (with C++ Examples)

The Hidden Math Behind Everyday Code (with C++ Examples)

Exploring how mathematical concepts like modular arithmetic, boolean logic, and floating-point precision appear in everyday programming. A deep dive into the math that makes our code work.

Maruf Hossain
July 8, 2025
10 min read

TL;DR

Discover the mathematical foundations powering everyday programming: modular arithmetic in hash functions, boolean logic in conditionals, graph theory in algorithms, and linear algebra in graphics. Complete with runnable C++ examples.

Who This Is For

  • Programmers wanting to understand the math behind their code
  • Students connecting computer science theory to practice
  • Anyone curious about mathematical thinking in software

Prerequisites: Basic programming experience, high school algebra, willingness to think mathematically.


When writing code, we often think we're just "telling the computer what to do." But beneath the surface, there's a lot of math making things possible. From modular arithmetic to logic, graph theory to floating-point precision — math is everywhere in code.

Let me show you a few places where it hides in plain sight.

What You'll Learn

This post explores how mathematical concepts like modular arithmetic, boolean logic, floating-point precision, graph theory, and linear algebra appear in everyday programming with practical C++ examples.

šŸ” Modular Arithmetic in Hash Functions

Many hash tables and encryption techniques rely on modulo math — wrapping numbers around a fixed range.

Let's take a basic hash function for storing student IDs in an array of size 10:

#include <iostream>
using namespace std;

int simpleHash(int studentId) {
    return studentId % 10;
}

int main() {
    int id = 123456;
    cout << "Hashed index: " << simpleHash(id) << endl;  // Output: 6
    return 0;
}

Environment Used

Last tested with: GCC 13.x, C++17 standard, tested on Windows/Linux/macOS

Here, % 10 wraps the ID into a bucket between 0 and 9. That's classic modular arithmetic — like a clock where 13 o'clock becomes 1.

Limitations & Trade-offs

  • Hash collisions: Simple modulo creates clustering and collisions - Distribution: Poor randomness with certain input patterns - Security: Predictable outputs vulnerable to attacks - Performance: Linear probing needed for collision resolution

šŸ’” Boolean Logic = Set Theory

Every time you write conditions like if (x && y), you're applying set theory — intersections, unions, and complements.

bool isStudent = true;
bool hasPaidFees = false;

if (isStudent && hasPaidFees) {
    cout << "Access granted." << endl;
} else {
    cout << "Access denied." << endl;
}

This is equivalent to:

  • AND (∩) = both sets overlap
  • OR (∪) = either one is true
  • NOT (¬) = exclusion

You're building logic gates — the same foundational ideas behind digital circuits.

šŸ” Precision Errors and Floating-Point Math

Math also reminds us that computers are not perfect with decimals:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double a = 0.1 * 3;
    double b = 0.3;

    if (abs(a - b) < 1e-9) {
        cout << "Equal" << endl;
    } else {
        cout << "Not equal" << endl;
    }
    return 0;
}

Even though mathematically 0.1 Ɨ 3 = 0.3, this can fail due to binary floating-point precision issues. So instead of a == b, we check if they're close enough — a common numerical analysis trick.

Why This Happens

Computers store floating-point numbers in binary, and some decimal fractions (like 0.1) can't be represented exactly in binary, leading to small rounding errors.

šŸ•øļø Graph Theory in Social Networks

Graph theory appears whenever you're modeling relationships between entities. Here's a simple social network example:

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

class SocialNetwork {
private:
    unordered_map<string, vector<string>> friends;

public:
    void addFriendship(const string& person1, const string& person2) {
        friends[person1].push_back(person2);
        friends[person2].push_back(person1);  // Undirected graph
    }

    bool areFriends(const string& person1, const string& person2) {
        if (friends.find(person1) == friends.end()) return false;

        for (const string& friend_name : friends[person1]) {
            if (friend_name == person2) return true;
        }
        return false;
    }

    int getFriendCount(const string& person) {
        return friends[person].size();
    }
};

int main() {
    SocialNetwork network;
    network.addFriendship("Alice", "Bob");
    network.addFriendship("Alice", "Charlie");
    network.addFriendship("Bob", "David");

    cout << "Alice has " << network.getFriendCount("Alice") << " friends" << endl;
    cout << "Are Alice and Bob friends? " << (network.areFriends("Alice", "Bob") ? "Yes" : "No") << endl;

    return 0;
}

This is a graph where:

  • Vertices = people
  • Edges = friendships
  • Degree = number of friends
  • Path = chain of friendships between two people

Real Applications

This same graph structure powers social media platforms, recommendation systems, and network analysis tools.

šŸ“Š Linear Algebra in Image Processing

Linear algebra is everywhere in computer graphics and image processing. Here's a simple example of matrix operations for image transformations:

#include <iostream>
#include <vector>
using namespace std;

class Matrix {
private:
    vector<vector<double>> data;
    int rows, cols;

public:
    Matrix(int r, int c) : rows(r), cols(c) {
        data.resize(r, vector<double>(c, 0));
    }

    void set(int i, int j, double value) {
        data[i][j] = value;
    }

    double get(int i, int j) const {
        return data[i][j];
    }

    // Matrix multiplication
    Matrix multiply(const Matrix& other) const {
        if (cols != other.rows) {
            throw runtime_error("Matrix dimensions don't match");
        }

        Matrix result(rows, other.cols);
        for (int i = 0; i < rows; i++) {
            for (int j= 0; j < other.cols; j++) {
                double sum= 0;
                for (int k= 0; k < cols; k++) {
                    sum = data[i][k] * other.data[k][j];
                }
                result.set(i, j, sum);
            }
        }
        return result;
    }

    // 2D rotation matrix
    static Matrix rotation2D(double angle) {
        Matrix rot(2, 2);
        double rad= angle * 3.14159 / 180.0;
        rot.set(0, 0, cos(rad));
        rot.set(0, 1, -sin(rad));
        rot.set(1, 0, sin(rad));
        rot.set(1, 1, cos(rad));
        return rot;
    }
};

int main() {
    // Create a point (x, y)
    Matrix point(2, 1);
    point.set(0, 0, 3);  // x = 3
    point.set(1, 0, 4);  // y = 4

    // Rotate by 90 degrees
    Matrix rotation= Matrix::rotation2D(90);
    Matrix rotated= rotation.multiply(point);

    cout << "Original point: (" << point.get(0, 0) << ", " << point.get(1, 0) << ")" << endl;
    cout << "Rotated point: (" << rotated.get(0, 0) << ", " << rotated.get(1, 0) << ")" << endl;

    return 0;
}

This demonstrates how rotation matrices work in computer graphics. The same principles apply to scaling, translation, and more complex transformations.

Beyond 2D

In 3D graphics, we use 4x4 matrices for transformations, and the math gets even more interesting with quaternions for smooth rotations.

šŸŽÆ Combinatorics in Algorithm Design

Combinatorics helps us understand the complexity of algorithms. Here's a classic example:

#include <iostream>
#include <vector>
using namespace std;

// Calculate factorial (n!)
long long factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

// Calculate combinations C(n, r) = n! / (r! * (n-r)!)
long long combination(int n, int r) {
    if (r > n) return 0;
    return factorial(n) / (factorial(r) * factorial(n - r));
}

// Generate all possible combinations
void generateCombinations(const vector<int>& arr, int r, vector<int>& current, int start) {
    if (current.size() == r) {
        // Print current combination
        cout << "{ ";
        for (int i= 0; i < current.size(); i++) {
            cout << current[i];
            if (i < current.size() - 1) cout << ", ";
        }
        cout << " }" << endl;
        return;
    }

    for (int i= start; i < arr.size(); i++) {
        current.push_back(arr[i]);
        generateCombinations(arr, r, current, i + 1);
        current.pop_back();
    }
}

int main() {
    vector<int> arr = {1, 2, 3, 4, 5};
    int r = 3;

    cout << "Total combinations C(" << arr.size() << ", " << r << ") = "
         << combination(arr.size(), r) << endl;

    cout << "All combinations:" << endl;
    vector<int> current;
    generateCombinations(arr, r, current, 0);

    return 0;
}

This shows how combinations work in practice. The number of ways to choose r items from n items is C(n, r) = n! / (r! * (n-r)!).

Complexity Warning

The factorial function grows extremely fast! For large numbers, we'd need more efficient algorithms or dynamic programming approaches.

🧮 Number Theory in Cryptography

Number theory is the foundation of modern cryptography. Here's a simple example using prime numbers:

#include <iostream>
#include <cmath>
using namespace std;

bool isPrime(int n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2= 0 || n % 3= 0) return false;

    for (int i= 5; i * i <= n; i = 6) {
        if (n % i= 0 || n % (i + 2)= 0) {
            return false;
        }
    }
    return true;
}

// Greatest Common Divisor using Euclidean algorithm
int gcd(int a, int b) {
    while (b = 0) {
        int temp= b;
        b= a % b;
        a= temp;
    }
    return a;
}

// Modular exponentiation (a^b mod m)
long long modPow(long long a, long long b, long long m) {
    long long result= 1;
    a= a % m;

    while (b > 0) {
        if (b % 2 == 1) {
            result = (result * a) % m;
        }
        a = (a * a) % m;
        b = b / 2;
    }
    return result;
}

int main() {
    int p = 61, q = 53;  // Two prime numbers
    int n = p * q;       // Product of primes

    cout << "Prime numbers: " << p << ", " << q << endl;
    cout << "Product n = " << n << endl;
    cout << "Is " << n << " prime? " << (isPrime(n) ? "Yes" : "No") << endl;

    // Simple RSA-like example
    int e= 17;  // Public exponent
    int phi= (p - 1) * (q - 1);  // Euler's totient function

    cout << "Euler's totient φ(n) = " << phi << endl;
    cout << "GCD(e, φ(n)) = " << gcd(e, phi) << endl;

    return 0;
}

This demonstrates concepts from RSA cryptography:

  • Prime factorization is computationally hard
  • Euler's totient function φ(n) = (p-1)(q-1)
  • Modular exponentiation for encryption/decryption

Real Cryptography

This is a simplified example. Real RSA uses much larger prime numbers (typically 2048+ bits) and additional security measures.

šŸŽÆ Why This Matters

Understanding the math behind code helps you:

  1. Write Better Algorithms - Know when to use hash tables vs. binary search
  2. Debug More Effectively - Recognize floating-point precision issues
  3. Optimize Performance - Understand time and space complexity
  4. Design Better Systems - Apply graph theory to network design
  5. Build Secure Applications - Use cryptographic principles correctly

Key Takeaway

Math isn't just for mathematicians — it's the foundation that makes all our digital technology possible. Every time you write code, you're applying mathematical concepts, whether you realize it or not.

šŸ”— Further Reading

If you're interested in diving deeper:

  • "Concrete Mathematics" by Graham, Knuth, and Patashnik
  • "Introduction to Algorithms" by Cormen, Leiserson, Rivest, and Stein
  • "Numerical Recipes" for computational methods
  • "Applied Cryptography" by Bruce Schneier

šŸ’¬ Final Thoughts

The next time you write a simple if statement or use a hash table, remember — you're applying centuries of mathematical discovery. From ancient Greek geometry to modern cryptography, math continues to shape how we solve problems with code.

What's Next

I'm planning to explore more advanced topics like machine learning algorithms, computational geometry, and optimization techniques in future posts.

Thanks for reading! If you have questions about any of these concepts or want to explore other mathematical topics in programming, drop me a message.

— Maruf