rng_utils.h (1067B)
1 #pragma once 2 3 #include "intrinsics.h" 4 5 // TODO: this probably sucks 6 template< typename T > 7 float rng_float( T * rng ) { 8 return ( float ) rng_next( rng ) / ( float ) UINT32_MAX; 9 } 10 11 // TODO: there are papers with better implementations than this 12 // but we might never need anything better 13 template< typename T > 14 double rng_double( T * rng ) { 15 u64 r64 = ( ( u64 ) rng_next( rng ) << 32 ) | rng_next( rng ); 16 u64 r53 = r64 & ( ( ( u64 ) 1 << 53 ) - 1 ); 17 18 return ( double ) r53 / ( ( u64 ) 1 << 53 ); 19 } 20 21 template< typename T > 22 bool rng_p( T * rng, double p ) { 23 return rng_next( rng ) < u32( p * U32_MAX ); 24 } 25 26 template< typename T > 27 u32 rng_mod( T * rng, u32 n ) { 28 u32 r = rng_next( rng ); 29 return u32( ( u64( r ) * n ) >> u64( 32 ) ); 30 } 31 32 // [min, max) 33 template< typename T > 34 u32 rng_uniform( T * rng, u32 lower_bound, u32 upper_bound ) { 35 ASSERT( lower_bound <= upper_bound ); 36 return rng_mod( rng, upper_bound - lower_bound ) + lower_bound; 37 } 38 39 template< typename T > 40 u64 rng_next_u64( T * rng ) { 41 return ( u64( rng_next( rng ) ) << u64( 31 ) ) | rng_next( rng ); 42 }