From 025f8b42188874c6f1b72fff22ee834c24f7eada Mon Sep 17 00:00:00 2001 From: olowo Date: Fri, 17 Jan 2025 11:01:10 +0100 Subject: [PATCH 1/5] Darey --- Cargo.toml | 1 + src/main.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7ff3046..da30973 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] + diff --git a/src/main.rs b/src/main.rs index 3cc3d3e..fc8da4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,68 @@ fn main() { intro_to_u(); + intro_to_f(); + intro_to_char() } // 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: u8 = sum(5, 20); + println!("the sum result is: {}", sum_result); + + let subtract_result: u8 = subtract(20, 15); + println!("the subtract result is: {}", subtract_result); + + let multiply_result: u8 = multiply(5, 12); + println!("the multiply result is {}", multiply_result); + + let divide_result: u8 = divide(20, 4); + println!("the divide result is {}", divide_result); + } +// functions for Floating points + +fn intro_to_f() { + let add_result: f64 = add(10.3.into(), 10.1.into()); + println!("the add result is: {}", add_result); + + +let minus_result: f64 = minus(25.5.into(), 5.5.into()); +println! ("the subract2 result is: {}", minus_result); + +let rise_result: f64 = rise(5.2.into(), 3.7.into() ); +println!("the multiply2 result is {}", rise_result); + + +let split_result: f64 = split(30.9.into(), 2.3.into()); +println!("the divide result is {}", split_result); + + + + + +} + + +// function char + + +fn intro_to_char() { +let name_result: String = name('D', 'o'); +println!("The char result is: {}", name_result); + +let myname_result: String = myname("Darey", "Olowo"); + println!("my name are : {}", myname_result); + + +} + + +// function to encapsulate all integers + fn sum(x: u8, y: u8) -> u8 { x + y // implicit return // return x + y; // explicit return @@ -18,7 +70,55 @@ fn sum(x: u8, y: u8) -> u8 { // subtract + +fn subtract(x: u8, y: u8) -> u8 { + return x - y +} + + // multiplication + +fn multiply(x: u8, y: u8) -> u8 { + x * y +} // division +fn divide(x: u8, y: u8) -> u8 { + x / y +} + + + +// Floating-point Types + +fn add(x: f64, y: f64) -> f64 { + x + y +} + +fn minus(x: f64, y: f64) -> f64 { + x - y +} + +fn rise(x: f64, y: f64) -> f64 { + x * y +} + +fn split(x: f64, y: f64) -> f64 { + x / y +} + + +// char type + +fn name(x: char, y: char) -> String { + let mut name = String::new(); + name.push(x); + name.push(y); + name } + + fn myname(x: &str, y: &str) -> String { + let mut myname = String::new(); + myname.push_str(x); + myname.push_str(y); + myname } \ No newline at end of file From eb7e1c175c8e123d3f7e2a3533a12bd8b66a4908 Mon Sep 17 00:00:00 2001 From: olowo Date: Mon, 20 Jan 2025 09:36:35 +0100 Subject: [PATCH 2/5] assignment --- src/main.rs | 229 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 184 insertions(+), 45 deletions(-) diff --git a/src/main.rs b/src/main.rs index fc8da4b..15a6a8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,43 @@ fn main() { intro_to_u(); intro_to_f(); - intro_to_char() + intro_to_char(); + convert_high(); + convert_high_to_low(); + perform_operations(); } - -// function to encapsulate all integers +// function to encapsulate all integers and to check for even numbers fn intro_to_u() { let sum_result: u8 = sum(5, 20); - println!("the sum result is: {}", sum_result); - + println!("the sum result is: {}", sum_result); + println!( + "Is the sum result even? {}", + if is_even(sum_result) { "Yes" } else { "No" } + ); + let subtract_result: u8 = subtract(20, 15); println!("the subtract result is: {}", subtract_result); + println!( + "Is the subtract result even? {}", + if is_even(subtract_result) { "Yes" } else { "No" } + ); let multiply_result: u8 = multiply(5, 12); println!("the multiply result is {}", multiply_result); + println!( + "Is the multiply result even? {}", + if is_even(multiply_result) { "Yes" } else { "No" } + ); + let divide_result: u8 = divide(20, 4); println!("the divide result is {}", divide_result); + println!( + "Is the divide result odd? {}", + if is_odd(divide_result) { "Yes" } else { "No" } + ); + @@ -26,56 +46,43 @@ fn intro_to_u() { // functions for Floating points fn intro_to_f() { - let add_result: f64 = add(10.3.into(), 10.1.into()); + let add_result: f64 = add(10.3.into(), 10.1.into()); println!("the add result is: {}", add_result); + + let minus_result: f64 = minus(25.5.into(), 5.5.into()); + println!("the subract2 result is: {}", minus_result); -let minus_result: f64 = minus(25.5.into(), 5.5.into()); -println! ("the subract2 result is: {}", minus_result); - -let rise_result: f64 = rise(5.2.into(), 3.7.into() ); -println!("the multiply2 result is {}", rise_result); - - -let split_result: f64 = split(30.9.into(), 2.3.into()); -println!("the divide result is {}", split_result); - - - - + let rise_result: f64 = rise(5.2.into(), 3.7.into()); + println!("the multiply2 result is {}", rise_result); + let split_result: f64 = split(30.9.into(), 2.3.into()); + println!("the divide result is {}", split_result); } - // function char - fn intro_to_char() { -let name_result: String = name('D', 'o'); -println!("The char result is: {}", name_result); - -let myname_result: String = myname("Darey", "Olowo"); - println!("my name are : {}", myname_result); - + let name_result: String = name('D', 'o'); + println!("The char result is: {}", name_result); + let myname_result: String = myname("Darey", "Olowo"); + println!("my name are : {}", myname_result); } - // function to encapsulate all integers fn sum(x: u8, y: u8) -> u8 { x + y // implicit return -// return x + y; // explicit return + // return x + y; // explicit return } - // subtract fn subtract(x: u8, y: u8) -> u8 { - return x - y + return x - y; } - // multiplication fn multiply(x: u8, y: u8) -> u8 { @@ -87,8 +94,6 @@ fn divide(x: u8, y: u8) -> u8 { x / y } - - // Floating-point Types fn add(x: f64, y: f64) -> f64 { @@ -107,18 +112,152 @@ fn split(x: f64, y: f64) -> f64 { x / y } +// char type + +fn name(x: char, y: char) -> String { + let mut name = String::new(); + name.push(x); + name.push(y); + name +} + +fn myname(x: &str, y: &str) -> String { + let mut myname = String::new(); + myname.push_str(x); + myname.push_str(y); + myname +} + +// + + + +// function to check for even numbers + +fn is_even(x: u8) -> bool { + x % 2 == 0 +} + + +// to check for odd nummbers + +fn is_odd(x: u8) -> bool { + x % 2 != 0 +} + + + + + +// how to convert u8 to u32 + + fn convert_high(){ + let low: u8 = 255; + let high: u32 = low as u32; + println!("u8 value: {}, u32 value:{}", low, high ); + } + + + +//Function to convert high bit integer to low bit integer u32 to u8 + +fn convert_high_to_low() { + let high: u32 = 300; + let low: u8 = high as u8; // Convert u32 to u8 with truncation + println!("u32 value: {}, u8 value: {}", high, low); +} + + + +//Implement arithmetic operations on signed integers + +fn perform_operations() { + let a: i32 = 25; // A signed 32-bit integer + let b: i32 = -10; // Another signed 32-bit integer + + // Arithmetic operations + let sum = a + b; // Addition + let difference = a - b; // Subtraction + let product = a * b; // Multiplication + let quotient = a / b; // Division + let remainder = a % b; // Modulus (remainder) + + println!("Arithmetic Operations on signed integers:"); + println!("a = {}, b = {}", a, b); + println!("Sum: {}", sum); + println!("Difference: {}", difference); + println!("Product: {}", product); + println!("Quotient: {}", quotient); + println!("Remainder: {}", remainder); +} + + + +//Explain the difference between the fp32 and fp64 data types + + //The key difference between fp32 (32-bit floating-point) and fp64 (64-bit floating-point) lies in their precision and range: + + //1. Bit Size: + // fp32 (32-bit): Uses 32 bits to represent a floating-point number. + // fp64 (64-bit): Uses 64 bits, allowing for more precision and a larger range. + + // 2. Precision: + // fp32: Provides approximately 7 decimal digits of precision. + // fp64: Provides approximately 15-16 decimal digits of precision. + // Example: Calculations with very small differences or many decimal places will be more accurate with fp64. + + // 3. Range: + //fp32: Can represent numbers from approximately 1.4 x 10^-45 to 3.4 x 10^38. + //fp64: Can represent numbers from approximately 5.0 x 10^-324 to 1.8 x 10^308. + //fp64: Covers a wide range than fp32, making it suitable for scientific calculations or financial applications. + + //4. Memory Usage: + // 32: Uses less memory, making it faster for applications where precision isn't critical (e.g., graphics or simulations). + // 64: Requires double the memory of fp32, which may impact performance or storage in large datasets. + + //5. Performance: + // 32: Faster due to smaller size, often used in real-time systems like games or machine learning models. + // 64: Slower but more precise, used in scientific computing, financial applications, or any domain requiring high precision. + + //6. When to Use: + // 32: Use when speed and memory efficiency are more important than precision (e.g., 3D graphics, neural networks). + // 64: Use when precision and range are crucial (e.g., scientific simulations, high-precision calculations). + +//Describe in details the role of pointers in memory management + + //Pointers play a critical role in memory management in programming, particularly in low-level languages like C, C++, and systems programming languages such as Rust (though Rust manages pointers more safely). Here’s a detailed explanation of their roles: + + //1. Memory Address: + // Pointers store the memory address of a variable or data structure in the computer's memory. This address points to the location where the data is stored, allowing programs to access and manipulate it directly. + + //2. Dynamic Memory Allocation: + // Pointers enable dynamic memory allocation, where programs can request memory from the heap at runtime and manage it using pointers. This allows for flexible memory usage and efficient storage of data structures like arrays, linked lists, and trees. + + //3. Efficient Data Access: + // By using pointers, programs can directly access and modify data in memory without copying it, leading to faster and more efficient data processing. Pointers are crucial for tasks like iterating over arrays, traversing linked lists, or accessing hardware registers. + + //4. Pass-by-Reference: + // Pointers enable pass-by-reference in function calls, where functions can modify variables in the calling scope by passing pointers to them. This allows for efficient sharing and manipulation of data across different parts of a program. + + //5. Pointer Arithmetic: + // Pointers support arithmetic operations like addition, subtraction, and comparison, allowing for efficient memory traversal and manipulation. This is essential for tasks like iterating over arrays, implementing data structures, or working with complex data layouts. + + //6. Memory Management: + // Pointers play a key role in memory management, allowing programs to allocate, deallocate, and reallocate memory dynamically. This helps optimize memory usage, prevent memory leaks, and manage resources efficiently in applications. + + //7. Low-Level Programming: + // In low-level programming, pointers are essential for interacting with hardware, managing memory layouts, and implementing efficient algorithms. They provide direct access to memory locations, enabling fine-grained control over data and system resources. + + //8. Pointer Safety: + // While pointers offer powerful capabilities, they can also introduce risks like null pointer dereferencing, memory leaks, and buffer overflows. Modern languages like Rust incorporate safety features to prevent common pointer-related errors and ensure memory safety. + + //In summary, pointers are fundamental to memory management in programming, enabling efficient data access, dynamic memory allocation, pass-by-reference semantics, and low-level system interactions. Understanding and using pointers effectively is crucial for developing performant, memory-efficient, and reliable software applications. + + + + + -// char type -fn name(x: char, y: char) -> String { - let mut name = String::new(); - name.push(x); - name.push(y); - name } - fn myname(x: &str, y: &str) -> String { - let mut myname = String::new(); - myname.push_str(x); - myname.push_str(y); - myname } \ No newline at end of file From 3fa22c6b63af418863da63f33631c41d3bd68e6c Mon Sep 17 00:00:00 2001 From: olowo Date: Tue, 28 Jan 2025 14:13:35 +0100 Subject: [PATCH 3/5] refactor the code --- README.md | 77 +++++++++++++- src/char.rs | 14 +++ src/f64operation.rs | 17 ++++ src/main.rs | 226 +++++++---------------------------------- src/signed_integers.rs | 22 ++++ src/u8operation.rs | 36 +++++++ 6 files changed, 200 insertions(+), 192 deletions(-) create mode 100644 src/char.rs create mode 100644 src/f64operation.rs create mode 100644 src/signed_integers.rs create mode 100644 src/u8operation.rs diff --git a/README.md b/README.md index 3aabe99..e8a44ab 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,75 @@ -# Rust Sessions -Intro to primitives \ No newline at end of file +1. Difference Between fp32 and fp64 Data Types +In Rust, floating-point numbers can be represented by two types + +f32: 32-bit floating-point number +f64: 64-bit floating-point number + Key Differences +Bit Size: +f32 uses 32 bits to represent a number. +f64 uses 64 bits, which allows for more precision and a larger range. + +Precision: +f32 gives you approximately 7 decimal digits of precision. +f64 gives you approximately 15-16 decimal digits of precision + +f32 = 1.1234567; // 7 decimal places, limited precision +f64 = 1.1234567891234567; // 15-16 decimal places, high precision + + +Range: +f32 can represent numbers between 1.4 x 10^-45 to 3.4 x 10^38. +f64 can represent numbers between 5.0 x 10^-324 to 1.8 x 10^308 + +Memory Usage: +f32 uses less memory (4 bytes). +f64 uses double the memory (8 bytes). + +When to Use: +we can use f32 when performance and memory efficiency are important and precision isn’t critical (e.g., graphics, gaming, some ML models). +we can use f64 when higher precision or a larger range is needed (e.g., scientific computations, financial calculations). + + +2. Role of Pointers in Memory Management in Rust +In Rust, pointers are crucial for memory management, but unlike languages like C or C++, Rust provides safe memory management through its ownership model, ensuring that most pointer issues (like dangling pointers, null pointers, etc.) are handled at compile-time. + + Key Points About Pointers in Rust + + +Memory Address: +In Rust, pointers store the memory address of a variable. These are like references to variables stored elsewhere in memory, allowing you to directly manipulate the data. + +let x = 10; +let y = &x; // `y` is a pointer to `x` +println!("The value of x is: {}", x); // Accessing value of `x` directly + +Dynamic Memory Allocation: +Rust automatically manages dynamic memory through its ownership model, but can be manually allocate using Box, Rc (reference-counted), and Arc (atomic reference-counted) for heap-allocated data. + +Efficient Data Access: +By using references (essentially pointers) in Rust, data can be passed around efficiently without being copied. +let s = String::from("Hello"); +let t = &s; // Borrowing a reference to `s` +println!("{}", t); // Access data without copying + +Pass-by-Reference: +Rust uses references (&T) and mutable references (&mut T) to allow functions to modify variables without making copies. + +Pointer Arithmetic: +Rust does not allow pointer arithmetic in safe code. This prevents mistakes like buffer overflows and out-of-bounds access. + + +Memory Management: +Rust uses a borrow checker and ownership system to prevent memory leaks. When a variable goes out of scope, Rust automatically deallocates memory (destruction) without needing explicit free() or delete() commands. + + +in summary Pointers in Rust are used to reference data in memory efficiently without copying. +Rust’s ownership and borrowing system ensures memory safety, and dynamic memory allocation is done using Box, Rc, Arc, and other structures. +Rust doesn’t allow pointer arithmetic in safe code to prevent common errors (e.g., buffer overflows), but you can use unsafe blocks if necessary, although they should be used with caution. + + + +difference between &str and string + +&str: This is a string slice, which is an immutable reference to a portion of a string. It does not own the data it references; instead, it borrows the data from another source, such as a String or a string literal. &str is lightweight and useful when you only need to view a part of a string without owning it. It is commonly used for function parameters when you do not need to modify the string. + +String: This is a growable, heap-allocated, UTF-8 encoded string. It owns its data and can be modified and resized at runtime. You can create a new String by calling String::new() or by converting from a string slice using to_string(). String is mutable and can be used in scenarios where you need to build or modify strings dyn \ No newline at end of file diff --git a/src/char.rs b/src/char.rs new file mode 100644 index 0000000..c4026f9 --- /dev/null +++ b/src/char.rs @@ -0,0 +1,14 @@ + +pub fn name(x: char, y: char) -> String { + let mut name = String::new(); + name.push(x); + name.push(y); + name +} + + pub fn myname(x: &str, y: &str) -> String { + let mut myname = String::new(); + myname.push_str(x); + myname.push_str(y); + myname +} \ No newline at end of file diff --git a/src/f64operation.rs b/src/f64operation.rs new file mode 100644 index 0000000..70ad7b4 --- /dev/null +++ b/src/f64operation.rs @@ -0,0 +1,17 @@ +// Floating-point Types + +pub fn add(x: f64, y: f64) -> f64 { + x + y +} + +pub fn minus(x: f64, y: f64) -> f64 { + x - y +} + +pub fn rise(x: f64, y: f64) -> f64 { + x * y +} + +pub fn split(x: f64, y: f64) -> f64 { + x / y +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 15a6a8d..504faae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,262 +1,108 @@ +mod u8operation; +mod f64operation; +mod char; +mod signed_integers; + fn main() { intro_to_u(); intro_to_f(); intro_to_char(); convert_high(); convert_high_to_low(); - perform_operations(); + crate::signed_integers::perform_operations(); } // function to encapsulate all integers and to check for even numbers fn intro_to_u() { - let sum_result: u8 = sum(5, 20); + let sum_result: u8 = u8operation::sum(5, 20); println!("the sum result is: {}", sum_result); println!( "Is the sum result even? {}", - if is_even(sum_result) { "Yes" } else { "No" } + if crate::u8operation::is_even(sum_result) { "Yes" } else { "No" } ); - let subtract_result: u8 = subtract(20, 15); + let subtract_result: u8 = u8operation::subtract(20, 15); println!("the subtract result is: {}", subtract_result); println!( "Is the subtract result even? {}", - if is_even(subtract_result) { "Yes" } else { "No" } + if crate::u8operation::is_even(subtract_result) { + "Yes" + } else { + "No" + } ); - let multiply_result: u8 = multiply(5, 12); + let multiply_result: u8 = u8operation:: multiply(5, 12); println!("the multiply result is {}", multiply_result); println!( "Is the multiply result even? {}", - if is_even(multiply_result) { "Yes" } else { "No" } + if crate::u8operation::is_even(multiply_result) { + "Yes" + } else { + "No" + } ); - - let divide_result: u8 = divide(20, 4); + let divide_result: u8 = u8operation::divide(20, 4); println!("the divide result is {}", divide_result); println!( "Is the divide result odd? {}", - if is_odd(divide_result) { "Yes" } else { "No" } + if crate::u8operation::is_odd(divide_result) { "Yes" } else { "No" } ); - +} + + -} // functions for Floating points fn intro_to_f() { - let add_result: f64 = add(10.3.into(), 10.1.into()); + let add_result: f64 = f64operation::add(10.3.into(), 10.1.into()); println!("the add result is: {}", add_result); - - let minus_result: f64 = minus(25.5.into(), 5.5.into()); + let minus_result: f64 = f64operation::minus(25.5.into(), 5.5.into()); println!("the subract2 result is: {}", minus_result); - let rise_result: f64 = rise(5.2.into(), 3.7.into()); + let rise_result: f64 = f64operation::rise(5.2.into(), 3.7.into()); println!("the multiply2 result is {}", rise_result); - let split_result: f64 = split(30.9.into(), 2.3.into()); + let split_result: f64 = f64operation::split(30.9.into(), 2.3.into()); println!("the divide result is {}", split_result); } // function char fn intro_to_char() { - let name_result: String = name('D', 'o'); + let name_result: String = char::name('D', 'o'); println!("The char result is: {}", name_result); - let myname_result: String = myname("Darey", "Olowo"); + let myname_result: String = char::myname("Darey", "Olowo"); println!("my name are : {}", myname_result); } -// function to encapsulate all integers - -fn sum(x: u8, y: u8) -> u8 { - x + y // implicit return - // return x + y; // explicit return -} - -// subtract - -fn subtract(x: u8, y: u8) -> u8 { - return x - y; -} - -// multiplication - -fn multiply(x: u8, y: u8) -> u8 { - x * y -} -// division - -fn divide(x: u8, y: u8) -> u8 { - x / y -} - -// Floating-point Types - -fn add(x: f64, y: f64) -> f64 { - x + y -} - -fn minus(x: f64, y: f64) -> f64 { - x - y -} - -fn rise(x: f64, y: f64) -> f64 { - x * y -} - -fn split(x: f64, y: f64) -> f64 { - x / y -} - -// char type - -fn name(x: char, y: char) -> String { - let mut name = String::new(); - name.push(x); - name.push(y); - name -} - -fn myname(x: &str, y: &str) -> String { - let mut myname = String::new(); - myname.push_str(x); - myname.push_str(y); - myname -} - -// - - - -// function to check for even numbers - -fn is_even(x: u8) -> bool { - x % 2 == 0 -} - - -// to check for odd nummbers - -fn is_odd(x: u8) -> bool { - x % 2 != 0 -} - // how to convert u8 to u32 - fn convert_high(){ +fn convert_high() { let low: u8 = 255; let high: u32 = low as u32; - println!("u8 value: {}, u32 value:{}", low, high ); - } - - - + println!("u8 value: {}, u32 value:{}", low, high); +} //Function to convert high bit integer to low bit integer u32 to u8 fn convert_high_to_low() { - let high: u32 = 300; - let low: u8 = high as u8; // Convert u32 to u8 with truncation + let high: u32 = 300; + let low: u8 = high as u8; println!("u32 value: {}, u8 value: {}", high, low); } -//Implement arithmetic operations on signed integers - -fn perform_operations() { - let a: i32 = 25; // A signed 32-bit integer - let b: i32 = -10; // Another signed 32-bit integer - - // Arithmetic operations - let sum = a + b; // Addition - let difference = a - b; // Subtraction - let product = a * b; // Multiplication - let quotient = a / b; // Division - let remainder = a % b; // Modulus (remainder) - - println!("Arithmetic Operations on signed integers:"); - println!("a = {}, b = {}", a, b); - println!("Sum: {}", sum); - println!("Difference: {}", difference); - println!("Product: {}", product); - println!("Quotient: {}", quotient); - println!("Remainder: {}", remainder); -} - - - -//Explain the difference between the fp32 and fp64 data types - - //The key difference between fp32 (32-bit floating-point) and fp64 (64-bit floating-point) lies in their precision and range: - - //1. Bit Size: - // fp32 (32-bit): Uses 32 bits to represent a floating-point number. - // fp64 (64-bit): Uses 64 bits, allowing for more precision and a larger range. - - // 2. Precision: - // fp32: Provides approximately 7 decimal digits of precision. - // fp64: Provides approximately 15-16 decimal digits of precision. - // Example: Calculations with very small differences or many decimal places will be more accurate with fp64. - - // 3. Range: - //fp32: Can represent numbers from approximately 1.4 x 10^-45 to 3.4 x 10^38. - //fp64: Can represent numbers from approximately 5.0 x 10^-324 to 1.8 x 10^308. - //fp64: Covers a wide range than fp32, making it suitable for scientific calculations or financial applications. - - //4. Memory Usage: - // 32: Uses less memory, making it faster for applications where precision isn't critical (e.g., graphics or simulations). - // 64: Requires double the memory of fp32, which may impact performance or storage in large datasets. - - //5. Performance: - // 32: Faster due to smaller size, often used in real-time systems like games or machine learning models. - // 64: Slower but more precise, used in scientific computing, financial applications, or any domain requiring high precision. - - //6. When to Use: - // 32: Use when speed and memory efficiency are more important than precision (e.g., 3D graphics, neural networks). - // 64: Use when precision and range are crucial (e.g., scientific simulations, high-precision calculations). - -//Describe in details the role of pointers in memory management - - //Pointers play a critical role in memory management in programming, particularly in low-level languages like C, C++, and systems programming languages such as Rust (though Rust manages pointers more safely). Here’s a detailed explanation of their roles: - - //1. Memory Address: - // Pointers store the memory address of a variable or data structure in the computer's memory. This address points to the location where the data is stored, allowing programs to access and manipulate it directly. - - //2. Dynamic Memory Allocation: - // Pointers enable dynamic memory allocation, where programs can request memory from the heap at runtime and manage it using pointers. This allows for flexible memory usage and efficient storage of data structures like arrays, linked lists, and trees. - - //3. Efficient Data Access: - // By using pointers, programs can directly access and modify data in memory without copying it, leading to faster and more efficient data processing. Pointers are crucial for tasks like iterating over arrays, traversing linked lists, or accessing hardware registers. - - //4. Pass-by-Reference: - // Pointers enable pass-by-reference in function calls, where functions can modify variables in the calling scope by passing pointers to them. This allows for efficient sharing and manipulation of data across different parts of a program. - - //5. Pointer Arithmetic: - // Pointers support arithmetic operations like addition, subtraction, and comparison, allowing for efficient memory traversal and manipulation. This is essential for tasks like iterating over arrays, implementing data structures, or working with complex data layouts. - - //6. Memory Management: - // Pointers play a key role in memory management, allowing programs to allocate, deallocate, and reallocate memory dynamically. This helps optimize memory usage, prevent memory leaks, and manage resources efficiently in applications. - - //7. Low-Level Programming: - // In low-level programming, pointers are essential for interacting with hardware, managing memory layouts, and implementing efficient algorithms. They provide direct access to memory locations, enabling fine-grained control over data and system resources. - - //8. Pointer Safety: - // While pointers offer powerful capabilities, they can also introduce risks like null pointer dereferencing, memory leaks, and buffer overflows. Modern languages like Rust incorporate safety features to prevent common pointer-related errors and ensure memory safety. - - //In summary, pointers are fundamental to memory management in programming, enabling efficient data access, dynamic memory allocation, pass-by-reference semantics, and low-level system interactions. Understanding and using pointers effectively is crucial for developing performant, memory-efficient, and reliable software applications. - - - - - diff --git a/src/signed_integers.rs b/src/signed_integers.rs new file mode 100644 index 0000000..f164815 --- /dev/null +++ b/src/signed_integers.rs @@ -0,0 +1,22 @@ + +//Implement arithmetic operations on signed integers + +pub fn perform_operations() { + let a: i32 = 25; // A signed 32-bit integer + let b: i32 = -10; // Another signed 32-bit integer + + // Arithmetic operations + let sum = a + b; + let difference = a - b; + let product = a * b; + let quotient = a / b; + let remainder = a % b; // Modulus (remainder) + + println!("Arithmetic Operations on signed integers:"); + println!("a = {}, b = {}", a, b); + println!("Sum: {}", sum); + println!("Difference: {}", difference); + println!("Product: {}", product); + println!("Quotient: {}", quotient); + println!("Remainder: {}", remainder); +} \ No newline at end of file diff --git a/src/u8operation.rs b/src/u8operation.rs new file mode 100644 index 0000000..3cfbd5b --- /dev/null +++ b/src/u8operation.rs @@ -0,0 +1,36 @@ +pub fn sum(x: u8, y: u8) -> u8 { + x + y // implicit return + // return x + y; // explicit return +} + + + +// subtract + +pub fn subtract(x: u8, y: u8) -> u8 { + return x - y; +} + +// multiplication + + pub fn multiply(x: u8, y: u8) -> u8 { + x * y +} +// division + + pub fn divide(x: u8, y: u8) -> u8 { + x / y +} + +// function to check for even numbers + +pub fn is_even(x: u8) -> bool { + x % 2 == 0 +} + +// to check for odd nummbers + +pub fn is_odd(x: u8) -> bool { + x % 2 != 0 +} + From d291157bf3b17848053a07df643b26621e4c2374 Mon Sep 17 00:00:00 2001 From: olowo Date: Tue, 28 Jan 2025 14:20:58 +0100 Subject: [PATCH 4/5] fixed char --- src/char.rs | 8 ++++++++ src/main.rs | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/char.rs b/src/char.rs index c4026f9..ea1fcb7 100644 --- a/src/char.rs +++ b/src/char.rs @@ -11,4 +11,12 @@ pub fn name(x: char, y: char) -> String { myname.push_str(x); myname.push_str(y); myname +} + +pub fn intro_to_char() { + let name_result: String = name('D', 'o'); + println!("The char result is: {}", name_result); + + let myname_result: String = myname("Darey", "Olowo"); + println!("my name are : {}", myname_result); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 504faae..36e96ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod signed_integers; fn main() { intro_to_u(); intro_to_f(); - intro_to_char(); + crate::char::intro_to_char(); convert_high(); convert_high_to_low(); crate::signed_integers::perform_operations(); @@ -72,15 +72,7 @@ fn intro_to_f() { println!("the divide result is {}", split_result); } -// function char -fn intro_to_char() { - let name_result: String = char::name('D', 'o'); - println!("The char result is: {}", name_result); - - let myname_result: String = char::myname("Darey", "Olowo"); - println!("my name are : {}", myname_result); -} From 92cbfa4b25599f6131209a0528cf78cdfaccb55b Mon Sep 17 00:00:00 2001 From: olowo Date: Fri, 31 Jan 2025 12:19:26 +0100 Subject: [PATCH 5/5] feat: add calculator --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++- src/calculator.rs | 53 +++++++++++++++++++++++++++++++ src/f64operation.rs | 5 +-- src/main.rs | 36 +++++++++++++++++---- 4 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 src/calculator.rs diff --git a/README.md b/README.md index e8a44ab..b5dbe51 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,78 @@ difference between &str and string &str: This is a string slice, which is an immutable reference to a portion of a string. It does not own the data it references; instead, it borrows the data from another source, such as a String or a string literal. &str is lightweight and useful when you only need to view a part of a string without owning it. It is commonly used for function parameters when you do not need to modify the string. -String: This is a growable, heap-allocated, UTF-8 encoded string. It owns its data and can be modified and resized at runtime. You can create a new String by calling String::new() or by converting from a string slice using to_string(). String is mutable and can be used in scenarios where you need to build or modify strings dyn \ No newline at end of file +String: This is a growable, heap-allocated, UTF-8 encoded string. It owns its data and can be modified and resized at runtime. You can create a new String by calling String::new() or by converting from a string slice using to_string(). String is mutable and can be used in scenarios where you need to build or modify strings dyn + + + + + + + + +A CPU, or Central Processing Unit, is the primary component in a computer that executes instructions and processes data from computer programs. It acts as the “brain” of the computer, handling tasks such as arithmetic, logic, and input/output operations. The CPU coordinates other components in the system and is essential for the computer’s overall functionality. + +RAM (Random Access Memory) + +Temporary, fast memory that stores: + +Currently running programs,Active data being processed,Operating system components + + +Characteristics: + +Volatile (loses data when power is off) +Much faster than storage drives +Directly accessible by CPU +Measured in GB (8GB, 16GB, etc.) + + + +ROM (Read-Only Memory) + +Permanent memory that contains: + +BIOS/UEFI (Basic Input/Output System) +Firmware +Boot instructions + + +Characteristics: + +Non-volatile (keeps data when power is off) +Can't be easily modified +Slower than RAM +Usually small capacity + + + +How They Work Together: + +ROM stores startup instructions +When computer starts, CPU reads ROM instructions +Operating system loads into RAM +CPU processes instructions, using RAM as working memory +Data flows between components via system bus + + +A stack is a part of memory that has a specific data structure. + +When there is a new piece of data that should be stored, the stack will always put it “on top”. (push to the stack) +When a piece of data should be removed from the stack, it is also taken “from the top”. (pop off the stack) +using the last in, first out (LIFO) data structure. +All entries that are pushed to the stack are required to have a known, fixed size. The size should be known at compile time, and can not change during runtime. We can not put things of variable size in the stack (like a string that might grow in size). + + + heap + +Heap memory in Rust is a part of the memory system used for dynamic memory allocation. Unlike stack memory, which is managed automatically by the compiler and has a fixed layout, heap memory is managed manually and is not bound to function scopes. This means that variables allocated on the heap can live longer than the function that created them, allowing for more flexible memory managem + + +A pointer is a general concept for a variable that contains an address in memory. This address refers to, or “points at,” some other data. + + +anything not implemented by a vetor dont have capacity + + + + diff --git a/src/calculator.rs b/src/calculator.rs new file mode 100644 index 0000000..c767e23 --- /dev/null +++ b/src/calculator.rs @@ -0,0 +1,53 @@ +struct Calculator { + value: f64, +} + +impl Calculator { + fn new() -> Calculator { + Calculator { + value: 5.0 + } + } + + fn add(&mut self, number: f64) -> f64 { + self.value += number; + self.value + } + + fn subtract(&mut self, number: f64) -> f64 { + self.value -= number; + self.value + } + + fn multiply(&mut self, number: f64) -> f64 { + self.value *= number; + self.value + } + + + fn divide(&mut self, number: f64) -> Result { + if number == 0.0 { + return Err(String::from("Cannot divide by zero!")); + } + self.value /= number; + Ok(self.value) + } + +} + + + +pub fn cal() { + let mut calc = Calculator::new(); + + println!("Adding 5: {}", calc.add(10.0)); + println!("Multiplying by 2: {}", calc.multiply(2.0)); + println!("Subtracting 3: {}", calc.subtract(3.0)); + + + match calc.divide(2.0) { + Ok(result) => println!("Dividing by 2: {}", result), + Err(error) => println!("Error: {}", error), + } +} + diff --git a/src/f64operation.rs b/src/f64operation.rs index 70ad7b4..3ea6d8f 100644 --- a/src/f64operation.rs +++ b/src/f64operation.rs @@ -2,7 +2,7 @@ pub fn add(x: f64, y: f64) -> f64 { x + y -} +} pub fn minus(x: f64, y: f64) -> f64 { x - y @@ -14,4 +14,5 @@ pub fn rise(x: f64, y: f64) -> f64 { pub fn split(x: f64, y: f64) -> f64 { x / y -} \ No newline at end of file +} + diff --git a/src/main.rs b/src/main.rs index 36e96ae..0779738 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,16 +2,40 @@ mod u8operation; mod f64operation; mod char; mod signed_integers; +mod calculator; fn main() { - intro_to_u(); - intro_to_f(); - crate::char::intro_to_char(); - convert_high(); - convert_high_to_low(); - crate::signed_integers::perform_operations(); + // intro_to_u(); + // intro_to_f(); + // crate::char::intro_to_char(); + // convert_high(); + // convert_high_to_low(); + // crate::signed_integers::perform_operations(); + crate::calculator::cal(); + } + + + + + + + + + + + + + + + + + + + + + // function to encapsulate all integers and to check for even numbers fn intro_to_u() { let sum_result: u8 = u8operation::sum(5, 20);