imeth
The stupid name "imeth" can be concluded into two translation:
- I + METH – Because I'm high on math equations like a guy high on meth.
- IYAN + METH Because Iyan (the original author) is high on math like a guy high on meth.
Even though both still share the same equal meaning.
Imeth is a lightweight C++ math library for exploring computational mathematics while testing the limit of author's C++ skill (and sanity). It's a high modular-designed library, making it very likely to have so many branches and abstractions just to get a method done. Though the author believes that modularity is the key to success. At least in his mind and his dream, it is.
Why imeth?
When asked, "why?", it's not about the matter, "why do I use imeth?". Instead, it's preferable to say that the real question is, "why do I make imeth?". No one, at least a sane being, is stupid enough to use imeth. Not even for fun I'd like to call them, sane, because someone who's sane will never hear the name imeth in their life. Someone who's insane however, will.
Apart from so, imeth is meant to be entirely an experiment that made public. It can be interpreted as a CIA trick to make propaganda so that they can control the world if they haven't. Or as a funny silly project to practice the author's skill while he learns C++ in his young age.
To me, I'm not developing imeth to be productive. It's more of an experiment that I think I'd like to accomplish.
Features
Imeth comes with plenty handy features that I'd like point out:
- Arithmetic Operations: Basic arithmetic calculations
- Linear Algebra: Equation solving, matrix operations, and more
- Factoring Quadratic Equation: Methods to factor quadratic equations
- Geometric Calculations: 2D and 3D geometric operations
- Base Conversions and Operations: Convert and operate on numbers between different bases
- Modular Design: Clean, organized API with namespace separation
- Simple API: Clean interfaces for complex math
My favorite one is the linear algebra, especially the linear equation with variables. Which I think will be the best and will be the overglazed feature, by me.
Installation
Dependencies
- C++20 Compatible Compilers
- CMake V3.15+
- Git
Clone the Repository
git clone https://github.com/lordpaijo/imeth.cpp imeth
cd imeth
Build and Install with CMake
Linux/MacOS
mkdir build && cd build
cmake ..
make -j
sudo make install
This will install:
- Library:
/usr/local/lib/libimeth.a - Headers:
/usr/local/include/imeth/ - CMake config:
/usr/local/lib/cmake/imeth/
Windows
Using Visual Studio:
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022"
cmake --build . --config Release
cmake --install . --config Release
Or using MinGW:
mkdir build
cd build
cmake .. -G "MinGW Makefiles"
mingw32-make -j
mingw32-make install
Usage
Using with CMake (Recommended)
In your project's CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(MyProject CXX)
set(CMAKE_CXX_STANDARD 20)
# Find the installed imeth library
find_package(imeth REQUIRED)
add_executable(my_app main.cpp)
# Link against imeth
target_link_libraries(my_app PRIVATE imeth::imeth)
Then build:
cmake -B build
cmake --build build
Using with Compiler Directly
After installation, compile your code with:
# Using g++
g++ -std=c++20 your_code.cpp -I/usr/local/include -L/usr/local/lib -limeth -o your_program
# Using clang++
clang++ -std=c++20 your_code.cpp -I/usr/local/include -L/usr/local/lib -limeth -o your_program
Quick Start
You can start building an app using imeth by including a category and its chapter in your code like this:
#include <imeth/linear/algebra.hpp>
Then start using the methods imported from the header like this:
int main() {
// Solve: 2x + 4 = 0
// Solution: x = -2
auto solution = imeth::LinearAlgebra::solve_1v(2, 4);
if (solution) {
std::cout << "Solution: x = " << *solution << "\n";
} else {
std::cout << "No solution exists\n";
}
return 0;
}
Example: Solving a System of Linear Equations
Let's make a program to solve linear equation of two variables using imeth:
#include <imeth/linear/algebra.hpp>
#include <iostream>
int main() {
// Solve:
// 2x + 3y = 8
// 4x - 2y = 0
// Solution: x = 1, y = 2
auto solution = imeth::LinearAlgebra::solve_2v(2, 3, 8, // First equation coefficients
4, -2, 0); // Second equation coefficients
if (solution) {
std::cout << "Solution: x = " << solution->first
<< ", y = " << solution->second << "\n";
} else {
std::cout << "No unique solution exists\n";
}
return 0;
}
Here, I call the library imeth, then the category linear, and then the chapter algebra.hpp.
What I'm really doing is, I'm importing the methods from the algebra chapter (header file, algebra.hpp) from the linear category (linear/) of the
imeth library (imeth/).
API Overview
Imeth is a modular library divided into namespaces and classes. I mention the term category and chapter previously, they are simply my way to say
a branch and a header. A category can be consisted of many chapters, just like a branch consisting many headers. Thus, imeth is a compilation of mathematical
categories and their chapters, which of course include their operations.
Available Categories
| Category | Description |
|---|---|
<imeth/linear> | Linear equations and operations |
<imeth/operation> | Bunch of general mathematical operations |
<imeth/geometry> | Geometric shape calculations |
<imeth/base> | Base conversions and operations |
Each category has their own chapters. And chapters are the actual APIs that you are going to use.
Operation Category
The operation category contains general mathematical operations including arithmetic and logarithmic functions.
Chapters
- Arithmetic - Comprehensive arithmetic operations and utilities
- Logarithm - Logarithmic operations and exponential equation solving
Usage
#include <imeth/operation/arithmetic.hpp>
#include <imeth/operation/logarithm.hpp>
Arithmetic
The arithmetic chapter is the first chapter from the operation category. It provides a comprehensive collection of arithmetic operations and mathematical utilities, ranging from basic operations to statistical functions, number theory, and practical calculations.
#include <imeth/operation/arithmetic.hpp>
Features
Basic Operations
add(double a, double b) → double- Standard additionsubtract(double a, double b) → double- Standard subtractionmultiply(double a, double b) → double- Standard multiplicationdivide(double a, double b) → double- Standard division
Power and Roots
power(double base, int exponent) → double- Raises base to an integer exponentsquareRoot(double n) → double- Computes √ncubeRoot(double n) → double- Computes ∛n
Absolute Value and Sign
absolute(double n) → double- Returns |n|sign(double n) → int- Returns -1 for negative, 0 for zero, 1 for positive
Remainders and Divisibility
remainder(int a, int b) → int- Integer remainder of a ÷ bisDivisible(int a, int b) → bool- Checks if a is divisible by b
Percentages
percentOf(double percent, double total) → double- Calculates percent% of totalwhatPercent(double part, double total) → double- Finds what percent part is of totalpercentIncrease(double original, double newValue) → double- Calculates percentage increasepercentDecrease(double original, double newValue) → double- Calculates percentage decrease
Averages and Statistics
average(const std::vector<double>& numbers) → double- Mean of a vector of numberssum(const std::vector<double>& numbers) → double- Total summinimum(const std::vector<double>& numbers) → double- Minimum valuemaximum(const std::vector<double>& numbers) → double- Maximum valuerange(const std::vector<double>& numbers) → double- Difference between max and minmedian(std::vector<double> numbers) → double- Middle value (sorts the data)
Fractions
addFractions(double num1, double den1, double num2, double den2) → double- Adds two fractionssubtractFractions(double num1, double den1, double num2, double den2) → double- Subtracts fractionsmultiplyFractions(double num1, double den1, double num2, double den2) → double- Multiplies fractionsdivideFractions(double num1, double den1, double num2, double den2) → double- Divides fractions
Rounding
roundToNearest(double n) → double- Rounds to nearest integerroundUp(double n) → double- Ceiling functionroundDown(double n) → double- Floor functionroundToDecimalPlaces(double n, int places) → double- Rounds to specified decimal places
Number Properties
isEven(int n) → bool- Checks if evenisOdd(int n) → bool- Checks if oddisPrime(int n) → bool- Tests for primalitygreatestCommonDivisor(int a, int b) → int- GCD of two integersleastCommonMultiple(int a, int b) → int- LCM of two integers
Geometry
distance2D(double x1, double y1, double x2, double y2) → double- Euclidean distance between two pointspythagorean(double a, double b) → double- Calculates hypotenuse using Pythagorean theorem
Conversions
celsiusToFahrenheit(double celsius) → double- Temperature conversion C → FfahrenheitToCelsius(double fahrenheit) → double- Temperature conversion F → C
Finance
simpleInterest(double principal, double rate, double time) → double- Calculates simple interest
Example Usage
#include <imeth/operation/arithmetic.hpp>
#include <iostream>
int main() {
double a, b;
char op;
std::cout << "Simple Calculator\n";
std::cout << "Enter operation (e.g., 5 + 3): ";
std::cin >> a >> op >> b;
double result;
switch(op) {
case '+':
result = imeth::Arithmetic::add(a, b);
break;
case '-':
result = imeth::Arithmetic::subtract(a, b);
break;
case '*':
result = imeth::Arithmetic::multiply(a, b);
break;
case '/':
result = imeth::Arithmetic::divide(a, b);
break;
default:
std::cout << "Invalid operator!\n";
return 1;
}
std::cout << "Result: " << result << "\n";
return 0;
}
More Examples
// Statistical calculations
std::vector<double> grades = {85.5, 92.0, 78.5, 95.0, 88.0};
double avg = imeth::Arithmetic::average(grades); // 87.8
double med = imeth::Arithmetic::median(grades); // 88.0
double minGrade = imeth::Arithmetic::minimum(grades); // 78.5
// Number theory
int gcd = imeth::Arithmetic::greatestCommonDivisor(48, 18); // 6
bool prime = imeth::Arithmetic::isPrime(17); // true
// Percentage calculations
double discount = imeth::Arithmetic::percentOf(20, 100.0); // 20.0
double increase = imeth::Arithmetic::percentIncrease(50, 75); // 50.0
// Geometry
double dist = imeth::Arithmetic::distance2D(0, 0, 3, 4); // 5.0
double hyp = imeth::Arithmetic::pythagorean(3, 4); // 5.0
// Temperature conversion
double fahrenheit = imeth::Arithmetic::celsiusToFahrenheit(25); // 77.0
Logarithm
Logarithm is the second chapter that can be found from the operation category. It provides methods and functions to operate logarithmic operations, including common logarithms, natural logarithms, exponential equation solving, and base conversions.
#include <imeth/operation/logarithm.hpp>
Features
Logarithm Functions
log(double base, double value) → std::optional<double>- Computes log_base(value) with arbitrary baseln(double value) → std::optional<double>- Natural logarithm (base e)log10(double value) → std::optional<double>- Common logarithm (base 10)log2(double value) → std::optional<double>- Binary logarithm (base 2)
Exponential Equations
solve_exponential(double base, double value) → std::optional<double>- Solves base^x = value for x
Base Conversion
change_base(double value, double old_base, double new_base) → std::optional<double>- Converts logarithm from one base to another using the change of base formula
Return Values
All methods return std::optional<double>:
- Contains a value if the operation is valid
- Returns
std::nulloptif:value ≤ 0(logarithm undefined for non-positive numbers)base ≤ 0(invalid base)base = 1(division by zero in change of base formula)
Example Usage
#include <imeth/operation/logarithm.hpp>
#include <iostream>
int main() {
// Basic logarithms
auto result = imeth::Logarithm::log(2, 8);
if (result.has_value()) {
std::cout << "log_2(8) = " << result.value() << "\n"; // 3.0
}
// Natural logarithm
auto ln_result = imeth::Logarithm::ln(2.718281828);
if (ln_result.has_value()) {
std::cout << "ln(e) ≈ " << ln_result.value() << "\n"; // ≈ 1.0
}
// Common logarithm
auto log10_result = imeth::Logarithm::log10(1000);
if (log10_result.has_value()) {
std::cout << "log_10(1000) = " << log10_result.value() << "\n"; // 3.0
}
// Binary logarithm
auto log2_result = imeth::Logarithm::log2(16);
if (log2_result.has_value()) {
std::cout << "log_2(16) = " << log2_result.value() << "\n"; // 4.0
}
return 0;
}
More Examples
// Solving exponential equations
// Solve: 2^x = 32
auto x = imeth::Logarithm::solve_exponential(2, 32);
if (x.has_value()) {
std::cout << "x = " << x.value() << "\n"; // 5.0
}
// Solve: 10^x = 1000
auto x2 = imeth::Logarithm::solve_exponential(10, 1000);
if (x2.has_value()) {
std::cout << "x = " << x2.value() << "\n"; // 3.0
}
// Change of base
// Convert log_2(8) to base 10
auto converted = imeth::Logarithm::change_base(8, 2, 10);
if (converted.has_value()) {
std::cout << "log_10(8) = " << converted.value() << "\n"; // ≈ 0.903
}
// Error handling
auto invalid = imeth::Logarithm::log(2, -5);
if (!invalid.has_value()) {
std::cout << "Cannot compute logarithm of negative number\n";
}
auto invalid_base = imeth::Logarithm::log(1, 10);
if (!invalid_base.has_value()) {
std::cout << "Base cannot be 1\n";
}
Mathematical Properties
The logarithm functions implement standard mathematical properties:
- Product rule: log(xy) = log(x) + log(y)
- Quotient rule: log(x/y) = log(x) - log(y)
- Power rule: log(x^n) = n·log(x)
- Change of base: log_b(x) = log_a(x) / log_a(b)
Linear Category
The linear category contains linear algebra operations including equation solving and matrix operations.
Chapters
- Algebra - Linear equations, systems of equations, and quadratic equations
- Matrix - Matrix operations, vectors, and linear system solvers
Usage
#include <imeth/linear/algebra.hpp>
#include <imeth/linear/matrix.hpp>
Algebra
Ah, yes, algebra, my favorite subject. This chapter exists in the linear category and provides tools for solving linear equations, systems of linear equations, and quadratic equations.
#include <imeth/linear/algebra.hpp>
Classes
The algebra module contains two main classes:
LinearAlgebra- Solves linear equations and systems of linear equationsQuadraticEquation- Solves quadratic equations using the quadratic formula
LinearAlgebra
Provides methods for solving linear equations in one or two variables.
Features
Single Variable Linear Equations
solve_1v(double a, double b) → std::optional<double>- Solves ax + b = 0 for x- Returns
std::nulloptif no solution exists (when a = 0 and b ≠ 0)
- Returns
System of Two Linear Equations
solve_2v(double a1, double b1, double c1, double a2, double b2, double c2) → std::optional<std::pair<double, double>>- Solves the system:a1·x + b1·y = c1 a2·x + b2·y = c2- Returns
std::pair<double, double>containing (x, y) if a unique solution exists - Returns
std::nulloptif the system has no solution or infinitely many solutions
- Returns
Example Usage
#include <imeth/linear/algebra.hpp>
#include <iostream>
int main() {
// Solve: 2x + 6 = 0
auto result = imeth::LinearAlgebra::solve_1v(2, 6);
if (result.has_value()) {
std::cout << "x = " << result.value() << "\n"; // x = -3
}
// Solve system:
// 2x + 3y = 8
// x - y = 1
auto system = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1);
if (system.has_value()) {
auto [x, y] = system.value();
std::cout << "x = " << x << ", y = " << y << "\n"; // x = 2.2, y = 1.2
}
return 0;
}
QuadraticEquation
Solves quadratic equations of the form ax² + bx + c = 0 using the quadratic formula.
Features
Solution Type
using Solution = std::variant<std::monostate, double, std::pair<double, double>>;
The Solution type can represent three possible outcomes:
std::monostate- No real solutions (complex roots, discriminant < 0)double- One solution / repeated root (discriminant = 0)std::pair<double, double>- Two distinct real solutions (discriminant > 0), where first ≤ second
Solving Quadratic Equations
solve(double a, double b, double c) → Solution- Solves ax² + bx + c = 0- Uses the quadratic formula: x = (-b ± √(b² - 4ac)) / 2a
- Handles degenerate cases (when a = 0, reduces to linear equation)
- Returns solutions in ascending order when two solutions exist
Example Usage
#include <imeth/linear/algebra.hpp>
#include <iostream>
#include <variant>
int main() {
// Solve: x² - 5x + 6 = 0
// Factors as: (x - 2)(x - 3) = 0
auto result = imeth::QuadraticEquation::solve(1, -5, 6);
if (std::holds_alternative<std::pair<double, double>>(result)) {
auto [x1, x2] = std::get<std::pair<double, double>>(result);
std::cout << "Two solutions: x1 = " << x1 << ", x2 = " << x2 << "\n";
// Output: x1 = 2, x2 = 3
}
else if (std::holds_alternative<double>(result)) {
double x = std::get<double>(result);
std::cout << "One solution: x = " << x << "\n";
}
else {
std::cout << "No real solutions (complex roots)\n";
}
return 0;
}
More Examples
// Repeated root (discriminant = 0)
// Solve: x² - 4x + 4 = 0 → (x - 2)² = 0
auto repeated = imeth::QuadraticEquation::solve(1, -4, 4);
if (std::holds_alternative<double>(repeated)) {
double x = std::get<double>(repeated);
std::cout << "Repeated root: x = " << x << "\n"; // x = 2
}
// No real solutions (discriminant < 0)
// Solve: x² + x + 1 = 0
auto no_real = imeth::QuadraticEquation::solve(1, 1, 1);
if (std::holds_alternative<std::monostate>(no_real)) {
std::cout << "No real solutions\n";
}
// Negative leading coefficient
// Solve: -x² + 4x - 3 = 0 → x² - 4x + 3 = 0
auto negative_a = imeth::QuadraticEquation::solve(-1, 4, -3);
if (std::holds_alternative<std::pair<double, double>>(negative_a)) {
auto [x1, x2] = std::get<std::pair<double, double>>(negative_a);
std::cout << "x1 = " << x1 << ", x2 = " << x2 << "\n"; // x1 = 1, x2 = 3
}
// Working with LinearAlgebra and QuadraticEquation together
// Check if a value is a solution
auto solutions = imeth::QuadraticEquation::solve(1, -3, 2);
if (std::holds_alternative<std::pair<double, double>>(solutions)) {
auto [x1, x2] = std::get<std::pair<double, double>>(solutions);
// Verify: x² - 3x + 2 = 0 when x = x1
double check = x1 * x1 - 3 * x1 + 2;
std::cout << "Verification: " << check << "\n"; // ≈ 0
}
Mathematical Background
Linear Equations (1 variable)
- Form: ax + b = 0
- Solution: x = -b/a (when a ≠ 0)
System of Linear Equations (2 variables)
- Uses elimination or substitution methods
- Determines if system has unique solution, no solution, or infinite solutions
Quadratic Equations
- Form: ax² + bx + c = 0
- Discriminant: Δ = b² - 4ac
- Δ > 0: Two distinct real roots
- Δ = 0: One repeated root
- Δ < 0: Two complex conjugate roots (no real solutions)
- Quadratic formula: x = (-b ± √Δ) / 2a
Matrix
I genuinely don't know what matrix or vector is (besides them being a dynamic alternative for arrays in C++). I mean, what do you expect from a 9th grader?
But, here the chapter matrix.hpp, exists...
#include <imeth/linear/matrix.hpp>
Classes
The matrix module contains three main classes:
- Matrix - Represents a 2D matrix and provides matrix operations
- Vector - Represents a mathematical vector (1D array of numbers)
- Solver - Provides methods for solving systems of linear equations
Matrix
A 2D array of numbers that supports mathematical operations like addition, multiplication, and transposition.
Constructors
Matrix(size_t rows, size_t cols)- Creates a matrix with specified dimensions (initialized to zero)Matrix(std::initializer_list<std::vector<double>> data)- Creates a matrix from a list of rows
Element Access
operator()(size_t r, size_t c) → double&- Accesses element at row r, column c (modifiable)operator()(size_t r, size_t c) const → double- Accesses element at row r, column c (read-only)
Properties
rows() const → size_t- Returns the number of rowscols() const → size_t- Returns the number of columns
Static Methods
identity(size_t n) → Matrix- Creates an n×n identity matrix (1s on diagonal, 0s elsewhere)
Operations
transpose() const → Matrix- Returns the transpose (rows ↔ columns)operator*(const Matrix& rhs) const → Matrix- Matrix multiplicationoperator+(const Matrix& rhs) const → Matrix- Matrix additionoperator-(const Matrix& rhs) const → Matrix- Matrix subtraction
Example Usage
#include <imeth/linear/matrix.hpp>
#include <iostream>
int main() {
// Create a 2×3 matrix
imeth::Matrix A = {
{1, 2, 3},
{4, 5, 6}
};
std::cout << "Matrix A is " << A.rows() << "×" << A.cols() << "\n";
// Access elements
std::cout << "A(0,0) = " << A(0, 0) << "\n"; // 1
std::cout << "A(1,2) = " << A(1, 2) << "\n"; // 6
// Modify element
A(0, 0) = 10;
// Transpose
imeth::Matrix A_T = A.transpose();
std::cout << "Transpose is " << A_T.rows() << "×" << A_T.cols() << "\n"; // 3×2
// Create identity matrix
imeth::Matrix I = imeth::Matrix::identity(3);
// I = [[1, 0, 0],
// [0, 1, 0],
// [0, 0, 1]]
return 0;
}
More Examples
// Matrix addition
imeth::Matrix A = {{1, 2}, {3, 4}};
imeth::Matrix B = {{5, 6}, {7, 8}};
imeth::Matrix C = A + B; // {{6, 8}, {10, 12}}
// Matrix multiplication
imeth::Matrix D = {{1, 2}, {3, 4}};
imeth::Matrix E = {{2, 0}, {1, 2}};
imeth::Matrix F = D * E; // {{4, 4}, {10, 8}}
// Matrix subtraction
imeth::Matrix G = B - A; // {{4, 4}, {4, 4}}
Vector
A 1D array of numbers (essentially a column vector in mathematical terms).
Constructors
Vector(size_t n)- Creates a vector of size n (initialized to zero)Vector(std::initializer_list<double> data)- Creates a vector from a list of values
Element Access
operator[](size_t i) → double&- Accesses element at index i (modifiable)operator[](size_t i) const → double- Accesses element at index i (read-only)
Properties
size() const → size_t- Returns the number of elements
Example Usage
#include <imeth/linear/matrix.hpp>
#include <iostream>
int main() {
// Create a vector
imeth::Vector v = {1.0, 2.0, 3.0, 4.0};
std::cout << "Vector size: " << v.size() << "\n"; // 4
// Access elements
std::cout << "v[0] = " << v[0] << "\n"; // 1.0
std::cout << "v[2] = " << v[2] << "\n"; // 3.0
// Modify element
v[1] = 5.0;
// Create empty vector and fill it
imeth::Vector u(5);
for (size_t i = 0; i < u.size(); ++i) {
u[i] = i * 2.0;
}
return 0;
}
Solver
Provides numerical methods for solving systems of linear equations Ax = b, where A is a matrix, x is the unknown vector, and b is the result vector.
Methods
gaussian_elimination(const Matrix& A, const Vector& b) → Vector- Solves Ax = b using Gaussian elimination with back substitutiongauss_jordan(const Matrix& A, const Vector& b) → Vector- Solves Ax = b using Gauss-Jordan elimination (reduced row echelon form)lu_decomposition(const Matrix& A, const Vector& b) → Vector- Solves Ax = b using LU decomposition (factors A = LU)
Example Usage
#include <imeth/linear/matrix.hpp>
#include <iostream>
int main() {
// Solve the system:
// 2x + 3y = 8
// x - y = 1
imeth::Matrix A = {
{2, 3},
{1, -1}
};
imeth::Vector b = {8, 1};
// Method 1: Gaussian elimination
imeth::Vector x1 = imeth::Solver::gaussian_elimination(A, b);
std::cout << "Solution (Gaussian): x = " << x1[0] << ", y = " << x1[1] << "\n";
// Method 2: Gauss-Jordan
imeth::Vector x2 = imeth::Solver::gauss_jordan(A, b);
std::cout << "Solution (Gauss-Jordan): x = " << x2[0] << ", y = " << x2[1] << "\n";
// Method 3: LU decomposition
imeth::Vector x3 = imeth::Solver::lu_decomposition(A, b);
std::cout << "Solution (LU): x = " << x3[0] << ", y = " << x3[1] << "\n";
return 0;
}
More Examples
// Solve a 3×3 system:
// x + 2y + z = 6
// 2x + y + z = 6
// x + y + 2z = 7
imeth::Matrix A = {
{1, 2, 1},
{2, 1, 1},
{1, 1, 2}
};
imeth::Vector b = {6, 6, 7};
imeth::Vector solution = imeth::Solver::gaussian_elimination(A, b);
std::cout << "x = " << solution[0] << "\n"; // x = 1
std::cout << "y = " << solution[1] << "\n"; // y = 2
std::cout << "z = " << solution[2] << "\n"; // z = 2
// Verify solution: A * x = b
for (size_t i = 0; i < A.rows(); ++i) {
double result = 0;
for (size_t j = 0; j < A.cols(); ++j) {
result += A(i, j) * solution[j];
}
std::cout << "Row " << i << " check: " << result << " = " << b[i] << "\n";
}
Mathematical Background
Matrix - A rectangular array of numbers arranged in rows and columns. Matrices are used to represent linear transformations and systems of equations.
Vector - A one-dimensional array of numbers. In this context, it represents either the coefficients on the right side of equations (vector b) or the solution values (vector x).
System of Linear Equations - Multiple equations like:
a₁₁x₁ + a₁₂x₂ + ... = b₁
a₂₁x₁ + a₂₂x₂ + ... = b₂
...
Solving Methods:
- Gaussian Elimination - Transforms the system to upper triangular form, then uses back substitution
- Gauss-Jordan - Reduces the matrix to reduced row echelon form (identity matrix)
- LU Decomposition - Factors matrix A into lower (L) and upper (U) triangular matrices
Geometry Category
The geometry category contains geometric shape calculations for 2D and 3D shapes.
Chapters
Usage
#include <imeth/geometry/2D.hpp>
#include <imeth/geometry/3D.hpp>
2D Shapes
The Shape2D classes provide an easy way to calculate areas and perimeters of common 2D shapes (flat shapes).
Overview
All 2D shapes inherit from the Shape2D base class and provide two main methods:
area()- Calculate the area (space inside the shape)perimeter()- Calculate the perimeter (distance around the shape)
Include
#include <imeth/shape/2D.hpp>
Base Class
class Shape2D {
public:
virtual double area() const = 0;
virtual double perimeter() const = 0;
};
Available Shapes
Circle
A round shape with all points equally distant from the center.
Circle(double radius);
Methods:
area()- Returns πr²perimeter()- Returns 2πr (also called circumference)
Examples:
Circle circle(5.0);
std::cout << "Area: " << circle.area() << "\n"; // 78.54
std::cout << "Perimeter: " << circle.perimeter() << "\n"; // 31.42
// Pizza with 12 inch diameter (radius = 6)
Circle pizza(6);
std::cout << "Pizza area: " << pizza.area() << " sq in\n"; // 113.1 sq in
Formula:
- Area = π × r²
- Perimeter = 2 × π × r
Rectangle
A four-sided shape with opposite sides equal and all angles 90°.
Rectangle(double width, double height);
Methods:
area()- Returns width × heightperimeter()- Returns 2(width + height)
Examples:
Rectangle rect(10, 5);
std::cout << "Area: " << rect.area() << "\n"; // 50
std::cout << "Perimeter: " << rect.perimeter() << "\n"; // 30
// Phone screen: 6 inches by 3 inches
Rectangle screen(6, 3);
std::cout << "Screen area: " << screen.area() << " sq in\n"; // 18 sq in
Formula:
- Area = width × height
- Perimeter = 2 × (width + height)
Square
A special rectangle where all four sides are equal.
Square(double side);
Methods:
area()- Returns side²perimeter()- Returns 4 × side
Examples:
Square square(4);
std::cout << "Area: " << square.area() << "\n"; // 16
std::cout << "Perimeter: " << square.perimeter() << "\n"; // 16
// Chess board square (each square is 2 inches)
Square chessSquare(2);
std::cout << "Square area: " << chessSquare.area() << " sq in\n"; // 4 sq in
Formula:
- Area = side²
- Perimeter = 4 × side
Triangle
A three-sided shape. This implementation uses base and height (for right triangles or when height is known).
Triangle(double base, double height);
Methods:
area()- Returns ½ × base × heightperimeter()- Returns base + side1 + side2 (calculated)
Examples:
Triangle triangle(6, 4);
std::cout << "Area: " << triangle.area() << "\n"; // 12
std::cout << "Perimeter: " << triangle.perimeter() << "\n";
// Triangular warning sign
Triangle sign(10, 8.66);
std::cout << "Sign area: " << sign.area() << " sq in\n"; // 43.3 sq in
Formula:
- Area = ½ × base × height
Pentagon
A five-sided regular polygon (all sides and angles equal).
Pentagon(double side);
Methods:
area()- Returns ¼√(25 + 10√5) × side²perimeter()- Returns 5 × side
Examples:
Pentagon pentagon(5);
std::cout << "Area: " << pentagon.area() << "\n"; // 43.01
std::cout << "Perimeter: " << pentagon.perimeter() << "\n"; // 25
// The Pentagon building (simplified, each side ≈ 921 feet)
Pentagon building(921);
std::cout << "Perimeter: " << building.perimeter() << " feet\n"; // 4605 feet
Formula:
- Area ≈ 1.72048 × side²
- Perimeter = 5 × side
Hexagon
A six-sided regular polygon (like a honeycomb cell).
Hexagon(double side);
Methods:
area()- Returns (3√3/2) × side²perimeter()- Returns 6 × side
Examples:
Hexagon hexagon(4);
std::cout << "Area: " << hexagon.area() << "\n"; // 41.57
std::cout << "Perimeter: " << hexagon.perimeter() << "\n"; // 24
// Honeycomb cell (each side ≈ 2.5mm)
Hexagon honeycomb(2.5);
std::cout << "Cell area: " << honeycomb.area() << " sq mm\n"; // 16.24 sq mm
Formula:
- Area ≈ 2.598 × side²
- Perimeter = 6 × side
Fun fact: Hexagons are the most efficient shape for covering an area (that's why bees use them!)
Octagon
An eight-sided regular polygon (like a stop sign).
Octagon(double side);
Methods:
area()- Returns 2(1 + √2) × side²perimeter()- Returns 8 × side
Examples:
Octagon octagon(3);
std::cout << "Area: " << octagon.area() << "\n"; // 43.46
std::cout << "Perimeter: " << octagon.perimeter() << "\n"; // 24
// Stop sign (each side ≈ 12 inches)
Octagon stopSign(12);
std::cout << "Sign area: " << stopSign.area() << " sq in\n"; // 695.3 sq in
Formula:
- Area ≈ 4.828 × side²
- Perimeter = 8 × side
Polymorphism Example
Since all shapes inherit from Shape2D, you can use them polymorphically:
#include <vector>
#include <memory>
std::vector<std::unique_ptr<Shape2D>> shapes;
shapes.push_back(std::make_unique<Circle>(5));
shapes.push_back(std::make_unique<Square>(4));
shapes.push_back(std::make_unique<Hexagon>(3));
for (const auto& shape : shapes) {
std::cout << "Area: " << shape->area()
<< ", Perimeter: " << shape->perimeter() << "\n";
}
Comparison Example
Compare different shapes:
Circle circle(5);
Square square(5);
std::cout << "Circle area: " << circle.area() << "\n"; // 78.54
std::cout << "Square area: " << square.area() << "\n"; // 25
// Which has more area?
if (circle.area() > square.area()) {
std::cout << "Circle has more area!\n";
}
Real-World Applications
1. Calculate Paint Needed
Rectangle wall(10, 8); // 10 feet wide, 8 feet tall
double paintPerSquareFoot = 0.02; // gallons per sq ft
double paintNeeded = wall.area() * paintPerSquareFoot;
std::cout << "Paint needed: " << paintNeeded << " gallons\n";
2. Fencing a Garden
Rectangle garden(15, 20); // 15m × 20m
double fenceCostPerMeter = 25; // $25 per meter
double totalCost = garden.perimeter() * fenceCostPerMeter;
std::cout << "Fencing cost: $" << totalCost << "\n"; // $1750
3. Pizza Size Comparison
Circle smallPizza(6); // 6 inch radius
Circle largePizza(9); // 9 inch radius
double smallArea = smallPizza.area();
double largeArea = largePizza.area();
std::cout << "Small pizza: " << smallArea << " sq in\n";
std::cout << "Large pizza: " << largeArea << " sq in\n";
std::cout << "Large is " << (largeArea / smallArea) << "x bigger!\n";
4. Sports Field
Rectangle soccerField(100, 60); // 100m × 60m
std::cout << "Field area: " << soccerField.area() << " sq m\n"; // 6000
std::cout << "Running track: " << soccerField.perimeter() << " m\n"; // 320
Circle centerCircle(9.15); // Center circle radius
std::cout << "Center circle area: " << centerCircle.area() << " sq m\n";
Quick Reference Table
| Shape | Sides | Area Formula | Perimeter Formula |
|---|---|---|---|
| Circle | - | πr² | 2πr |
| Square | 4 | s² | 4s |
| Rectangle | 4 | w×h | 2(w+h) |
| Triangle | 3 | ½bh | a+b+c |
| Pentagon | 5 | ~1.72s² | 5s |
| Hexagon | 6 | ~2.598s² | 6s |
| Octagon | 8 | ~4.828s² | 8s |
Tips
- Use circles for round objects (pizza, wheels, clocks)
- Use rectangles for most everyday objects (rooms, screens, books)
- Use squares when all sides are equal
- Regular polygons (pentagon, hexagon, octagon) have all sides and angles equal
- The more sides a regular polygon has, the more it looks like a circle!
Common Units
- Area units: square meters (m²), square feet (ft²), square inches (in²)
- Perimeter units: meters (m), feet (ft), inches (in)
3D Shapes
The Shape3D classes provide an easy way to calculate surface areas and volumes of common 3D shapes (solid objects).
Overview
All 3D shapes inherit from the Shape3D base class and provide two main methods:
area()- Calculate the surface area (total area of all outer surfaces)volume()- Calculate the volume (space inside the shape)
Include
#include <imeth/shape/3D.hpp>
Base Class
class Shape3D {
public:
virtual double area() const = 0;
virtual double volume() const = 0;
};
Available Shapes
Sphere
A perfectly round 3D object (like a ball or globe).
Sphere(double radius);
Methods:
area()- Returns 4πr² (surface area)volume()- Returns (4/3)πr³
Examples:
Sphere sphere(5.0);
std::cout << "Surface area: " << sphere.area() << "\n"; // 314.16
std::cout << "Volume: " << sphere.volume() << "\n"; // 523.6
// Basketball (radius ≈ 12 cm)
Sphere basketball(12);
std::cout << "Surface area: " << basketball.area() << " sq cm\n"; // 1809.6
std::cout << "Volume: " << basketball.volume() << " cu cm\n"; // 7238.2
Formulas:
- Surface Area = 4 × π × r²
- Volume = (4/3) × π × r³
Real-world: Balls, planets, bubbles, oranges
Cube
A 3D square - all sides, edges, and angles are equal.
Cube(double side);
Methods:
area()- Returns 6 × side² (6 square faces)volume()- Returns side³
Examples:
Cube cube(4);
std::cout << "Surface area: " << cube.area() << "\n"; // 96
std::cout << "Volume: " << cube.volume() << "\n"; // 64
// Rubik's Cube (side ≈ 5.7 cm)
Cube rubiksCube(5.7);
std::cout << "Surface area: " << rubiksCube.area() << " sq cm\n"; // 194.94
std::cout << "Volume: " << rubiksCube.volume() << " cu cm\n"; // 185.19
Formulas:
- Surface Area = 6 × side²
- Volume = side³
Real-world: Dice, boxes, Minecraft blocks, ice cubes
Cylinder
A tube shape with circular ends (like a can or pipe).
Cylinder(double radius, double height);
Methods:
area()- Returns 2πr² + 2πrh (top + bottom + side)volume()- Returns πr²h
Examples:
Cylinder cylinder(3, 10);
std::cout << "Surface area: " << cylinder.area() << "\n"; // 245.04
std::cout << "Volume: " << cylinder.volume() << "\n"; // 282.74
// Soda can (radius ≈ 3 cm, height ≈ 12 cm)
Cylinder sodaCan(3, 12);
std::cout << "Can surface: " << sodaCan.area() << " sq cm\n"; // 282.74
std::cout << "Can volume: " << sodaCan.volume() << " cu cm\n"; // 339.29
std::cout << "That's " << sodaCan.volume() / 1000 << " liters\n"; // 0.339 L
Formulas:
- Surface Area = 2πr² + 2πrh = 2πr(r + h)
- Volume = π × r² × h
Real-world: Cans, pipes, drums, tree trunks, water tanks
Cone
A shape with a circular base that tapers to a point (like an ice cream cone).
Cone(double radius, double height);
Methods:
area()- Returns πr² + πr√(h² + r²) (base + curved surface)volume()- Returns (1/3)πr²h
Examples:
Cone cone(4, 9);
std::cout << "Surface area: " << cone.area() << "\n"; // 175.93
std::cout << "Volume: " << cone.volume() << "\n"; // 150.8
// Ice cream cone (radius ≈ 3 cm, height ≈ 10 cm)
Cone iceCream(3, 10);
std::cout << "Cone surface: " << iceCream.area() << " sq cm\n"; // 125.66
std::cout << "Cone volume: " << iceCream.volume() << " cu cm\n"; // 94.25
Formulas:
- Surface Area = πr² + πr√(h² + r²)
- Base area: πr²
- Slant area: πr√(h² + r²)
- Volume = (1/3) × π × r² × h
Fun fact: A cone's volume is exactly 1/3 of a cylinder with the same base and height!
Real-world: Ice cream cones, traffic cones, party hats, funnels
Torus
A donut shape (a tube bent into a circle).
Torus(double major_radius, double minor_radius);
Parameters:
major_radius- Distance from center of torus to center of tubeminor_radius- Radius of the tube itself
Methods:
area()- Returns 4π²Rr (surface area)volume()- Returns 2π²Rr²
Examples:
Torus torus(10, 3); // Big radius 10, tube radius 3
std::cout << "Surface area: " << torus.area() << "\n"; // 1184.4
std::cout << "Volume: " << torus.volume() << "\n"; // 1776.6
// Swimming tube (major ≈ 40 cm, minor ≈ 10 cm)
Torus swimmingTube(40, 10);
std::cout << "Tube surface: " << swimmingTube.area() << " sq cm\n"; // 15791.4
std::cout << "Tube volume: " << swimmingTube.volume() << " cu cm\n"; // 78957.1
Formulas:
- Surface Area = 4π² × R × r
- Volume = 2π² × R × r²
Where:
- R = major radius (big circle)
- r = minor radius (tube)
Real-world: Donuts, swimming tubes, O-rings, bagels, hula hoops
Polymorphism Example
Since all shapes inherit from Shape3D, you can use them polymorphically:
#include <vector>
#include <memory>
std::vector<std::unique_ptr<Shape3D>> shapes;
shapes.push_back(std::make_unique<Sphere>(5));
shapes.push_back(std::make_unique<Cube>(4));
shapes.push_back(std::make_unique<Cylinder>(3, 10));
for (const auto& shape : shapes) {
std::cout << "Surface area: " << shape->area()
<< ", Volume: " << shape->volume() << "\n";
}
Volume Comparisons
Sphere vs Cube
Sphere sphere(5);
Cube cube(5);
std::cout << "Sphere volume: " << sphere.volume() << "\n"; // 523.6
std::cout << "Cube volume: " << cube.volume() << "\n"; // 125
// A sphere with radius = cube side has ~4.2x more volume!
Cylinder vs Cone
Cylinder cylinder(4, 9);
Cone cone(4, 9); // Same base and height
std::cout << "Cylinder volume: " << cylinder.volume() << "\n"; // 452.39
std::cout << "Cone volume: " << cone.volume() << "\n"; // 150.8
// Cone is exactly 1/3 of cylinder volume!
std::cout << "Ratio: " << cylinder.volume() / cone.volume() << "\n"; // 3.0
Real-World Applications
1. Water Tank Capacity
Cylinder waterTank(1.5, 3); // 1.5m radius, 3m height
double liters = waterTank.volume() * 1000; // 1 m³ = 1000 liters
std::cout << "Tank holds " << liters << " liters\n"; // 21,205 liters
2. Paint for a Sphere
Sphere globe(0.5); // 0.5m radius globe
double paintPerSqM = 0.1; // liters per square meter
double paintNeeded = globe.area() * paintPerSqM;
std::cout << "Paint needed: " << paintNeeded << " liters\n";
3. Gift Box Volume
Cube giftBox(20); // 20cm × 20cm × 20cm
double volumeCm3 = giftBox.volume(); // 8000 cm³
double volumeLiters = volumeCm3 / 1000;
std::cout << "Box can hold " << volumeLiters << " liters\n"; // 8 liters
4. Ice Cream Cone vs Scoop
Cone cone(3, 10); // Cone: radius 3cm, height 10cm
Sphere scoop(3); // Scoop: radius 3cm
std::cout << "Cone volume: " << cone.volume() << " cu cm\n"; // 94.25
std::cout << "Scoop volume: " << scoop.volume() << " cu cm\n"; // 113.1
// The scoop has more ice cream than the cone can hold!
if (scoop.volume() > cone.volume()) {
std::cout << "Better order a bigger cone!\n";
}
5. Swimming Pool
Cylinder pool(5, 1.5); // 5m radius, 1.5m deep
double volume = pool.volume();
double liters = volume * 1000;
std::cout << "Pool volume: " << volume << " cubic meters\n";
std::cout << "That's " << liters << " liters of water!\n";
std::cout << "Or " << liters * 0.264172 << " gallons\n";
Quick Reference Table
| Shape | Area Formula | Volume Formula | Example |
|---|---|---|---|
| Sphere | 4πr² | (4/3)πr³ | Ball, planet |
| Cube | 6s² | s³ | Dice, box |
| Cylinder | 2πr(r+h) | πr²h | Can, pipe |
| Cone | πr² + πrs | (1/3)πr²h | Ice cream cone |
| Torus | 4π²Rr | 2π²Rr² | Donut, tube |
Where:
- r = radius
- s = side
- h = height
- R = major radius (for torus)
Volume Relationships
Interesting Facts:
- A cone's volume = 1/3 of a cylinder (same base & height)
- A sphere's volume = 2/3 of a cylinder (if cylinder has radius r and height 2r)
- A cube with side s has less volume than a sphere with radius s
Common Volume Units
- Metric: cubic meters (m³), cubic centimeters (cm³), liters (L)
- 1 m³ = 1,000 liters
- 1 liter = 1,000 cm³
- Imperial: cubic feet (ft³), cubic inches (in³), gallons (gal)
- 1 gallon ≈ 3,785 cm³
Tips
- Surface area is measured in square units (m², cm²)
- Volume is measured in cubic units (m³, cm³)
- Use
Cylinderfor most containers (cans, tanks, tubes) - Use
Spherefor balls and planets - Use
Cubefor perfect boxes and dice Torusis rare but fun for donuts and swimming tubes!- Remember: Volume tells you how much fits inside, surface area tells you how much material you need to cover it
Base Category
The base category contains base conversions and operations for working with different number bases.
Chapters
- Base - Comprehensive base conversions and operations utilities.
- Binary - Binary conversions and operations utilities.
- Hexadecimal - Hexadecimal conversions and operations utilities.
- Octal - Octal conversions and operations utilities.
Usage
#include <imeth/base/base.hpp>
#include <imeth/base/binary.hpp>
#include <imeth/base/hexadecimal.hpp>
#include <imeth/base/octal.hpp>
Binary
The Binary class provides specialized functions for working with binary numbers (base 2), including bitwise operations that are essential in computer science.
Overview
Binary is the foundation of computer systems. Every number in a computer is stored as binary (0s and 1s). This class helps you understand and work with binary numbers directly.
Include
#include <imeth/base/binary.hpp>
Conversion Functions
FROM Decimal TO Binary
static std::string fromDecimal(int decimal);
Examples:
Binary::fromDecimal(10); // "1010"
Binary::fromDecimal(42); // "101010"
Binary::fromDecimal(255); // "11111111"
Binary::fromDecimal(0); // "0"
Binary::fromDecimal(-5); // "-101"
FROM Binary TO Decimal
static int toDecimal(const std::string& binary);
Examples:
Binary::toDecimal("1010"); // 10
Binary::toDecimal("101010"); // 42
Binary::toDecimal("11111111"); // 255
Binary::toDecimal("-101"); // -5
Arithmetic Operations
static std::string add(const std::string& a, const std::string& b);
static std::string subtract(const std::string& a, const std::string& b);
static std::string multiply(const std::string& a, const std::string& b);
Perform basic math directly in binary.
Examples:
Binary::add("1010", "101"); // "1111" (10 + 5 = 15)
Binary::subtract("1100", "101"); // "111" (12 - 5 = 7)
Binary::multiply("101", "11"); // "1111" (5 × 3 = 15)
Bitwise Operations
These operations work at the bit level and are fundamental to computer programming.
AND Operation
static std::string bitwiseAND(const std::string& a, const std::string& b);
Returns 1 only when both bits are 1.
Examples:
Binary::bitwiseAND("1100", "1010"); // "1000"
// 1100
// &1010
// -----
// 1000
OR Operation
static std::string bitwiseOR(const std::string& a, const std::string& b);
Returns 1 when at least one bit is 1.
Examples:
Binary::bitwiseOR("1100", "1010"); // "1110"
// 1100
// |1010
// -----
// 1110
XOR Operation
static std::string bitwiseXOR(const std::string& a, const std::string& b);
Returns 1 only when bits are different.
Examples:
Binary::bitwiseXOR("1100", "1010"); // "110"
// 1100
// ^1010
// -----
// 0110
NOT Operation
static std::string bitwiseNOT(const std::string& binary);
Flips all bits (0→1, 1→0).
Examples:
Binary::bitwiseNOT("1010"); // "0101"
Binary::bitwiseNOT("1111"); // "0000"
Bit Shifting
static std::string leftShift(const std::string& binary, int positions);
static std::string rightShift(const std::string& binary, int positions);
Shift bits left or right. Left shift multiplies by 2, right shift divides by 2.
Examples:
Binary::leftShift("101", 2); // "10100" (5 << 2 = 20)
Binary::rightShift("1100", 2); // "11" (12 >> 2 = 3)
Utility Functions
Validation
static bool isValid(const std::string& binary);
Check if a string contains only valid binary digits (0 and 1).
Examples:
Binary::isValid("1010"); // true
Binary::isValid("1012"); // false (contains '2')
Binary::isValid("abc"); // false
Padding
static std::string padLeft(const std::string& binary, size_t length);
Add zeros to the left to reach a specific length.
Examples:
Binary::padLeft("101", 8); // "00000101"
Binary::padLeft("1111", 8); // "00001111"
Binary::padLeft("10101010", 4);// "10101010" (already longer)
Counting Bits
static int countOnes(const std::string& binary);
static int countZeros(const std::string& binary);
Count the number of 1s or 0s in a binary number.
Examples:
Binary::countOnes("1010"); // 2
Binary::countZeros("1010"); // 2
Binary::countOnes("1111"); // 4
Binary::countZeros("0000"); // 4
Real-World Examples
Converting Your Age to Binary
int age = 15;
std::string binaryAge = Binary::fromDecimal(age); // "1111"
std::cout << "I'm " << binaryAge << " years old in binary!\n";
Checking if a Number is Even
std::string num = Binary::fromDecimal(42); // "101010"
// If last bit is 0, the number is even
bool isEven = (num.back() == '0'); // true
Simple Encryption with XOR
std::string message = "1010";
std::string key = "1100";
std::string encrypted = Binary::bitwiseXOR(message, key); // "0110"
std::string decrypted = Binary::bitwiseXOR(encrypted, key);// "1010" (back to original!)
Creating Bit Masks
// Create a mask with 4 ones
std::string mask = Binary::fromDecimal(15); // "1111"
// Use AND to extract bits
std::string data = "10110101";
std::string result = Binary::bitwiseAND(data, Binary::padLeft(mask, 8));
// Gets the last 4 bits: "0101"
Understanding Binary
- Each digit is called a "bit"
- 8 bits make a "byte"
- Right to left: Each position is worth 2^n (1, 2, 4, 8, 16, 32, ...)
Example: 1011 = (1×8) + (0×4) + (1×2) + (1×1) = 8 + 0 + 2 + 1 = 11
Tips
- Use
padLeft()to make binary numbers the same length before comparing - Bitwise operations are much faster than regular math in computers
- Left shift by n is the same as multiplying by 2^n
- Right shift by n is the same as dividing by 2^n (rounded down)
Hexadecimal
The Hexadecimal class provides functions for working with hexadecimal numbers (base 16). Hex is widely used in computing for colors, memory addresses, and more.
Overview
Hexadecimal (hex) uses 16 digits: 0-9 and A-F (where A=10, B=11, C=12, D=13, E=14, F=15). It's popular because each hex digit represents exactly 4 binary digits (bits).
Include
#include <imeth/base/hexadecimal.hpp>
Conversion Functions
FROM Decimal TO Hexadecimal
static std::string fromDecimal(int decimal);
Examples:
Hexadecimal::fromDecimal(10); // "A"
Hexadecimal::fromDecimal(15); // "F"
Hexadecimal::fromDecimal(16); // "10"
Hexadecimal::fromDecimal(255); // "FF"
Hexadecimal::fromDecimal(42); // "2A"
Hexadecimal::fromDecimal(4096); // "1000"
Hexadecimal::fromDecimal(-10); // "-A"
FROM Hexadecimal TO Decimal
static int toDecimal(const std::string& hex);
Examples:
Hexadecimal::toDecimal("A"); // 10
Hexadecimal::toDecimal("F"); // 15
Hexadecimal::toDecimal("10"); // 16
Hexadecimal::toDecimal("FF"); // 255
Hexadecimal::toDecimal("2A"); // 42
Hexadecimal::toDecimal("1000"); // 4096
Hexadecimal::toDecimal("ff"); // 255 (case insensitive)
Arithmetic Operations
static std::string add(const std::string& a, const std::string& b);
static std::string subtract(const std::string& a, const std::string& b);
static std::string multiply(const std::string& a, const std::string& b);
Perform basic math directly in hexadecimal.
Examples:
Hexadecimal::add("A", "5"); // "F" (10 + 5 = 15)
Hexadecimal::add("FF", "1"); // "100" (255 + 1 = 256)
Hexadecimal::subtract("20", "A"); // "16" (32 - 10 = 22)
Hexadecimal::multiply("10", "10"); // "100" (16 × 16 = 256)
Utility Functions
Validation
static bool isValid(const std::string& hex);
Check if a string contains only valid hexadecimal digits (0-9, A-F).
Examples:
Hexadecimal::isValid("1234"); // true
Hexadecimal::isValid("ABCDEF"); // true
Hexadecimal::isValid("FF00"); // true
Hexadecimal::isValid("GHI"); // false (G, H, I are not hex digits)
Hexadecimal::isValid("ff"); // true (case insensitive)
Case Conversion
static std::string toUpperCase(const std::string& hex);
static std::string toLowerCase(const std::string& hex);
Convert hex strings between upper and lowercase.
Examples:
Hexadecimal::toUpperCase("2a"); // "2A"
Hexadecimal::toUpperCase("ff"); // "FF"
Hexadecimal::toLowerCase("2A"); // "2a"
Hexadecimal::toLowerCase("FF"); // "ff"
Padding
static std::string padLeft(const std::string& hex, size_t length);
Add zeros to the left to reach a specific length.
Examples:
Hexadecimal::padLeft("FF", 4); // "00FF"
Hexadecimal::padLeft("A", 2); // "0A"
Hexadecimal::padLeft("1234", 3); // "1234" (already longer)
Real-World Examples
RGB Colors
Colors on screens are often represented in hex!
// RGB color: Red=255, Green=128, Blue=64
std::string red = Hexadecimal::fromDecimal(255); // "FF"
std::string green = Hexadecimal::fromDecimal(128); // "80"
std::string blue = Hexadecimal::fromDecimal(64); // "40"
std::string color = red + green + blue; // "FF8040"
std::cout << "Color code: #" << color << "\n"; // #FF8040
Converting Hex Color Codes
// Parse color #A1B2C3
std::string hexColor = "A1B2C3";
int red = Hexadecimal::toDecimal(hexColor.substr(0, 2)); // 161
int green = Hexadecimal::toDecimal(hexColor.substr(2, 2)); // 178
int blue = Hexadecimal::toDecimal(hexColor.substr(4, 2)); // 195
std::cout << "RGB(" << red << ", " << green << ", " << blue << ")\n";
Memory Addresses
Computer memory addresses are shown in hex:
// A typical memory address
std::string address = "7FFF5C";
int decimal = Hexadecimal::toDecimal(address); // 8388444
std::cout << "Memory location: 0x" << address << "\n";
Binary to Hex Conversion
Since 4 binary digits = 1 hex digit, hex is a compact way to write binary:
Binary: 1111 1010 0101
Hex: F A 5
// If you have binary "111110100101"
// Group into 4s: 1111 1010 0101
// Each group: F, A, 5
// Result: FA5 in hex
int decimal = Binary::toDecimal("111110100101"); // 4005
std::string hex = Hexadecimal::fromDecimal(decimal); // "FA5"
Common Hex Values
// Powers of 16
Hexadecimal::fromDecimal(16); // "10"
Hexadecimal::fromDecimal(256); // "100"
Hexadecimal::fromDecimal(4096); // "1000"
// Max values
Hexadecimal::fromDecimal(255); // "FF" (max 8-bit value)
Hexadecimal::fromDecimal(65535); // "FFFF" (max 16-bit value)
Understanding Hexadecimal
- 16 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
- A through F: A=10, B=11, C=12, D=13, E=14, F=15
- Right to left: Each position is worth 16^n (1, 16, 256, 4096, ...)
Example: 2A in hex = (2×16) + (10×1) = 32 + 10 = 42 in decimal
Why Use Hexadecimal?
- Compact Binary: 4 binary digits = 1 hex digit
- Colors: Web colors use hex (#FF0000 = red)
- Memory: Addresses and data dumps
- File Formats: Image files, network packets
- Easier to Read: Than long binary strings
Hex Counting
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, ..., 1F, 20, ...
// Count from 0 to 20 in hex
for (int i = 0; i <= 20; ++i) {
std::cout << i << " = " << Hexadecimal::fromDecimal(i) << " (hex)\n";
}
// Output includes:
// 10 = A (hex)
// 15 = F (hex)
// 16 = 10 (hex)
// 20 = 14 (hex)
Hex Addition Example
2A
+ 1F
----
49
How it works:
- A + F = 10 + 15 = 25 (decimal) = 19 (hex), write 9, carry 1
- 2 + 1 + 1 (carry) = 4
- Result: 49 (hex) = 73 (decimal)
Hexadecimal::add("2A", "1F"); // "49"
Tips
- Both uppercase and lowercase work: "FF" and "ff" are the same
- Use
padLeft()to format numbers:padLeft("A", 2)gives "0A" - Hex is everywhere in web development (colors!)
- In C++, you can write hex literals with 0x:
int x = 0x2A;(equals 42) - Two hex digits = one byte (8 bits)
Common Hex Patterns
// All F's are special
Hexadecimal::toDecimal("F"); // 15 (max 4 bits)
Hexadecimal::toDecimal("FF"); // 255 (max 8 bits / 1 byte)
Hexadecimal::toDecimal("FFF"); // 4095 (max 12 bits)
Hexadecimal::toDecimal("FFFF"); // 65535 (max 16 bits / 2 bytes)
Octal
The Octal class provides functions for working with octal numbers (base 8). Octal is commonly used in computing, especially in Unix/Linux file permissions.
Overview
Octal uses digits 0-7. It's a convenient way to represent binary numbers because each octal digit represents exactly 3 binary digits (bits). For example, octal 7 = binary 111.
Include
#include <imeth/base/octal.hpp>
Conversion Functions
FROM Decimal TO Octal
static std::string fromDecimal(int decimal);
Examples:
Octal::fromDecimal(8); // "10"
Octal::fromDecimal(64); // "100"
Octal::fromDecimal(42); // "52"
Octal::fromDecimal(255); // "377"
Octal::fromDecimal(0); // "0"
Octal::fromDecimal(-10); // "-12"
FROM Octal TO Decimal
static int toDecimal(const std::string& octal);
Examples:
Octal::toDecimal("10"); // 8
Octal::toDecimal("100"); // 64
Octal::toDecimal("52"); // 42
Octal::toDecimal("377"); // 255
Octal::toDecimal("-12"); // -10
Arithmetic Operations
static std::string add(const std::string& a, const std::string& b);
static std::string subtract(const std::string& a, const std::string& b);
static std::string multiply(const std::string& a, const std::string& b);
Perform basic math directly in octal.
Examples:
Octal::add("12", "5"); // "17" (10 + 5 = 15 in decimal)
Octal::subtract("20", "7"); // "11" (16 - 7 = 9 in decimal)
Octal::multiply("7", "7"); // "61" (7 × 7 = 49 in decimal)
Octal::add("77", "1"); // "100" (63 + 1 = 64 in decimal)
Utility Functions
Validation
static bool isValid(const std::string& octal);
Check if a string contains only valid octal digits (0-7).
Examples:
Octal::isValid("1234567"); // true
Octal::isValid("123"); // true
Octal::isValid("789"); // false (8 and 9 are not octal digits)
Octal::isValid("abc"); // false
Padding
static std::string padLeft(const std::string& octal, size_t length);
Add zeros to the left to reach a specific length.
Examples:
Octal::padLeft("12", 4); // "0012"
Octal::padLeft("777", 4); // "0777"
Octal::padLeft("1234", 3); // "1234" (already longer)
Real-World Examples
Unix/Linux File Permissions
File permissions in Unix/Linux are often shown in octal!
// rwxr-xr-x = 755 in octal
// rwx = 111 (binary) = 7 (octal) - owner can read, write, execute
// r-x = 101 (binary) = 5 (octal) - group can read and execute
// r-x = 101 (binary) = 5 (octal) - others can read and execute
std::string permissions = "755";
int decimal = Octal::toDecimal(permissions); // 493
std::cout << "Decimal value: " << decimal << "\n";
Binary to Octal Conversion
Since 3 binary digits = 1 octal digit, octal is a compact way to write binary:
Binary: 111 101 010
Octal: 7 5 2
// If you have binary "111101010"
// Group into 3s: 111 101 010
// Each group: 7, 5, 2
// Result: 752 in octal
int decimal = Binary::toDecimal("111101010"); // 490
std::string octal = Octal::fromDecimal(decimal); // "752"
Counting in Octal
// Octal counting: 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, ..., 17, 20
for (int i = 0; i <= 20; ++i) {
std::cout << i << " = " << Octal::fromDecimal(i) << " (octal)\n";
}
// Output:
// 0 = 0 (octal)
// 1 = 1 (octal)
// ...
// 7 = 7 (octal)
// 8 = 10 (octal)
// 9 = 11 (octal)
// ...
Understanding Octal
- Each digit can be 0-7 (no 8 or 9!)
- Right to left: Each position is worth 8^n (1, 8, 64, 512, ...)
Example: 52 in octal = (5×8) + (2×1) = 40 + 2 = 42 in decimal
Why Use Octal?
- Compact Binary: 3 binary digits = 1 octal digit
- File Permissions: Standard in Unix/Linux systems
- Historical: Used in older computer systems
- Easier to Read: Than long binary strings
Octal Addition Example
47
+ 35
----
104
How it works:
- 7 + 5 = 12 (decimal) = 14 (octal), write 4, carry 1
- 4 + 3 + 1 (carry) = 8 (decimal) = 10 (octal), write 0, carry 1
- Result: 104 (octal)
Octal::add("47", "35"); // "104"
Tips
- Remember: digits only go up to 7!
- When you see "10" in octal, it means 8 in decimal
- Octal is great for grouping binary numbers
- In C++, you can write octal literals with a leading 0:
int x = 052;(equals 42 in decimal)