Reputation: 768
I'm trying to convert a Bitv to uint.
use std::collections::Bitv;
use std::num::Float;
fn main() {
let mut bv = Bitv::with_capacity(3,false);
bv.set(2,true); // Set bit 3
let deci = Vec::from_fn(bv.len(),|i| if bv.get(i) {
(i as f32).exp2()
} else { 0f32 }).iter()
.fold(0u, |acc, &n| acc+n as uint);
println!["{}",deci] // 4
}
That works. Though I wanna know if there is any library function that I'm unaware of or is there any other better way to do.
Upvotes: 1
Views: 174
Reputation: 430891
Some transformations of your code I made.
Rust 1.0
let vec: Vec<_> = (0..bv.len()).map(|i| {
if bv[i] {
1 << i
} else {
0
}}).collect();
let deci = vec.iter().fold(0, |acc, &n| acc + n);
Original
let vec = Vec::from_fn(bv.len(), |i| {
if bv.get(i) {
1u << i
} else {
0u
}});
let deci = vec.iter().fold(0u, |acc, &n| acc + n);
Rust 1.0
let deci = bv.iter()
.fold((0, 0), |(mut acc, nth), bit| {
if bit { acc += 1 << nth };
(acc, nth + 1)
}).0;
Original
let deci = bv.iter()
.fold((0u, 0u), |(mut acc, nth), bit| {
if bit { acc += 1 << nth };
(acc, nth + 1)
}).0;
Rust 1.0
let deci = bv.iter()
.enumerate()
.filter_map(|(nth, bit)| if bit { Some(1 << nth) } else { None })
.fold(0, |acc, val| acc + val);
Original
let deci = bv.iter()
.enumerate()
.filter_map(|(nth, bit)| if bit { Some(1 << nth) } else { None })
.fold(0u, |acc, val| acc + val);
Ideally, you could reorganize your code to make use of to_bytes, but the order of bits is different from your example.
Upvotes: 2
Reputation: 65782
Bitv
doesn't provide a way to return its value as a uint
, because the Bitv
might contain more bits than a uint
does. BTW, the size of uint
is architecture-dependant (32 bits on 32-bit systems, 64 bits on 64-bit systems), so you should prefer using u32
or u64
unless you really need a uint
.
Bitv
provides the to_bytes
and to_bools
methods, which return a Vec<u8>
and a Vec<bool>
, respectively. A Vec<u8>
is more compact than a Vec<bool>
, so to_bytes
should be preferred when the Bitv
is known to be large (but if it's known to be large, why would you try converting it to a uint
?).
We can also iterate on the bits directly by using iter
.
use std::collections::Bitv;
use std::mem;
fn main() {
let mut bv = Bitv::with_capacity(3, false);
bv.set(2, true); // Set bit 3
let deci = bv.iter().enumerate().fold(
0u64,
|accum, (bit_pos, bit)| {
if bit {
assert!(bit_pos < mem::size_of_val(&accum) * 8);
accum + (1 << bit_pos)
} else {
accum
}
});
println!("{}", deci); // 4
}
Upvotes: 2