unsafe extern "C" {
fn eadk_random() -> u32;
}
static mut FAST_RNG_STATE: u32 = 0x12345678;
#[inline(always)]
pub fn random_c() -> u32 {
unsafe {
if FAST_RNG_STATE & 0xFF == 0 {
FAST_RNG_STATE = eadk_random();
if FAST_RNG_STATE == 0 { FAST_RNG_STATE = 1; }
}
FAST_RNG_STATE ^= FAST_RNG_STATE << 13;
FAST_RNG_STATE ^= FAST_RNG_STATE >> 17;
FAST_RNG_STATE ^= FAST_RNG_STATE << 5;
FAST_RNG_STATE
}
}
#[inline(always)]
pub fn random_hardware() -> u32 {
unsafe { eadk_random() }
}
#[inline(always)]
pub fn randint(min: u64, max: u64) -> u64 {
debug_assert!(min <= max, "randint: min cannot be greater than max");
if min == max {
return min;
}
let range = max - min + 1;
if range & (range.wrapping_sub(1)) == 0 {
let mask = range - 1;
if range <= 0x1_0000_0000 { return min + ((unsafe { eadk_random() } as u64) & mask);
} else {
let rand_u64 = unsafe {
(eadk_random() as u64) | ((eadk_random() as u64) << 32)
};
return min + (rand_u64 & mask);
}
}
if range <= 0x1_0000_0000 {
let threshold = (0x1_0000_0000_u64 / range) * range;
loop {
let rand_val = unsafe { eadk_random() } as u64;
if rand_val < threshold {
return min + (rand_val % range);
}
}
}
let threshold = (u64::MAX / range) * range;
loop {
let rand_u64 = unsafe {
(eadk_random() as u64) | ((eadk_random() as u64) << 32)
};
if rand_u64 < threshold {
return min + (rand_u64 % range);
}
}
}
#[inline(always)]
pub fn random_f64() -> f64 {
let rand_bits = unsafe { eadk_random() };
let float_bits = 0x3FF0_0000_0000_0000_u64 | ((rand_bits as u64) << 20);
f64::from_bits(float_bits) - 1.0
}
#[inline(always)]
pub fn random_f64_range(min: f64, max: f64) -> f64 {
debug_assert!(min < max, "random_f64_range: min must be less than max");
let rand_bits = unsafe { eadk_random() };
let float_bits = 0x3FF0_0000_0000_0000_u64 | ((rand_bits as u64) << 20);
let rnd = f64::from_bits(float_bits) - 1.0;
min + (max - min) * rnd
}
#[inline]
pub fn random_bool() -> bool {
unsafe { (eadk_random() & 1) != 0 }
}
#[inline(always)]
pub fn random_bool_with_probability(probability: f64) -> bool {
debug_assert!((0.0..=1.0).contains(&probability), "probability must be between 0.0 and 1.0");
let threshold = (probability * 4294967296.0) as u64; let threshold = threshold.min(0xFFFFFFFF) as u32;
unsafe { eadk_random() <= threshold }
}