{"id":50338707,"url":"https://github.com/tigran-sargsyan-w/cpp-module-02","last_synced_at":"2026-05-29T15:30:22.730Z","repository":{"id":326429795,"uuid":"1104901114","full_name":"tigran-sargsyan-w/cpp-module-02","owner":"tigran-sargsyan-w","description":"This module is designed to help you understand ad-hoc polymorphism, function overloading, and orthodox canonical classes in C++.","archived":false,"fork":false,"pushed_at":"2025-12-23T10:47:47.000Z","size":50,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T11:49:03.991Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigran-sargsyan-w.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-26T21:15:56.000Z","updated_at":"2025-12-23T10:47:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tigran-sargsyan-w/cpp-module-02","commit_stats":null,"previous_names":["tigran-sargsyan-w/cpp-module-02"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tigran-sargsyan-w/cpp-module-02","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-02","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-02/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-02/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-02/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigran-sargsyan-w","download_url":"https://codeload.github.com/tigran-sargsyan-w/cpp-module-02/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-02/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33659872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2026-05-29T15:30:21.028Z","updated_at":"2026-05-29T15:30:22.715Z","avatar_url":"https://github.com/tigran-sargsyan-w.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# C++ Module 02 – Fixed-Point Numbers \u0026 Operator Overloading 🔢🧩\n\n✅ **Status**: Completed – all mandatory exercises *(ex03 optional)*  \n🏫 **School**: 42 – C++ Modules (Module 02)  \n🏅 **Score**: 100/100\n\n\u003e *Ad-hoc polymorphism, operator overloading, and the Orthodox Canonical Class Form (C++98).*\n\n---\n\n## 📚 Table of Contents\n\n* [Description](#-description)\n* [Goals of the Module](#-goals-of-the-module)\n* [How `Fixed` Works (Quick Intuition)](#-how-fixed-works-quick-intuition)\n\n  * [Bit Shifts and Powers of Two](#bit-shifts-and-powers-of-two)\n* [How BSP Works (ex03)](#-how-bsp-works-ex03)\n\n  * [BSP](#bsp)\n  * [Cross Product](#cross-product)\n  * [Right-Hand Rule](#right-hand-rule)\n  * [What the `cross` Value Means](#what-the-cross-value-means)\n* [Exercises Overview](#-exercises-overview)\n\n  * [ex00 – My First Class in Orthodox Canonical Form](#ex00--my-first-class-in-orthodox-canonical-form)\n  * [ex01 – Towards a more useful fixed-point number class](#ex01--towards-a-more-useful-fixed-point-number-class)\n  * [ex02 – Now we’re talking](#ex02--now-were-talking)\n  * [ex03 – BSP (optional)](#ex03--bsp-optional)\n* [Requirements](#-requirements)\n* [Build \u0026 Run](#-build--run)\n* [Repository Layout](#-repository-layout)\n* [Testing Tips](#-testing-tips)\n* [42 Notes](#-42-notes)\n\n---\n\n## 📝 Description\n\nThis repository contains my solutions to **42’s C++ Module 02 (C++98)**.\nThe 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**.\n\n---\n\n## 🎯 Goals of the Module\n\nConcepts covered:\n\n* **Orthodox Canonical Form** (default ctor, copy ctor, copy assignment, destructor)\n* **Operator overloading** (`\u003c\u003c`, comparisons, arithmetic, ++/--, min/max)\n* Fixed-point representation and precision behavior (fractional bits)\n* Clean separation: **headers** (`.hpp`) vs **implementation** (`.cpp`)\n\n---\n\n## 🧠 How `Fixed` Works (Quick Intuition)\n\nIn this module, `Fixed` stores a real number using an **integer** internally:\n\n* The internal storage is usually something like `int raw`.\n* The class uses a constant number of **fractional bits** (in the subject it’s typically `8`).\n* That means your value is scaled by:\n\n```cpp\nscale = 1 \u003c\u003c fractionalBits; // for 8 bits =\u003e 1 \u003c\u003c 8 == 256\n```\n\nSo you can think of it like:\n\n* **Real value** = `raw / 256`\n* **Raw value** = `real * 256`\n\nExamples (with 8 fractional bits):\n\n* `1.0` is stored as `256`\n* `42.0` is stored as `42 * 256 = 10752`\n* the smallest step (epsilon) is `1 / 256`\n\nThat’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`.\n\n---\n\n### Bit Shifts and Powers of Two\n\n#### Multiplying by 2^n\n\nFor integer values, multiplying by 2^n can be done in several ways.\n\n* **Using bitwise left shift** (recommended for integers):\n\n```cpp\nint result = x \u003c\u003c n; // x * 2^n\n```\n\n* **Using the `pow` function from the `\u003ccmath\u003e` library** (less ideal for integers because it uses floating point):\n\n```cpp\n#include \u003ccmath\u003e\n\nint result = static_cast\u003cint\u003e(x * pow(2, n)); // x * 2^n\n```\n\n* **Using a loop**:\n\n```cpp\nint result = x;\nfor (int i = 0; i \u003c n; ++i)\n{\n    result *= 2; // multiply by 2 each step\n}\n```\n\n---\n\n#### Dividing by 2^n\n\nFor positive integers, dividing by 2^n can also be written in several ways.\n\n* **Using bitwise right shift** (for non-negative integers):\n\n```cpp\nint result = x \u003e\u003e n; // x / 2^n, fractional part is discarded\n```\n\n* **Using integer division with a power-of-two factor**:\n\n```cpp\nint result = x / (1 \u003c\u003c n); // x / 2^n, integer division\n```\n\n* **Using a loop**:\n\n```cpp\nint result = x;\nfor (int i = 0; i \u003c n; ++i)\n{\n    result /= 2; // divide by 2 each step, discarding fractions\n}\n```\n\nIn summary:\n\n* `x \u003c\u003c n` is equivalent to `x * 2^n` (for integers without overflow).\n* `x \u003e\u003e n` is roughly equivalent to `x / 2^n` for non-negative integers, with the fractional part discarded.\n\n\u003e 🔗 How it maps to `Fixed`\n\u003e If your `Fixed` has `fractionalBits = 8`, then:\n\u003e\n\u003e * Converting `int -\u003e Fixed` is basically `raw = i \u003c\u003c 8`\n\u003e * Converting `Fixed -\u003e int` is basically `i = raw \u003e\u003e 8` (discarding fractions)\n\n---\n\n## 📐 How BSP Works (ex03)\n\nThis section is a practical explanation of the idea behind **ex03**: checking whether a point `P` lies strictly inside triangle `ABC`.\nIn this module we typically use the **cross product** approach (orientation test).\n\n### BSP\n\nBSP (Binary Space Partitioning) is a technique that can be used to determine whether a point `P` is inside triangle `ABC`.\n\n#### How do we determine where `P` is relative to triangle `ABC`?\n\nHere’s a great article describing two of the most popular approaches (in English):\n[https://www.sunshine2k.de/coding/java/PointInTriangle/PointInTriangle.html](https://www.sunshine2k.de/coding/java/PointInTriangle/PointInTriangle.html)\n\nThere are multiple ways to solve the “point in triangle” problem:\n\n* using the cross product of vectors\n* using barycentric coordinates\n* using triangle areas\n* using angles between vectors\n* etc.\n\nIn this module, we implement the first approach — using the **cross product**.\n\n---\n\n### Cross Product\n\nA **point** is a position: `A(x, y)`.\n\nA **vector** is a direction + length, obtained by “going from one point to another”.\n\nExample:\n\n* `A(0, 0)`\n* `B(10, 0)`\n\nThen vector `AB = B - A`:\n\n* `AB.x = B.x - A.x = 10 - 0 = 10`\n* `AB.y = B.y - A.y = 0 - 0 = 0`\n\nSo `AB = (10, 0)` — an arrow pointing right.\nSimilarly:\n\n* `AP = P - A`\n* `BC = C - B`\n* `BP = P - B`\n* etc.\n\n👉 In code, this is typically written like:\n\n```cpp\nFixed abx = b.getX() - a.getX();\nFixed aby = b.getY() - a.getY();\nFixed apx = p.getX() - a.getX();\nFixed apy = p.getY() - a.getY();\n```\n\nFormula:\n\n```text\ncross(AB, AP) = AB.x * AP.y - AB.y * AP.x\n```\n\nThe 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).\n\n---\n\n### Right-Hand Rule\n\nUsing the right-hand rule, we can understand where point `P` lies relative to the directed line `AB`.\n\nCommon right-hand rule variants:\n\n1. Index finger + middle finger RHR (three-finger rule).\n\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Right_hand_rule_cross_product.svg/1200px-Right_hand_rule_cross_product.svg.png\" alt=\"Right-hand rule (three-finger)\" width=\"300\"/\u003e\n\n2. Curl Fingers RHR (right-hand screw rule).\n\n\u003cimg src=\"https://philschatz.com/calculus-book/resources/CNX_Calc_Figure_12_04_001.jpg\" alt=\"Right-hand screw rule\" width=\"300\"/\u003e\n\n3. Palm-push RHR (right-hand palm rule).\n\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/6/63/Openstax_college-physics_22.17_Lorentz-force-right-hand.jpg\" alt=\"Right-hand palm rule\" width=\"300\"/\u003e\n\n\u003e ⚠️ 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.\n\n---\n\n### What the `cross` Value Means\n\nThis part is the most important:\n\n* The **sign** tells where `P` is relative to the directed line `AB`:\n\n  * `cross \u003e 0` → `P` is on the **left** side of `AB`\n  * `cross \u003c 0` → `P` is on the **right** side of `AB`\n  * `cross = 0` → `P` lies **on the line** `AB` (on the boundary)\n\n👉 How it’s used for triangle `ABC`:\n\n* Compute `cross(AB, AP)`, `cross(BC, BP)`, `cross(CA, CP)`\n* If all three have the **same sign** (and none is `0`), then the point is **strictly inside**\n* If any of them is `0`, the point is on an edge/vertex → **false** (per subject: edges/vertices are excluded)\n\n---\n\n## 📦 Exercises Overview\n\n### ex00 – My First Class in Orthodox Canonical Form\n\n**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()`.\n\n---\n\n### ex01 – Towards a more useful fixed-point number class\n\n**Goal:** Add:\n\n* `Fixed(int const)`\n* `Fixed(float const)`\n* `toFloat()` and `toInt()`\n* `operator\u003c\u003c` to print float representation\n\n**Allowed function:** `roundf` (from `\u003ccmath\u003e`)\n\n---\n\n### ex02 – Now we’re talking\n\n**Goal:** Add:\n\n* Comparisons: `\u003e \u003c \u003e= \u003c= == !=`\n* Arithmetic: `+ - * /`\n* Pre/Post increment \u0026 decrement\n* Static `min` / `max` overloads for const and non-const references\n\n**Allowed function:** `roundf` (from `\u003ccmath\u003e`)\n\n---\n\n### ex03 – BSP (optional)\n\n**Goal:** Implement:\n\n* `Point` class with **const** `Fixed` coordinates\n* `bsp(a, b, c, point)` → `true` only if `point` is strictly inside triangle (edges/vertices → false)\n\n---\n\n## 🛠 Requirements\n\nFrom the subject:\n\n* **Compiler**: `c++`\n* **Flags**: `-Wall -Wextra -Werror` + `-std=c++98`\n* Forbidden: `printf`, `malloc/alloc`, `free` (and family)\n* Also forbidden unless explicitly allowed: `using namespace ...`, `friend`\n* **No STL containers/algorithms** until later modules (08/09)\n\nMakefile expectations follow the same rules as in C projects (targets like `all/clean/fclean/re`, no unnecessary relink, etc.).\n\n---\n\n## ▶️ Build \u0026 Run\n\n```bash\ngit clone \u003cthis-repo-url\u003e\ncd cpp-module-02\n```\n\n```bash\ncd ex00 \u0026\u0026 make \u0026\u0026 ./a.out\ncd ../ex01 \u0026\u0026 make \u0026\u0026 ./a.out\ncd ../ex02 \u0026\u0026 make \u0026\u0026 ./a.out\ncd ../ex03 \u0026\u0026 make \u0026\u0026 ./a.out   # optional\n```\n\n---\n\n## 📂 Repository Layout\n\n```text\ncpp-module-02/\n├── ex00/  (Fixed OCF + raw bits)\n├── ex01/  (int/float conversions + operator\u003c\u003c)\n├── ex02/  (full operators)\n└── ex03/  (Point + bsp)  [optional]\n```\n\n---\n\n## 🔍 Testing Tips\n\n* Verify that `toInt()` truncates toward zero (fraction discarded)\n* Compare `a++` vs `++a`\n* Validate `min/max` for const and non-const overloads\n* For ex03: points inside/outside/on-edge/on-vertex (edge \u0026 vertex must be false)\n\n---\n\n## 🧾 42 Notes\n\n* C++ modules do **not** use Norminette; readability still matters for peer evaluation.\n* From Module 02 onward, **Orthodox Canonical Form is mandatory** unless stated otherwise.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-02","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-02","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-02/lists"}