# Convert a type u16 number to a matrix (Vec<Vec<u8>> or array) of 4 x 4

I am a Rust newbie and I am not familiar with all the iterator options. This is what I have so far. How can I make this better or at least avoid collecting twice into a Vec?

let num: u16 = 0b0010001000100010; // input number
let bin = format!("{:016b}", num);

let parsed = bin
.split("")
.filter_map(|s| s.parse().ok())
.collect::<Vec<u8>>();

let mat = parsed.chunks(4).collect::<Vec<_>>();

println!("{:?}", mat);

// outputs [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]]


## 1 Answer

One thing I'm going to do first is create an enum with only two values. This represents a binary value and is more memory-efficient than passing around a bunch of u8s. This way 16 Bits can be represented as 16 actual bits in memory (though this isn't guaranteed).

/// a single bit
#[derive(Clone, Copy, Debug)]
enum Bit {
/// 1, high
H1 = 1,
/// 0, low
L0 = 0,
}
use Bit::*; // allow us to just use L0 and H1 without the Bit:: prefix


It is likely much faster to split a number into bits using numerical operators. There are a couple ways of doing it.

1. Iterating a mask

With this we increase our mask each time, building an array from it. The 15 - i is there because we want the MSB at index 0.

/// convert a number to 16 bits by sliding a mask across it
fn into_bits_mask(num: u16) -> [Bit; 16] {
let mut out = [L0; 16];

for i in 0..16 {
out[15 - i] = if num & (1u16 << i) > 0 {
H1
} else {
L0
};
}

out
}

1. Shifting the number with a static mask

This is essentially the same thing, but we shift the number instead of the mask.

/// convert a number to 16 bits by right-shifting it
fn into_bits_shift(num: u16) -> [Bit; 16] {
let mut out = [L0; 16];

for i in 0..16 {
out[15 - i] = if (num >> i) & 1u16 > 0 {
H1
} else {
L0
};
}

out
}


We can then modify these to output an array of 4 nibbles.

/// convert a number to 4 nibbles by sliding a mask across it
fn into_nibbles_mask(num: u16) -> [[Bit; 4]; 4] {
let mut out = [[L0; 4]; 4];

for i in 0..16 {
let mask = 1u16 << (15 - i);
out[i / 4][i % 4] = if num & mask > 0 {
H1
} else {
L0
};
}

out
}

/// convert a number to 4 nibbles by right-shifting it
fn into_nibbles_shift(num: u16) -> [[Bit; 4]; 4] {
let mut out = [[L0; 4]; 4];

for i in 0..16 {
out[i /4][i % 4] = if (num >> (15 - i)) & 1u16 > 0 {
H1
} else {
L0
};
}

out
}


There is room for more optimization here, of course.

EDIT: I was asked about using iterators, so here's my most iterator-function styled method

/// convert a number to 4 nibbles using iterator methods
fn into_nibbles_iter(num: u16) -> Vec<Vec<Bit>> {
// split into nibbles
[num >> 12, num >> 8, num >> 4, num]
.iter()
.map(|nibble| {
// mask off each bit
[nibble & 8, nibble & 4, nibble & 2, nibble & 1]
.iter()
// convert to Bits
.map(|b| if b > &0 { H1 } else { L0 })
.collect()
})
.collect()
}


And here's a new playground link demonstrating it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=5ecda81379c3cab749709f551109adfb

• This is amazing @PitaJ and thanks for the working example. I am curious about doing it using iterators regardless of performance – matharumanpreet00 Oct 25 '18 at 16:04
• @matharumanpreet00 I've added an iterator-styled method. Does that answer your question? – PitaJ Oct 25 '18 at 22:05