Reputation: 21333
I have a random number generator as follows.
uint64_t s[ 2 ];
uint64_t next(void) {
uint64_t s1 = s[ 0 ];
const uint64_t s0 = s[ 1 ];
s[ 0 ] = s0;
s1 ^= s1 << 23; // a
return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0; // b, c
}
I would like in fact to get doubles in the range (0,1). One option is to do this in my code
#define M_RAN_INVM64 5.42101086242752217003726400434970855e-20
[..]
double u1;
u1 = next()*M_RAN_INVM64;
One option is to cast next() to signed long long, multiply by M_RAN_INVM64 and then add 0.5. I can then add 2^(64)/2 to make sure I never get 0 I think.
Upvotes: 3
Views: 1273
Reputation: 154335
After accept answer:
double
numbers are logarithmically distributed. There are as many double
0.25 to 0.5 as there is 0.5 to 1.0 - assuming a base 2 double
.
Assuming double
is IEEE binary64:...
To get a uniform (linear) distribution of double
in the range [0.0 to 1.0) only 2^53 values can be used. So throw out 11 bits from the result of next()
uint64_t u1 = next();
u1 >>= 11;
// or
u1 &= 0x001FFFFFFFFFFFFF;
if (u1 == 0) ThrowOutZero();
// convert to (0.0 to 1.0)
double d = u1 / 9007199254740992.0; // Divide by 2^53
Upvotes: 2
Reputation: 4433
EDITED: In order to convert any positive unsigned long long
to long double
in the range (0, 1), you can use the following step factor:
long double step = ((long double) 1.0) / ULLONG_MAX
ADDITIONAL INFORMATION Perhaps you could take in account the limits of your system when working with floating point numbers. What follows could help you to understand the floating point numbers in your system:
There is a portable way to obtain the smallest floating point number in the system where your program is compiled.
This can be achieved by using the standard library <float.h>
.
With it you can use the following macro constants:
FLT_MIN // Smallest positive float number in your system
DBL_MIN // Smallest positive double number in your system
LDBL_MIN // Smallest positive long double number in your system
Also, you can take in account the "epsilon"-like constants, which gives you the information about the smallest positive number, of a given type, such that 1.0 != 1.0 + "epsilon".
This can helps you when you are trying to obtain numbers as close to 1.0 as possible, but still different:
FLT_EPSILON
DBL_EPSILON
LDBL_EPSILON
See, for example: float.h (ANSI)
Upvotes: 1