deep_causality_rand/extensions/
dist_float_64.rs

1/*
2 * SPDX-License-Identifier: MIT
3 * Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
4 */
5use 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}