Check whether an integer's leftmost bits are ones in Rust
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
I'm trying to validate if an integer represents a valid IPv6 mask, which boils down to checking if all the left-most bits of an u128 are 1s, and all the right-most bits are 0s. For instance:
0
is valid0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is valid0xffff_ffff_ffff_ffff_0000_0000_0000_0000
is valid0xffff_ffff_fff8_0000_0000_0000_0000_0000
is valid0xffff_ffff_fffe_0000_0000_0000_0000_0000
is valid
but:
1
is invalid (its representation is0x0000_0000_0000_0000_0000_0000_0000_0001
)0x0fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is invalid0xffff_ffff_fff1_0000_0000_0000_0000_0000
is invalid
Here is the function:
/// Check whether the given integer represents a valid IPv6 mask.
/// A valid IP mask is an integer which left-most bits are 1s, and right-most bits are 0s.
fn is_valid_ipv6_mask(value: u128) -> bool
// flag to check if we're currently processing 1s or 0s
let mut count_ones = true;
// check each byte starting from the left.
for byte_index in (0..=15).rev()
let x = (value >> (byte_index * 8)) & 0xff;
match x
// We're processing 1s and this byte is 0b1111_1111
0xff if count_ones => continue,
// We're processing 0s and this byte is 0b0000_0000
0x00 if !count_ones => continue,
// We're processing 1s and this byte is 0b0000_0000.
// That means all the remaining bytes should be 0 for this integer
// to be a valid mask
0x00 if count_ones =>
count_ones = false;
continue;
// We're processsing 1s and this byte has at least a 1, so we have
// to check bit by bit that the left-most bits are 1s and the
// right-most bits are 0s
byte if byte > 0 && count_ones =>
let mut bit_index = 7;
while (byte >> bit_index) & 1 == 1
// This does not overflow, because we now this byte has at
// least a 0 somewhere
bit_index -= 1
// At this point, all the bits should be 0s
count_ones = false;
for i in 0..bit_index
if (byte >> i) & 1 == 1
return false;
// Any other case is an error
_ => return false,
true
And to test it:
fn main()
assert!(is_valid_ipv6_mask(0));
assert!(is_valid_ipv6_mask(
0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
));
assert!(is_valid_ipv6_mask(
0xffff_0000_0000_0000_0000_0000_0000_0000
));
assert!(is_valid_ipv6_mask(
0xff80_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xff01_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xffff_0000_ffff_ffff_ffff_ffff_ffff_ffff
));
Link to playground.
The problem is that have the feeling that there must be a much simple solution to this problem. After all, bit operations are what computers do, I can't believe there's not more concise and more efficient way to check if an integer is all 1s then all 0s.
integer rust
add a comment |Â
up vote
2
down vote
favorite
I'm trying to validate if an integer represents a valid IPv6 mask, which boils down to checking if all the left-most bits of an u128 are 1s, and all the right-most bits are 0s. For instance:
0
is valid0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is valid0xffff_ffff_ffff_ffff_0000_0000_0000_0000
is valid0xffff_ffff_fff8_0000_0000_0000_0000_0000
is valid0xffff_ffff_fffe_0000_0000_0000_0000_0000
is valid
but:
1
is invalid (its representation is0x0000_0000_0000_0000_0000_0000_0000_0001
)0x0fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is invalid0xffff_ffff_fff1_0000_0000_0000_0000_0000
is invalid
Here is the function:
/// Check whether the given integer represents a valid IPv6 mask.
/// A valid IP mask is an integer which left-most bits are 1s, and right-most bits are 0s.
fn is_valid_ipv6_mask(value: u128) -> bool
// flag to check if we're currently processing 1s or 0s
let mut count_ones = true;
// check each byte starting from the left.
for byte_index in (0..=15).rev()
let x = (value >> (byte_index * 8)) & 0xff;
match x
// We're processing 1s and this byte is 0b1111_1111
0xff if count_ones => continue,
// We're processing 0s and this byte is 0b0000_0000
0x00 if !count_ones => continue,
// We're processing 1s and this byte is 0b0000_0000.
// That means all the remaining bytes should be 0 for this integer
// to be a valid mask
0x00 if count_ones =>
count_ones = false;
continue;
// We're processsing 1s and this byte has at least a 1, so we have
// to check bit by bit that the left-most bits are 1s and the
// right-most bits are 0s
byte if byte > 0 && count_ones =>
let mut bit_index = 7;
while (byte >> bit_index) & 1 == 1
// This does not overflow, because we now this byte has at
// least a 0 somewhere
bit_index -= 1
// At this point, all the bits should be 0s
count_ones = false;
for i in 0..bit_index
if (byte >> i) & 1 == 1
return false;
// Any other case is an error
_ => return false,
true
And to test it:
fn main()
assert!(is_valid_ipv6_mask(0));
assert!(is_valid_ipv6_mask(
0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
));
assert!(is_valid_ipv6_mask(
0xffff_0000_0000_0000_0000_0000_0000_0000
));
assert!(is_valid_ipv6_mask(
0xff80_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xff01_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xffff_0000_ffff_ffff_ffff_ffff_ffff_ffff
));
Link to playground.
The problem is that have the feeling that there must be a much simple solution to this problem. After all, bit operations are what computers do, I can't believe there's not more concise and more efficient way to check if an integer is all 1s then all 0s.
integer rust
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm trying to validate if an integer represents a valid IPv6 mask, which boils down to checking if all the left-most bits of an u128 are 1s, and all the right-most bits are 0s. For instance:
0
is valid0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is valid0xffff_ffff_ffff_ffff_0000_0000_0000_0000
is valid0xffff_ffff_fff8_0000_0000_0000_0000_0000
is valid0xffff_ffff_fffe_0000_0000_0000_0000_0000
is valid
but:
1
is invalid (its representation is0x0000_0000_0000_0000_0000_0000_0000_0001
)0x0fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is invalid0xffff_ffff_fff1_0000_0000_0000_0000_0000
is invalid
Here is the function:
/// Check whether the given integer represents a valid IPv6 mask.
/// A valid IP mask is an integer which left-most bits are 1s, and right-most bits are 0s.
fn is_valid_ipv6_mask(value: u128) -> bool
// flag to check if we're currently processing 1s or 0s
let mut count_ones = true;
// check each byte starting from the left.
for byte_index in (0..=15).rev()
let x = (value >> (byte_index * 8)) & 0xff;
match x
// We're processing 1s and this byte is 0b1111_1111
0xff if count_ones => continue,
// We're processing 0s and this byte is 0b0000_0000
0x00 if !count_ones => continue,
// We're processing 1s and this byte is 0b0000_0000.
// That means all the remaining bytes should be 0 for this integer
// to be a valid mask
0x00 if count_ones =>
count_ones = false;
continue;
// We're processsing 1s and this byte has at least a 1, so we have
// to check bit by bit that the left-most bits are 1s and the
// right-most bits are 0s
byte if byte > 0 && count_ones =>
let mut bit_index = 7;
while (byte >> bit_index) & 1 == 1
// This does not overflow, because we now this byte has at
// least a 0 somewhere
bit_index -= 1
// At this point, all the bits should be 0s
count_ones = false;
for i in 0..bit_index
if (byte >> i) & 1 == 1
return false;
// Any other case is an error
_ => return false,
true
And to test it:
fn main()
assert!(is_valid_ipv6_mask(0));
assert!(is_valid_ipv6_mask(
0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
));
assert!(is_valid_ipv6_mask(
0xffff_0000_0000_0000_0000_0000_0000_0000
));
assert!(is_valid_ipv6_mask(
0xff80_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xff01_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xffff_0000_ffff_ffff_ffff_ffff_ffff_ffff
));
Link to playground.
The problem is that have the feeling that there must be a much simple solution to this problem. After all, bit operations are what computers do, I can't believe there's not more concise and more efficient way to check if an integer is all 1s then all 0s.
integer rust
I'm trying to validate if an integer represents a valid IPv6 mask, which boils down to checking if all the left-most bits of an u128 are 1s, and all the right-most bits are 0s. For instance:
0
is valid0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is valid0xffff_ffff_ffff_ffff_0000_0000_0000_0000
is valid0xffff_ffff_fff8_0000_0000_0000_0000_0000
is valid0xffff_ffff_fffe_0000_0000_0000_0000_0000
is valid
but:
1
is invalid (its representation is0x0000_0000_0000_0000_0000_0000_0000_0001
)0x0fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
is invalid0xffff_ffff_fff1_0000_0000_0000_0000_0000
is invalid
Here is the function:
/// Check whether the given integer represents a valid IPv6 mask.
/// A valid IP mask is an integer which left-most bits are 1s, and right-most bits are 0s.
fn is_valid_ipv6_mask(value: u128) -> bool
// flag to check if we're currently processing 1s or 0s
let mut count_ones = true;
// check each byte starting from the left.
for byte_index in (0..=15).rev()
let x = (value >> (byte_index * 8)) & 0xff;
match x
// We're processing 1s and this byte is 0b1111_1111
0xff if count_ones => continue,
// We're processing 0s and this byte is 0b0000_0000
0x00 if !count_ones => continue,
// We're processing 1s and this byte is 0b0000_0000.
// That means all the remaining bytes should be 0 for this integer
// to be a valid mask
0x00 if count_ones =>
count_ones = false;
continue;
// We're processsing 1s and this byte has at least a 1, so we have
// to check bit by bit that the left-most bits are 1s and the
// right-most bits are 0s
byte if byte > 0 && count_ones =>
let mut bit_index = 7;
while (byte >> bit_index) & 1 == 1
// This does not overflow, because we now this byte has at
// least a 0 somewhere
bit_index -= 1
// At this point, all the bits should be 0s
count_ones = false;
for i in 0..bit_index
if (byte >> i) & 1 == 1
return false;
// Any other case is an error
_ => return false,
true
And to test it:
fn main()
assert!(is_valid_ipv6_mask(0));
assert!(is_valid_ipv6_mask(
0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
));
assert!(is_valid_ipv6_mask(
0xffff_0000_0000_0000_0000_0000_0000_0000
));
assert!(is_valid_ipv6_mask(
0xff80_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xff01_0000_0000_0000_0000_0000_0000_0000
));
assert!(!is_valid_ipv6_mask(
0xffff_0000_ffff_ffff_ffff_ffff_ffff_ffff
));
Link to playground.
The problem is that have the feeling that there must be a much simple solution to this problem. After all, bit operations are what computers do, I can't believe there's not more concise and more efficient way to check if an integer is all 1s then all 0s.
integer rust
asked Jun 23 at 19:16
little-dude
1985
1985
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
The problem is that have the feeling that there must be a much simple solution to this problem.
You're right! Integers in Rust have many useful bitwise operations (as well as other useful ones like wrapping and saturating arithmetic), most of which are exposed as methods on the type. To see the full list, look at the generated documentation for the type, e.g. u128
.
Here's a simple way to write is_valid_ipv6_mask
:
fn is_valid_ipv6_mask(value: u128) -> bool
value.count_zeros() == value.trailing_zeros()
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
The problem is that have the feeling that there must be a much simple solution to this problem.
You're right! Integers in Rust have many useful bitwise operations (as well as other useful ones like wrapping and saturating arithmetic), most of which are exposed as methods on the type. To see the full list, look at the generated documentation for the type, e.g. u128
.
Here's a simple way to write is_valid_ipv6_mask
:
fn is_valid_ipv6_mask(value: u128) -> bool
value.count_zeros() == value.trailing_zeros()
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
add a comment |Â
up vote
4
down vote
accepted
The problem is that have the feeling that there must be a much simple solution to this problem.
You're right! Integers in Rust have many useful bitwise operations (as well as other useful ones like wrapping and saturating arithmetic), most of which are exposed as methods on the type. To see the full list, look at the generated documentation for the type, e.g. u128
.
Here's a simple way to write is_valid_ipv6_mask
:
fn is_valid_ipv6_mask(value: u128) -> bool
value.count_zeros() == value.trailing_zeros()
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
add a comment |Â
up vote
4
down vote
accepted
up vote
4
down vote
accepted
The problem is that have the feeling that there must be a much simple solution to this problem.
You're right! Integers in Rust have many useful bitwise operations (as well as other useful ones like wrapping and saturating arithmetic), most of which are exposed as methods on the type. To see the full list, look at the generated documentation for the type, e.g. u128
.
Here's a simple way to write is_valid_ipv6_mask
:
fn is_valid_ipv6_mask(value: u128) -> bool
value.count_zeros() == value.trailing_zeros()
The problem is that have the feeling that there must be a much simple solution to this problem.
You're right! Integers in Rust have many useful bitwise operations (as well as other useful ones like wrapping and saturating arithmetic), most of which are exposed as methods on the type. To see the full list, look at the generated documentation for the type, e.g. u128
.
Here's a simple way to write is_valid_ipv6_mask
:
fn is_valid_ipv6_mask(value: u128) -> bool
value.count_zeros() == value.trailing_zeros()
answered Jun 23 at 21:09
trentcl
1563
1563
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
add a comment |Â
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
beautilful! Thank you, this is much nicer indeed!
â little-dude
Jun 23 at 22:58
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197131%2fcheck-whether-an-integers-leftmost-bits-are-ones-in-rust%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password