Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,66 @@
# Rust Sessions
Intro to primitives
# Computer Architecture: Stack and Heap Explained

This is a simplified explanation of computer architecture, focusing on the **stack** and **heap** sections of memory.

---

## **Computer Architecture Basics**
Computer architecture is like the blueprint of how a computer works. It includes the CPU (brain), memory (where data is stored), and other components that work together to run programs.

Memory is divided into different sections, and two of the most important ones are the **stack** and the **heap**. These are used to store data while a program is running.

---

## **The Stack**
- **What it is**: The stack is a section of memory that works like a stack of plates: **Last In, First Out (LIFO)**. This means the last thing you put on the stack is the first thing you take off.
- **How it works**:
- When a function is called, its data (like local variables) is "pushed" onto the stack.
- When the function finishes, its data is "popped" off the stack.
- **Why it's fast**: The stack is very organized and predictable, so the CPU can access it quickly.
- **What it stores**:
- Local variables (e.g., `int x = 10;`).
- Function calls and their return addresses.
- **Limitations**:
- The stack has a fixed size, so if you try to store too much data (e.g., with deep recursion), you get a **stack overflow** error.

---

## **The Heap**
- **What it is**: The heap is a section of memory used for **dynamic memory allocation**. Unlike the stack, it doesn't follow a strict order, and you can allocate and free memory whenever you need.
- **How it works**:
- When you need memory (e.g., for an array or object), you request it from the heap using functions like `malloc()` in C or `new` in C++/Java.
- You must manually free this memory when you're done (in some languages, like C/C++), or it will lead to **memory leaks**.
- **Why it's flexible**: The heap can grow and shrink as needed, and you can allocate large amounts of memory.
- **What it stores**:
- Dynamically created objects (e.g., `int* arr = new int[100];`).
- Data that needs to persist beyond the scope of a function.
- **Limitations**:
- The heap is slower than the stack because it’s less organized.
- Managing memory manually can lead to errors like memory leaks or dangling pointers.

---

## **Stack vs. Heap: Key Differences**
| **Feature** | **Stack** | **Heap** |
|--------------------|------------------------------------|-----------------------------------|
| **Speed** | Fast | Slower |
| **Memory Management** | Automatic (handled by the system) | Manual (programmer must manage) |
| **Size** | Fixed size | Flexible size |
| **Lifetime** | Short (tied to function scope) | Long (persists until freed) |
| **Use Case** | Local variables, function calls | Dynamic data, large objects |

---

## **Example in Code**
```c
#include <stdlib.h>

void function() {
int x = 10;
int* y = (int*)malloc(sizeof(int));
*y = 20;
free(y);
}
```

![Alt Text](illustration.png)
21 changes: 21 additions & 0 deletions fp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Difference between f32 and f64

1. Size and Memory Usage

f32 takes 4 bytes (32 bits) of memory, whereas f64 takes 8 bytes (64 bits).
Because of the smaller size, f32 uses less memory, which can be useful in memory-constrained environments (e.g., embedded systems, GPUs).

2. Precision

f32 has 6–9 decimal digits of precision.
This means that the smallest difference between two numbers that f32 can distinguish is on the order of 10⁻⁶ to 10⁻⁹, depending on the number's size.

f64 has 15–17 decimal digits of precision.
This provides more accurate representation of floating-point numbers with less rounding errors compared to f32. f64 is more suitable for scientific, financial, and high-precision calculations.

3. Range

f32 has a range of approximately ±3.4 × 10⁻³⁸ to ±3.4 × 10³⁸.
f64 has a range of approximately ±1.7 × 10⁻³⁰ to ±1.7 × 10³⁰.

The f64 type can represent much larger and much smaller numbers than f32, which is important in fields like astronomy, physics simulations, or high-precision calculations.
Binary file added illustration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 115 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,129 @@

fn main() {
intro_to_u();
intro_to_i();
intro_to_bool();
intro_to_string();
}


// function to encapsulate all integers
fn intro_to_u() {
let sum_result: u8 = sum(5, 10);
println!("the sum result is: {}", sum_result);

let sum_result_for_unsigned_integer: u8 = sum_for_unsigned_integer(5, 10);
let subtraction_result_for_unsigned_integer: u8 = subtraction_for_unsigned_integer(10, 5);
let multiplication_result_for_unsigned_integer: u8 = multiplication_for_unsigned_integer(5, 10);
let division_result_for_unsigned_integer: f32 = division_for_unsigned_integer(10.0, 3.0);

let u8int_to_u32int = convert_u8int_to_u32int(200);
let u32int_to_u8int = convert_u32int_to_u8int(100);

println!("The sum is (Unsigned Int): {}", sum_result_for_unsigned_integer);
println!("The difference is (Unsigned Int): {}", subtraction_result_for_unsigned_integer);
println!("The multiplication is (Unsigned Int): {}", multiplication_result_for_unsigned_integer);
println!("The division is (Unsigned Int): {}", division_result_for_unsigned_integer);

println!("u8 to u3 conversion: {}", u8int_to_u32int);
println!("u32 to u8 conversion: {}", u32int_to_u8int);

}

fn intro_to_i(){

let sum_result_for_signed_integer: i8 = sum_for_signed_integer(5, 10);
let subtraction_result_for_signed_integer: i8 = subtraction_for_signed_integer(10, 5);
let multiplication_result_for_signed_integer: i8 = multiplication_for_signed_integer(5, 10);
let division_result_for_signed_integer: i8 = division_for_signed_integer(10, 2);

println!("The sum is (Signed Int): {}", sum_result_for_signed_integer);
println!("The difference is (Signed Int): {}", subtraction_result_for_signed_integer);
println!("The multiplication is (Signed Int): {}", multiplication_result_for_signed_integer);
println!("The division is (Signed Int): {}", division_result_for_signed_integer);

}

fn intro_to_bool(){
let is_sum_even: bool = is_sum_even(10,5);
println!("Is Sum even?: {}", is_sum_even);
}

fn intro_to_string(){
let name: String = display_name("Jethro".to_string(), "Adamu".to_string());
let reg_number: String = String::from("HG-2025-001");
let reg_number_to_string: &str = convert_string_to_str(&reg_number);

println!("Your name is: {}", name);
println!("Registration number as String slice: {}", reg_number_to_string);
}

/////////////////////////////////////////////////////////////////////////////////////////
/********** This Block handles arithmetic operations for unsigned integers *************/
/////////////////////////////////////////////////////////////////////////////////////////
fn sum_for_unsigned_integer(x:u8, y:u8) -> u8 {
x + y
}

fn subtraction_for_unsigned_integer(x:u8, y:u8) -> u8 {
x - y
}

fn multiplication_for_unsigned_integer(x:u8, y:u8) -> u8 {
x * y
}

fn division_for_unsigned_integer(x:f32, y:f32) -> f32 {
x / y
}

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////
/********** This Block handles arithmetic operations for signed integers *************/
/////////////////////////////////////////////////////////////////////////////////////////
fn sum_for_signed_integer(x:i8, y:i8) -> i8 {
x + y
}

fn subtraction_for_signed_integer(x:i8, y:i8) -> i8 {
x - y
}

fn sum(x: u8, y: u8) -> u8 {
x + y // implicit return
// return x + y; // explicit return
fn multiplication_for_signed_integer(x:i8, y:i8) -> i8 {
x * y
}

fn division_for_signed_integer(x:i8, y:i8) -> i8 {
x / y
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// subtract
// multiplication
// division
fn is_sum_even(x:u8, y:u8) -> bool {
let check_result = sum_for_unsigned_integer(x, y);
if check_result % 2 == 0 {
return true;
} else {
return false;
}
}

fn display_name(first_name: String, last_name: String) -> String {
return format!("{} {}", first_name, last_name);
}

/////////////////////////////////////////////////////////////////////////////////////////
/******************* This Block handles all conversion function ************************/
/////////////////////////////////////////////////////////////////////////////////////////

fn convert_u8int_to_u32int(u8int: u8) -> u32{
return u8int.into();
}

fn convert_u32int_to_u8int(u32int: u32) -> u8 {
return u32int.try_into().expect("The return value is out of range for u8");
}

fn convert_string_to_str(string_name: &String) -> &str {
return string_name.as_str();
}