|
![](/i/fill.gif) |
Severi Salminen <sev### [at] NOT THISsaunalahti fi invalid> wrote:
>
> double x,y,z;
>
> do{
> x = 2.0 * rNG.randomNumberClosed() - 1.0;
> z = 2.0 * rNG.randomNumberClosed() - 1.0;
> }
> while(x*x + z*z > 1.0);
>
> y = sqrt(1.0 - (x*x + z*z));
This can be optimized to:
double x,y,z,rSquare;
do{
x = 2.0 * rNG.randomNumberClosed() - 1.0;
z = 2.0 * rNG.randomNumberClosed() - 1.0;
rSquare = x*x + z*z;
}
while(rSquare > 1.0);
y = sqrt(1.0 - rSquare);
Or maybe this is even a bit faster (and actually a tiny bit more defensively
coded):
double x,y,z,ySquare;
do{
x = 2.0 * rNG.randomNumberClosed() - 1.0;
z = 2.0 * rNG.randomNumberClosed() - 1.0;
ySquare = 1.0 - (x*x + z*z);
}
while(ySquare < 0.0);
y = sqrt(ySquare);
(I guess comparing two floats is roughly as expensive as computing their
difference; at least this is the case for integers; and comparing a float with
zero is a piece of cake.)
I also fancy that it would be favorable from a performance point of view to pull
*signed* floats in the range of [-1..1] directly out of the random stream,
because it would just be a matter of filling in one more random bit (namely the
sign bit). It would double the chance of getting a zero, but we can probably
invest some of the time saved by the elimination of a multiplication and
subtraction to filter out negative-zero values (which would occur once in 2^24
rolls for single-precision floats).
But that's probably a RNG design thing.
Post a reply to this message
|
![](/i/fill.gif) |