deep_causality_rand/extensions/
dist_float_64.rs1use crate::{Distribution, Rng};
6use crate::{Open01, OpenClosed01, StandardUniform};
7use deep_causality_num::{FloatAsScalar, FloatFromInt, IntAsScalar, IntoFloat};
8use std::mem;
9
10impl Distribution<f64> for StandardUniform {
11 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
12 let float_size = mem::size_of::<f64>() as u64 * 8;
13 let precision = 52 + 1;
14 let scale = 1.0 / ((1_u64 << precision) as f64);
15
16 let value: u64 = (*rng).random::<u64>();
17 let value = value >> u64::splat(float_size - precision);
18 f64::splat(scale) * f64::cast_from_int(value)
19 }
20}
21
22impl Distribution<f64> for OpenClosed01 {
23 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
24 let float_size = mem::size_of::<f64>() as u64 * 8;
25 let precision = 52 + 1;
26 let scale = 1.0 / ((1_u64 << precision) as f64);
27
28 let value: u64 = (*rng).random::<u64>();
29 let value = value >> u64::splat(float_size - precision);
30 f64::splat(scale) * f64::cast_from_int(value + u64::splat(1))
31 }
32}
33
34impl Distribution<f64> for Open01 {
35 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
36 let float_size = mem::size_of::<f64>() as u64 * 8;
37
38 let value: u64 = (*rng).random::<u64>();
39 let fraction = value >> u64::splat(float_size - 52);
40 fraction.into_float_with_exponent(0) - f64::splat(1.0 - f64::EPSILON / 2.0)
41 }
42}