Obsah / Utility / RANDOM / Gaussovo náhodné číslo
Zdrojový kód:
INCLUDE\UTIL\RANDOM.INC, UTIL\RANDOM.ASM
Gaussovo náhodné
číslo
Funkce RandGauss je
jednoduchou variantou generátoru náhodného čísla s
Gaussovým rozložením. Vstupním parametrem je stupeň strmosti
v registru AL, což je číslo s rozsahem 0 až 255, které
představuje strmost křivek.
Pro stupeň 0 se jedná o
běžný lineární generátor náhody. Stupeň 1 představuje
generátor náhody s lineárním nárustem v intervalu 0 až 0.5
a s lineárním poklesem v intervalu 0.5 až 1. S rostoucím
stupněm se křivka náhodnosti zaobluje, snižuje se
pravděpodobnost čísel blížících se hodnotám 0 a 1 a
zvyšuje se pravděpodobnost čísel blížících se hodnotě
0.5.
; -----------------------------------------------------------------------------
; Generate Pseudo-Gaussian random number
; -----------------------------------------------------------------------------
; INPUT: AL = level (0 to 255, 0=linear)
; OUTPUT: ST0 = random double float (0 to 1)
; NOTES: This random generator is not true Gaussian generator. It
; generates random numbers with distribution which is near to
; the Gaussian distribution. This is very simple algorithm:
; it simple adds given number of random numbers. In results
; there is minimal probability of values near 0 and 1 and
; maximal probability of values near 0.5. Level value determines
; steepness of the probability curve.
; Warning - this function uses FPU (push/pop state if in kernel).
; -----------------------------------------------------------------------------
; Level 0: Level 1: Level 2: Level 10: X
; | | | | XXX
; | | x | xXXXx | xXXXx
; | | xXXXx | XXXXXXXXX | XXXXX
; |XXXXXXXXXXX | xXXXXXXXx | XXXXXXXXXXX | xXXXXXx
; |XXXXXXXXXXX |xXXXXXXXXXXXx | xxXXXXXXXXXXXXXXXxx | xxXXXXXXXXXxx
; +----------- +------------- +--------------------- +----------------------
; -----------------------------------------------------------------------------
; ------------- Push registers
RandGauss: push ecx ; push ECX
; ------------- Prepare level
movzx ecx,al ; ECX <- required level
inc ecx ; ECX <- number of random numbers
push ecx ; push ECX, count of numbers
; ------------- Add random numbers
fldz ; load zero to ST0
RandGaussFPU2: call RandDoubleFPU ; generate random double float number
faddp st1,st0 ; add number to accumulator
loop RandGaussFPU2 ; next value
; ------------- Divide accumulator with count of numbers
fidiv dword [esp] ; divide with count of numbers
pop ecx ; destroy ECX from the stack
; ------------- Pop registers
pop ecx ; pop ECX
ret
|
Obsah funkce RandGauss je
velmi jednoduchý. Do registru ECX se připraví požadovaný
stupeň strmosti (z registru AL) zvýšený o 1. Opakovaně se v
cyklu s počtem opakování podle registru ECX generuje náhodné
číslo a přičítá se ke střadači. Po výpočtu všech
čísel se součet vydělí původním obsahem registru ECX, tedy
stupněm strmosti + 1 neboli počtem vygenerovaných náhodných
čísel ve střadači.
Obsah / Utility / RANDOM / Gaussovo náhodné číslo