Const random array

Looking for a simple way to generate const arrays of random numbers. There is a const_random crate that generates const random values. The code below compiles - but it's not what I want - I want a1 and a2 to be different and each have 64 different random values...

use const_random::const_random;

const fn f() -> [u64; 64] {
    [const_random!(u64); 64]
}

const a1: [u64; 64] = f();
const a2: [u64; 64] = f();

fn main() {
    for i in 0..64 {
        println!("i: {} a1: {} a2: {}", i, a1[i], a2[i])
    }
}

a const fn will always return the same thing, and thus isn't what you want.

Try this:

macro_rules! add_elems {
    ($entry:ident $($tokens:tt)*) => {
        add_elems!{0, $entry $($tokens)*}
    };
    ($acc:expr, $entry:ident $token:tt $($tokens:tt)*) => {
        add_elems!{2*$acc, $entry $($tokens)*}
        add_elems!{2*$acc + 1, $entry $($tokens)*}
    };
    ($count:expr, $entry:ident) => {
        $entry[$count] = const_random!(u64);
    };
}

macro_rules! random_arr {
    () => {{
        let mut arr: [u64; 64] = [0; 64];
        add_elems!(arr ######);
        arr
    }}
}

const A1: [u64; 64] = random_arr!();
const A2: [u64; 64] = random_arr!();

Based on this macro conversation.

3 Likes

Many thanks - cool macro.

Found another way to produce u64 arrays - because I notice now that const_random! supports u8 arrays

let data: [u8; 4096] = const_random::const_random!([u8; 4096]);

Only u8, but we can then cast to u64:

    let mut data64 = [0u64; 64];
    let i=0;
    while i<64 {
        let j = i * 8;
        data64[i] = u64::from_be_bytes(data[j..j + 8].try_into().unwrap());
        i+=1;
    }

Edit: almost - from is not const ...