Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 98400e1

Browse files
Add is power of two (TheAlgorithms#970)
1 parent ebc3767 commit 98400e1

File tree

3 files changed

+243
-0
lines changed

3 files changed

+243
-0
lines changed

‎DIRECTORY.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* [Binary Coded Decimal](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/binary_coded_decimal.rs)
2121
* [Counting Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/counting_bits.rs)
2222
* [Highest Set Bit](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/highest_set_bit.rs)
23+
* [Is Power of Two](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/is_power_of_two.rs)
2324
* [N Bits Gray Code](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/n_bits_gray_code.rs)
2425
* [Previous Power of Two](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/find_previous_power_of_two.rs)
2526
* [Reverse Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/reverse_bits.rs)
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
//! Power of Two Check
2+
//!
3+
//! This module provides a function to determine if a given positive integer is a power of two
4+
//! using efficient bit manipulation.
5+
//!
6+
//! # Algorithm
7+
//!
8+
//! The algorithm uses the property that powers of two have exactly one bit set in their
9+
//! binary representation. When we subtract 1 from a power of two, all bits after the single
10+
//! set bit become 1, and the set bit becomes 0:
11+
//!
12+
//! ```text
13+
//! n = 0..100..00 (power of 2)
14+
//! n - 1 = 0..011..11
15+
//! n & (n - 1) = 0 (no intersections)
16+
//! ```
17+
//!
18+
//! For example:
19+
//! - 8 in binary: 1000
20+
//! - 7 in binary: 0111
21+
//! - 8 & 7 = 0000 = 0 ✓
22+
//!
23+
//! Author: Alexander Pantyukhin
24+
//! Date: November 1, 2022
25+
26+
/// Determines if a given number is a power of two.
27+
///
28+
/// This function uses bit manipulation to efficiently check if a number is a power of two.
29+
/// A number is a power of two if it has exactly one bit set in its binary representation.
30+
/// The check `number & (number - 1) == 0` leverages this property.
31+
///
32+
/// # Arguments
33+
///
34+
/// * `number` - An integer to check (must be non-negative)
35+
///
36+
/// # Returns
37+
///
38+
/// A `Result` containing:
39+
/// - `Ok(true)` - If the number is a power of two (including 0 and 1)
40+
/// - `Ok(false)` - If the number is not a power of two
41+
/// - `Err(String)` - If the number is negative
42+
///
43+
/// # Examples
44+
///
45+
/// ```
46+
/// use the_algorithms_rust::bit_manipulation::is_power_of_two;
47+
///
48+
/// assert_eq!(is_power_of_two(0).unwrap(), true);
49+
/// assert_eq!(is_power_of_two(1).unwrap(), true);
50+
/// assert_eq!(is_power_of_two(2).unwrap(), true);
51+
/// assert_eq!(is_power_of_two(4).unwrap(), true);
52+
/// assert_eq!(is_power_of_two(8).unwrap(), true);
53+
/// assert_eq!(is_power_of_two(16).unwrap(), true);
54+
///
55+
/// assert_eq!(is_power_of_two(3).unwrap(), false);
56+
/// assert_eq!(is_power_of_two(6).unwrap(), false);
57+
/// assert_eq!(is_power_of_two(17).unwrap(), false);
58+
///
59+
/// // Negative numbers return an error
60+
/// assert!(is_power_of_two(-1).is_err());
61+
/// ```
62+
///
63+
/// # Errors
64+
///
65+
/// Returns an error if the input number is negative.
66+
///
67+
/// # Time Complexity
68+
///
69+
/// O(1) - The function performs a constant number of operations regardless of input size.
70+
pub fn is_power_of_two(number: i32) -> Result<bool, String> {
71+
if number < 0 {
72+
return Err("number must not be negative".to_string());
73+
}
74+
75+
// Convert to u32 for safe bit operations
76+
let num = number as u32;
77+
78+
// Check if number & (number - 1) == 0
79+
// For powers of 2, this will always be true
80+
Ok(num & num.wrapping_sub(1) == 0)
81+
}
82+
83+
#[cfg(test)]
84+
mod tests {
85+
use super::*;
86+
87+
#[test]
88+
fn test_zero() {
89+
// 0 is considered a power of 2 by the algorithm (2^(-∞) interpretation)
90+
assert!(is_power_of_two(0).unwrap());
91+
}
92+
93+
#[test]
94+
fn test_one() {
95+
// 1 = 2^0
96+
assert!(is_power_of_two(1).unwrap());
97+
}
98+
99+
#[test]
100+
fn test_powers_of_two() {
101+
assert!(is_power_of_two(2).unwrap()); // 2^1
102+
assert!(is_power_of_two(4).unwrap()); // 2^2
103+
assert!(is_power_of_two(8).unwrap()); // 2^3
104+
assert!(is_power_of_two(16).unwrap()); // 2^4
105+
assert!(is_power_of_two(32).unwrap()); // 2^5
106+
assert!(is_power_of_two(64).unwrap()); // 2^6
107+
assert!(is_power_of_two(128).unwrap()); // 2^7
108+
assert!(is_power_of_two(256).unwrap()); // 2^8
109+
assert!(is_power_of_two(512).unwrap()); // 2^9
110+
assert!(is_power_of_two(1024).unwrap()); // 2^10
111+
assert!(is_power_of_two(2048).unwrap()); // 2^11
112+
assert!(is_power_of_two(4096).unwrap()); // 2^12
113+
assert!(is_power_of_two(8192).unwrap()); // 2^13
114+
assert!(is_power_of_two(16384).unwrap()); // 2^14
115+
assert!(is_power_of_two(32768).unwrap()); // 2^15
116+
assert!(is_power_of_two(65536).unwrap()); // 2^16
117+
}
118+
119+
#[test]
120+
fn test_non_powers_of_two() {
121+
assert!(!is_power_of_two(3).unwrap());
122+
assert!(!is_power_of_two(5).unwrap());
123+
assert!(!is_power_of_two(6).unwrap());
124+
assert!(!is_power_of_two(7).unwrap());
125+
assert!(!is_power_of_two(9).unwrap());
126+
assert!(!is_power_of_two(10).unwrap());
127+
assert!(!is_power_of_two(11).unwrap());
128+
assert!(!is_power_of_two(12).unwrap());
129+
assert!(!is_power_of_two(13).unwrap());
130+
assert!(!is_power_of_two(14).unwrap());
131+
assert!(!is_power_of_two(15).unwrap());
132+
assert!(!is_power_of_two(17).unwrap());
133+
assert!(!is_power_of_two(18).unwrap());
134+
}
135+
136+
#[test]
137+
fn test_specific_non_powers() {
138+
assert!(!is_power_of_two(6).unwrap());
139+
assert!(!is_power_of_two(17).unwrap());
140+
assert!(!is_power_of_two(100).unwrap());
141+
assert!(!is_power_of_two(1000).unwrap());
142+
}
143+
144+
#[test]
145+
fn test_large_powers_of_two() {
146+
assert!(is_power_of_two(131072).unwrap()); // 2^17
147+
assert!(is_power_of_two(262144).unwrap()); // 2^18
148+
assert!(is_power_of_two(524288).unwrap()); // 2^19
149+
assert!(is_power_of_two(1048576).unwrap()); // 2^20
150+
}
151+
152+
#[test]
153+
fn test_numbers_near_powers_of_two() {
154+
// One less than powers of 2
155+
assert!(!is_power_of_two(3).unwrap()); // 2^2 - 1
156+
assert!(!is_power_of_two(7).unwrap()); // 2^3 - 1
157+
assert!(!is_power_of_two(15).unwrap()); // 2^4 - 1
158+
assert!(!is_power_of_two(31).unwrap()); // 2^5 - 1
159+
assert!(!is_power_of_two(63).unwrap()); // 2^6 - 1
160+
assert!(!is_power_of_two(127).unwrap()); // 2^7 - 1
161+
assert!(!is_power_of_two(255).unwrap()); // 2^8 - 1
162+
163+
// One more than powers of 2
164+
assert!(!is_power_of_two(3).unwrap()); // 2^1 + 1
165+
assert!(!is_power_of_two(5).unwrap()); // 2^2 + 1
166+
assert!(!is_power_of_two(9).unwrap()); // 2^3 + 1
167+
assert!(!is_power_of_two(17).unwrap()); // 2^4 + 1
168+
assert!(!is_power_of_two(33).unwrap()); // 2^5 + 1
169+
assert!(!is_power_of_two(65).unwrap()); // 2^6 + 1
170+
assert!(!is_power_of_two(129).unwrap()); // 2^7 + 1
171+
}
172+
173+
#[test]
174+
fn test_negative_number_returns_error() {
175+
let result = is_power_of_two(-1);
176+
assert!(result.is_err());
177+
assert_eq!(result.unwrap_err(), "number must not be negative");
178+
}
179+
180+
#[test]
181+
fn test_multiple_negative_numbers() {
182+
assert!(is_power_of_two(-1).is_err());
183+
assert!(is_power_of_two(-2).is_err());
184+
assert!(is_power_of_two(-4).is_err());
185+
assert!(is_power_of_two(-8).is_err());
186+
assert!(is_power_of_two(-100).is_err());
187+
}
188+
189+
#[test]
190+
fn test_all_powers_of_two_up_to_30() {
191+
// Test 2^0 through 2^30
192+
for i in 0..=30 {
193+
let power = 1u32 << i; // 2^i
194+
assert!(
195+
is_power_of_two(power as i32).unwrap(),
196+
"2^{i} = {power} should be a power of 2"
197+
);
198+
}
199+
}
200+
201+
#[test]
202+
fn test_range_verification() {
203+
// Test that between consecutive powers of 2, only the powers return true
204+
for i in 1..10 {
205+
let power = 1 << i; // 2^i
206+
assert!(is_power_of_two(power).unwrap());
207+
208+
// Check numbers between this power and the next
209+
let next_power = 1 << (i + 1);
210+
for num in (power + 1)..next_power {
211+
assert!(
212+
!is_power_of_two(num).unwrap(),
213+
"{num} should not be a power of 2"
214+
);
215+
}
216+
}
217+
}
218+
219+
#[test]
220+
fn test_bit_manipulation_correctness() {
221+
// Verify the bit manipulation logic for specific examples
222+
// For 8: 1000 & 0111 = 0000 ✓
223+
assert_eq!(8 & 7, 0);
224+
assert!(is_power_of_two(8).unwrap());
225+
226+
// For 16: 10000 & 01111 = 00000 ✓
227+
assert_eq!(16 & 15, 0);
228+
assert!(is_power_of_two(16).unwrap());
229+
230+
// For 6: 110 & 101 = 100 ✗
231+
assert_ne!(6 & 5, 0);
232+
assert!(!is_power_of_two(6).unwrap());
233+
}
234+
235+
#[test]
236+
fn test_edge_case_max_i32_power_of_two() {
237+
// Largest power of 2 that fits in i32: 2^30 = 1073741824
238+
assert!(is_power_of_two(1073741824).unwrap());
239+
}
240+
}

‎src/bit_manipulation/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod binary_coded_decimal;
22
mod counting_bits;
33
mod find_previous_power_of_two;
44
mod highest_set_bit;
5+
mod is_power_of_two;
56
mod n_bits_gray_code;
67
mod reverse_bits;
78
mod sum_of_two_integers;
@@ -12,6 +13,7 @@ pub use self::binary_coded_decimal::binary_coded_decimal;
1213
pub use self::counting_bits::count_set_bits;
1314
pub use self::find_previous_power_of_two::find_previous_power_of_two;
1415
pub use self::highest_set_bit::find_highest_set_bit;
16+
pub use self::is_power_of_two::is_power_of_two;
1517
pub use self::n_bits_gray_code::generate_gray_code;
1618
pub use self::reverse_bits::reverse_bits;
1719
pub use self::sum_of_two_integers::add_two_integers;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /