Looking for a random number generator, I've found (thanks to one of my "C++ pals") a routine which could be expanded to assembly as:

It seems to produce well-distribued random dwords and I'm used to initialize the seed with RDTSC. That's all for the integers. Now to the floating point results.

The easiest way to produce a random floating point value I've managed to write on my own is:

This procedure provides (just as the integer one) a very good distribution of values, however:

- resulting values are in the range between 1.0 (inclusive) and 2.0 (exclusive), and I've not found any reasonable integer method for range conversion (any ideas?)

- results are returned in EAX, not on the top of FPU's stack. That seems to be against the "common" rules, but can be easily used for purposes of:

Alternatively, I'd propose such a modification (this solves both oddities listed above):

Cheers, Mikael

`iRand PROC USES EDX`

mov EAX,00BB38435h

mul

add EAX,03619636Bh

mov ,EAX

ret

iRand ENDP

It seems to produce well-distribued random dwords and I'm used to initialize the seed with RDTSC. That's all for the integers. Now to the floating point results.

The easiest way to produce a random floating point value I've managed to write on my own is:

`fRand PROC USES EDX`

mov EAX,00BB38435h

mul

add EAX,03619636Bh

mov ,EAX

and EAX,07FFFFFFFh ; get rid of sign bit

or EAX,03F800000h ; fix the exponent

ret

fRand ENDP

This procedure provides (just as the integer one) a very good distribution of values, however:

- resulting values are in the range between 1.0 (inclusive) and 2.0 (exclusive), and I've not found any reasonable integer method for range conversion (any ideas?)

- results are returned in EAX, not on the top of FPU's stack. That seems to be against the "common" rules, but can be easily used for purposes of:

` mov ,$INVOKE(fRand)`

Alternatively, I'd propose such a modification (this solves both oddities listed above):

`fRand PROC`

push EAX

push EDX

fld1

mov EAX,00BB38435h

mul

fadd st(0),st(0)

add EAX,03619636Bh

mov ,EAX

and EAX,07FFFFFFFh ; get rid of sign bit

or EAX,03F800000h ; fix the exponent

xchg EAX,

pop EDX

fsub DWORD PTR

add ESP,04

ret

fRand ENDP

Cheers, Mikael

There seems to be one more oddity with your algo for floating point values:

Based on random distribution of bits, bit30 should be set some 50% of the time. This means that the generated float value would be considered as a NAN some 50% of the time if you tried to use it as a parameter on the FPU. I do agree that the other 50% of the time, the generated number would be between 1 and 2.

A result between 0 and 1 would be more acceptable since it could easily be converted to a random value within a specified range. My suggestion to prevent NANs and provide a random fractional floating point number between 0 and 1 would be (still based on your RNG algo):

Raymond

Based on random distribution of bits, bit30 should be set some 50% of the time. This means that the generated float value would be considered as a NAN some 50% of the time if you tried to use it as a parameter on the FPU. I do agree that the other 50% of the time, the generated number would be between 1 and 2.

A result between 0 and 1 would be more acceptable since it could easily be converted to a random value within a specified range. My suggestion to prevent NANs and provide a random fractional floating point number between 0 and 1 would be (still based on your RNG algo):

`mov eax,00BB38435h`

mul

add eax,03619636Bh

mov ,EAX

and eax,3FFFFFFFh ;instead of 7FFFFFFFh

or eax,3F800000h ; fix the exponent to 1

push eax

fld dword ptr

fld1

fsubp st(1),st

pop eax ;clean stack

Raymond

You're absolutely right. Since we need an exponent equal to 127, bit 30 should be always cleared and thus - we need to and EAX with 3FFFFFFFh. Thanks.