https://github.com/tigran-sargsyan-w/cpp-module-02
This module is designed to help you understand ad-hoc polymorphism, function overloading, and orthodox canonical classes in C++.
https://github.com/tigran-sargsyan-w/cpp-module-02
42 42-school ad-hoc-polymorphism bsp canonical-form cpp cpp-modules cpp98 cross-product fixed fixed-point geometry module02 operator-overloading operator-overloads orthodox-canonical orthodox-canonical-class point-in-triangle school-42
Last synced: 3 days ago
JSON representation
This module is designed to help you understand ad-hoc polymorphism, function overloading, and orthodox canonical classes in C++.
- Host: GitHub
- URL: https://github.com/tigran-sargsyan-w/cpp-module-02
- Owner: tigran-sargsyan-w
- Created: 2025-11-26T21:15:56.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-23T10:47:47.000Z (5 months ago)
- Last Synced: 2026-05-06T11:49:03.991Z (27 days ago)
- Topics: 42, 42-school, ad-hoc-polymorphism, bsp, canonical-form, cpp, cpp-modules, cpp98, cross-product, fixed, fixed-point, geometry, module02, operator-overloading, operator-overloads, orthodox-canonical, orthodox-canonical-class, point-in-triangle, school-42
- Language: C++
- Homepage:
- Size: 48.8 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# C++ Module 02 β Fixed-Point Numbers & Operator Overloading π’π§©
β
**Status**: Completed β all mandatory exercises *(ex03 optional)*
π« **School**: 42 β C++ Modules (Module 02)
π
**Score**: 100/100
> *Ad-hoc polymorphism, operator overloading, and the Orthodox Canonical Class Form (C++98).*
---
## π Table of Contents
* [Description](#-description)
* [Goals of the Module](#-goals-of-the-module)
* [How `Fixed` Works (Quick Intuition)](#-how-fixed-works-quick-intuition)
* [Bit Shifts and Powers of Two](#bit-shifts-and-powers-of-two)
* [How BSP Works (ex03)](#-how-bsp-works-ex03)
* [BSP](#bsp)
* [Cross Product](#cross-product)
* [Right-Hand Rule](#right-hand-rule)
* [What the `cross` Value Means](#what-the-cross-value-means)
* [Exercises Overview](#-exercises-overview)
* [ex00 β My First Class in Orthodox Canonical Form](#ex00--my-first-class-in-orthodox-canonical-form)
* [ex01 β Towards a more useful fixed-point number class](#ex01--towards-a-more-useful-fixed-point-number-class)
* [ex02 β Now weβre talking](#ex02--now-were-talking)
* [ex03 β BSP (optional)](#ex03--bsp-optional)
* [Requirements](#-requirements)
* [Build & Run](#-build--run)
* [Repository Layout](#-repository-layout)
* [Testing Tips](#-testing-tips)
* [42 Notes](#-42-notes)
---
## π Description
This repository contains my solutions to **42βs C++ Module 02 (C++98)**.
The module focuses on building a **fixed-point number class**, progressively enhancing it with conversions, stream output, comparisons, arithmetic, and increment/decrement operators β all while respecting the **Orthodox Canonical Form**.
---
## π― Goals of the Module
Concepts covered:
* **Orthodox Canonical Form** (default ctor, copy ctor, copy assignment, destructor)
* **Operator overloading** (`<<`, comparisons, arithmetic, ++/--, min/max)
* Fixed-point representation and precision behavior (fractional bits)
* Clean separation: **headers** (`.hpp`) vs **implementation** (`.cpp`)
---
## π§ How `Fixed` Works (Quick Intuition)
In this module, `Fixed` stores a real number using an **integer** internally:
* The internal storage is usually something like `int raw`.
* The class uses a constant number of **fractional bits** (in the subject itβs typically `8`).
* That means your value is scaled by:
```cpp
scale = 1 << fractionalBits; // for 8 bits => 1 << 8 == 256
```
So you can think of it like:
* **Real value** = `raw / 256`
* **Raw value** = `real * 256`
Examples (with 8 fractional bits):
* `1.0` is stored as `256`
* `42.0` is stored as `42 * 256 = 10752`
* the smallest step (epsilon) is `1 / 256`
Thatβs also why in **ex02** `++fixed` increases the value by exactly **one epsilon**: it increments the raw integer by `1`, which corresponds to `+1/256`.
---
### Bit Shifts and Powers of Two
#### Multiplying by 2^n
For integer values, multiplying by 2^n can be done in several ways.
* **Using bitwise left shift** (recommended for integers):
```cpp
int result = x << n; // x * 2^n
```
* **Using the `pow` function from the `` library** (less ideal for integers because it uses floating point):
```cpp
#include
int result = static_cast(x * pow(2, n)); // x * 2^n
```
* **Using a loop**:
```cpp
int result = x;
for (int i = 0; i < n; ++i)
{
result *= 2; // multiply by 2 each step
}
```
---
#### Dividing by 2^n
For positive integers, dividing by 2^n can also be written in several ways.
* **Using bitwise right shift** (for non-negative integers):
```cpp
int result = x >> n; // x / 2^n, fractional part is discarded
```
* **Using integer division with a power-of-two factor**:
```cpp
int result = x / (1 << n); // x / 2^n, integer division
```
* **Using a loop**:
```cpp
int result = x;
for (int i = 0; i < n; ++i)
{
result /= 2; // divide by 2 each step, discarding fractions
}
```
In summary:
* `x << n` is equivalent to `x * 2^n` (for integers without overflow).
* `x >> n` is roughly equivalent to `x / 2^n` for non-negative integers, with the fractional part discarded.
> π How it maps to `Fixed`
> If your `Fixed` has `fractionalBits = 8`, then:
>
> * Converting `int -> Fixed` is basically `raw = i << 8`
> * Converting `Fixed -> int` is basically `i = raw >> 8` (discarding fractions)
---
## π How BSP Works (ex03)
This section is a practical explanation of the idea behind **ex03**: checking whether a point `P` lies strictly inside triangle `ABC`.
In this module we typically use the **cross product** approach (orientation test).
### BSP
BSP (Binary Space Partitioning) is a technique that can be used to determine whether a point `P` is inside triangle `ABC`.
#### How do we determine where `P` is relative to triangle `ABC`?
Hereβs a great article describing two of the most popular approaches (in English):
[https://www.sunshine2k.de/coding/java/PointInTriangle/PointInTriangle.html](https://www.sunshine2k.de/coding/java/PointInTriangle/PointInTriangle.html)
There are multiple ways to solve the βpoint in triangleβ problem:
* using the cross product of vectors
* using barycentric coordinates
* using triangle areas
* using angles between vectors
* etc.
In this module, we implement the first approach β using the **cross product**.
---
### Cross Product
A **point** is a position: `A(x, y)`.
A **vector** is a direction + length, obtained by βgoing from one point to anotherβ.
Example:
* `A(0, 0)`
* `B(10, 0)`
Then vector `AB = B - A`:
* `AB.x = B.x - A.x = 10 - 0 = 10`
* `AB.y = B.y - A.y = 0 - 0 = 0`
So `AB = (10, 0)` β an arrow pointing right.
Similarly:
* `AP = P - A`
* `BC = C - B`
* `BP = P - B`
* etc.
π In code, this is typically written like:
```cpp
Fixed abx = b.getX() - a.getX();
Fixed aby = b.getY() - a.getY();
Fixed apx = p.getX() - a.getX();
Fixed apy = p.getY() - a.getY();
```
Formula:
```text
cross(AB, AP) = AB.x * AP.y - AB.y * AP.x
```
The cross product of two vectors is perpendicular to both (in 2D we effectively compute the **Z component**), and its **sign** tells us the orientation (clockwise vs counter-clockwise).
---
### Right-Hand Rule
Using the right-hand rule, we can understand where point `P` lies relative to the directed line `AB`.
Common right-hand rule variants:
1. Index finger + middle finger RHR (three-finger rule).

2. Curl Fingers RHR (right-hand screw rule).

3. Palm-push RHR (right-hand palm rule).

> β οΈ Note: the last image link may expire (it contains a signed URL). If you want long-term stability on GitHub, consider rehosting it or switching to a stable source.
---
### What the `cross` Value Means
This part is the most important:
* The **sign** tells where `P` is relative to the directed line `AB`:
* `cross > 0` β `P` is on the **left** side of `AB`
* `cross < 0` β `P` is on the **right** side of `AB`
* `cross = 0` β `P` lies **on the line** `AB` (on the boundary)
π How itβs used for triangle `ABC`:
* Compute `cross(AB, AP)`, `cross(BC, BP)`, `cross(CA, CP)`
* If all three have the **same sign** (and none is `0`), then the point is **strictly inside**
* If any of them is `0`, the point is on an edge/vertex β **false** (per subject: edges/vertices are excluded)
---
## π¦ Exercises Overview
### ex00 β My First Class in Orthodox Canonical Form
**Goal:** Create a `Fixed` class (OCF) storing a fixed-point value as an `int`, with **8 fractional bits** stored as a `static const int`. Add `getRawBits()` / `setRawBits()`.
---
### ex01 β Towards a more useful fixed-point number class
**Goal:** Add:
* `Fixed(int const)`
* `Fixed(float const)`
* `toFloat()` and `toInt()`
* `operator<<` to print float representation
**Allowed function:** `roundf` (from ``)
---
### ex02 β Now weβre talking
**Goal:** Add:
* Comparisons: `> < >= <= == !=`
* Arithmetic: `+ - * /`
* Pre/Post increment & decrement
* Static `min` / `max` overloads for const and non-const references
**Allowed function:** `roundf` (from ``)
---
### ex03 β BSP (optional)
**Goal:** Implement:
* `Point` class with **const** `Fixed` coordinates
* `bsp(a, b, c, point)` β `true` only if `point` is strictly inside triangle (edges/vertices β false)
---
## π Requirements
From the subject:
* **Compiler**: `c++`
* **Flags**: `-Wall -Wextra -Werror` + `-std=c++98`
* Forbidden: `printf`, `malloc/alloc`, `free` (and family)
* Also forbidden unless explicitly allowed: `using namespace ...`, `friend`
* **No STL containers/algorithms** until later modules (08/09)
Makefile expectations follow the same rules as in C projects (targets like `all/clean/fclean/re`, no unnecessary relink, etc.).
---
## βΆοΈ Build & Run
```bash
git clone
cd cpp-module-02
```
```bash
cd ex00 && make && ./a.out
cd ../ex01 && make && ./a.out
cd ../ex02 && make && ./a.out
cd ../ex03 && make && ./a.out # optional
```
---
## π Repository Layout
```text
cpp-module-02/
βββ ex00/ (Fixed OCF + raw bits)
βββ ex01/ (int/float conversions + operator<<)
βββ ex02/ (full operators)
βββ ex03/ (Point + bsp) [optional]
```
---
## π Testing Tips
* Verify that `toInt()` truncates toward zero (fraction discarded)
* Compare `a++` vs `++a`
* Validate `min/max` for const and non-const overloads
* For ex03: points inside/outside/on-edge/on-vertex (edge & vertex must be false)
---
## π§Ύ 42 Notes
* C++ modules do **not** use Norminette; readability still matters for peer evaluation.
* From Module 02 onward, **Orthodox Canonical Form is mandatory** unless stated otherwise.