2026-03-02 15:53:32 +07:00
# include "stdafx.h"
2026-03-01 12:16:08 +08:00
# include "Random.h"
# include "System.h"
Random : : Random ( )
{
// 4J - jave now uses the system nanosecond counter added to a "seedUniquifier" to get an initial seed. Our nanosecond timer is actually only millisecond accuate, so
// use QueryPerformanceCounter here instead
2026-03-02 15:53:32 +07:00
int64_t seed ;
2026-03-01 12:16:08 +08:00
QueryPerformanceCounter ( ( LARGE_INTEGER * ) & seed ) ;
seed + = 8682522807148012LL ;
setSeed ( seed ) ;
}
2026-03-02 15:53:32 +07:00
Random : : Random ( int64_t seed )
2026-03-01 12:16:08 +08:00
{
setSeed ( seed ) ;
}
2026-03-02 15:53:32 +07:00
void Random : : setSeed ( int64_t s )
2026-03-01 12:16:08 +08:00
{
this - > seed = ( s ^ 0x5DEECE66DLL ) & ( ( 1LL < < 48 ) - 1 ) ;
haveNextNextGaussian = false ;
}
int Random : : next ( int bits )
{
seed = ( seed * 0x5DEECE66DLL + 0xBLL ) & ( ( 1LL < < 48 ) - 1 ) ;
return ( int ) ( seed > > ( 48 - bits ) ) ;
}
void Random : : nextBytes ( byte * bytes , unsigned int count )
{
for ( unsigned int i = 0 ; i < count ; i + + )
{
bytes [ i ] = ( byte ) next ( 8 ) ;
}
}
double Random : : nextDouble ( )
{
2026-03-02 15:53:32 +07:00
return ( ( ( int64_t ) next ( 26 ) < < 27 ) + next ( 27 ) )
2026-03-01 12:16:08 +08:00
/ ( double ) ( 1LL < < 53 ) ;
}
double Random : : nextGaussian ( )
{
if ( haveNextNextGaussian )
{
haveNextNextGaussian = false ;
return nextNextGaussian ;
}
else
{
double v1 , v2 , s ;
do
2026-03-02 15:53:32 +07:00
{
2026-03-01 12:16:08 +08:00
v1 = 2 * nextDouble ( ) - 1 ; // between -1.0 and 1.0
v2 = 2 * nextDouble ( ) - 1 ; // between -1.0 and 1.0
s = v1 * v1 + v2 * v2 ;
} while ( s > = 1 | | s = = 0 ) ;
double multiplier = sqrt ( - 2 * log ( s ) / s ) ;
nextNextGaussian = v2 * multiplier ;
haveNextNextGaussian = true ;
return v1 * multiplier ;
}
}
int Random : : nextInt ( )
{
return next ( 32 ) ;
}
int Random : : nextInt ( int n )
{
assert ( n > 0 ) ;
if ( ( n & - n ) = = n ) // i.e., n is a power of 2
2026-03-02 15:53:32 +07:00
return ( int ) ( ( ( int64_t ) next ( 31 ) * n ) > > 31 ) ; // 4J Stu - Made int64_t instead of long
2026-03-01 12:16:08 +08:00
int bits , val ;
do
{
bits = next ( 31 ) ;
val = bits % n ;
} while ( bits - val + ( n - 1 ) < 0 ) ;
return val ;
}
float Random : : nextFloat ( )
{
return next ( 24 ) / ( ( float ) ( 1 < < 24 ) ) ;
}
2026-03-02 15:53:32 +07:00
int64_t Random : : nextLong ( )
2026-03-01 12:16:08 +08:00
{
2026-03-02 15:53:32 +07:00
return ( ( int64_t ) next ( 32 ) < < 32 ) + next ( 32 ) ;
2026-03-01 12:16:08 +08:00
}
bool Random : : nextBoolean ( )
{
return next ( 1 ) ! = 0 ;
}