Bitwise Operators in Rust
Bitwise operators in Rust allow manipulation of individual bits in binary representations of data. They are useful for low-level operations like setting or clearing specific bits, creating bitmasks, and optimizing algorithms. Rust provides bitwise AND, OR, XOR, left shift, and right shift operators for efficient bit-level manipulation.
Webdock – Fast Cloud VPS Linux Hosting
Lets’s see some example code and output:
fn main() {
let value = 0; // You set the value to either 0 or 1.
// Calculate the exit status using the provided formula:
let exit_status = (value << 1) | 1;
// Now, we'll print the value and the resulting exit status.
println!("Value: {}", value);
println!("Exit Status: {}", exit_status);
// Finally, we'll simulate an exit with the calculated exit status.
std::process::exit(exit_status);
}
Standard Output
Value: 0
Exit Status: 1
fn main() {
let value = 1; // You set the value to either 0 or 1.
// Calculate the exit status using the provided formula:
let exit_status = (value << 1) | 1;
// Now, we'll print the value and the resulting exit status.
println!("Value: {}", value);
println!("Exit Status: {}", exit_status);
// Finally, we'll simulate an exit with the calculated exit status.
std::process::exit(exit_status);
}
Standard Output
Value: 1
Exit Status: 3
The Rust code above defines a main
function that simulates an exit status calculation and then exits the program using that exit status. Here’s the breakdown:
let value = 0;
sets thevalue
to either 0 or 1. You can change this value to 1 if you want to see how it affects the exit status.let exit_status = (value << 1) | 1;
calculates the exit status using a formula:
(value << 1)
shifts the bits ofvalue
one position to the left, which is equivalent to multiplying it by 2.1
is a binary representation for the number 1.|
performs a bitwise OR operation between the left-shifted value and 1, which combines the two binary values.
println!("Value: {}", value);
prints the original value (0 or 1) to the console.println!("Exit Status: {}", exit_status);
prints the calculated exit status to the console.std::process::exit(exit_status);
simulates an exit from the program with the calculated exit status. The program will terminate, and the exit status will be returned to the calling process, typically indicating the success or failure of the program. Ifvalue
is 0, the exit status will be 1, and ifvalue
is 1, the exit status will be 3 (due to the left shift).
Use case for bitwise operators in Rust
Suppose we already had another process using 0 for a success exit code, instead we’ve used 33
Why / how does this work?
TL,DR;
In hexadecimal notation, 0x20
represents 32 in decimal, and 1
is 1 in decimal. When you perform a bitwise OR operation (|
) between 0x20
and 1
, you get 0x21
, which is 33 in decimal.
Full explanation:
Let’s break down the binary calculation for 0x20 | 1
, which results in 0x21
(or 33 in decimal):
0x20
in binary is00100000
.1
in binary is00000001
.
Now, let’s perform the bitwise OR operation between these two binary values:
00100000
| 00000001
-----------
00100001
The result of the bitwise OR operation is 00100001
, which is 0x21
in hexadecimal and 33 in decimal.
fn main() {
let val = 5;
println!("{:}",is_even(val));
}
fn is_even(val: u32) -> bool {
val & 1 == 0
}
Another example, this function will work on any value of any size, because it only ever looks at the least significant bit, so it’s another way of doing modulo 2 == 0.
5 -> 0 1 0 1
1 -> 0 0 0 1
& _________
1 -> 0 0 0 1 even == False
___
6 -> 0 1 1 0
1 -> 0 0 0 1
& _________
0 -> 0 0 0 0 even == True
The function effectively checks whether the input number val
is even by examining the LSB using bitwise operations and returns true
if it’s even and false
if it’s odd.
Conclusion
Bitwise operations in Rust are invaluable for optimizing code and saving memory by allowing direct bit manipulation without the need for temporary variables. They are efficient for tasks like creating compact data structures, flag management, and extracting or modifying specific bits. This reduces memory overhead and improves performance in low-level programming scenarios.