Need 100% random... :D
It's probably distribution idependent since it is a Kernel thing, but yeah it uses a seed this helps to peoduce more values out of one which has good randomness, the thing is not wether a algorithm uses a seed but where the value for the seed comes from, and Linux uses hardware noiso to generate it, it would also be good to get new seeds when new noise randomness is available, but I don't know more about it.
Visit www.sceneproject.org
It is very difficult to create truly random numbers. Many large computers that develop products that require true random values need external devices that create the seed and/or random number (ex. First Data uses very expensive external devices for their credit card manufacturing.) Some of these devices use light waves to create the random value.
Just remember, there is two kinds of random number generators.
The cryptologically "secure" one.
The goal here is to make sure that numbers do not repeat,
and if they do it should only happen after all other numbers has been exhausted.
Then there is the "random" one,
Kind of a misnomer really as this (and the previous) are both pseudo-random.
The goal with this one is to make sure that there is a even spread,
optimally all numbers in the range should occur with the exact same frequency.
i.e. If you got the range 0-1 then 50% of numbers should be 0 and 50% of numbers should be 1.
It is extreemly difficult to avoid bias in both those types of generators.
The first is used mostly for encryption and similar,
the second is most popular with games and so on.
Simpler random generators sorta do not attempt either of the two methods. (Like PureBasic's generator I guess)
These are more of the traditional kind, either manualy seeded or automaticaly seeded, uses simple seeding values like time or similar.
(seconds from 1 1 1970 midnight GMT is suspectible to same instance issues if two programs (or threads) start within the same second though).
For most people it's usually enough, it is not adviced for serious cryptography though, nor for a perfect spread of numbers (fo AI and scientific research), i.e it can't generate "noise" numbers.
My suggestion is to keep PB's random generator as it is,
if people wish to modify the behaviour they can by re-seeding it using some more unique value than system time, thats why the seed function exist after all.
But I'd like to suggest (maybe this belongs in the feature request forum though),
is that PB later gets two "more" RND generators.
So that eventually PB will have 3 random number generators.
The traditional one:
Random() and RandomSeed()
Cryptologicaly secure:
RandomSecure() and RandomSecureSeed()
Even spread:
RandomSpread() and RandomSpreadSeed()
Yeah yeah silly names I know, it's just an example.
The cryptologic variant may fit better in the cipher lib.
The traditional (current) one is fine where it is.
The even spread on Im' unsure of where it belongs,
it's sorta game and math oriented really.
The cryptologically "secure" one.
The goal here is to make sure that numbers do not repeat,
and if they do it should only happen after all other numbers has been exhausted.
Then there is the "random" one,
Kind of a misnomer really as this (and the previous) are both pseudo-random.
The goal with this one is to make sure that there is a even spread,
optimally all numbers in the range should occur with the exact same frequency.
i.e. If you got the range 0-1 then 50% of numbers should be 0 and 50% of numbers should be 1.
It is extreemly difficult to avoid bias in both those types of generators.
The first is used mostly for encryption and similar,
the second is most popular with games and so on.
Simpler random generators sorta do not attempt either of the two methods. (Like PureBasic's generator I guess)
These are more of the traditional kind, either manualy seeded or automaticaly seeded, uses simple seeding values like time or similar.
(seconds from 1 1 1970 midnight GMT is suspectible to same instance issues if two programs (or threads) start within the same second though).
For most people it's usually enough, it is not adviced for serious cryptography though, nor for a perfect spread of numbers (fo AI and scientific research), i.e it can't generate "noise" numbers.
My suggestion is to keep PB's random generator as it is,
if people wish to modify the behaviour they can by re-seeding it using some more unique value than system time, thats why the seed function exist after all.
But I'd like to suggest (maybe this belongs in the feature request forum though),
is that PB later gets two "more" RND generators.
So that eventually PB will have 3 random number generators.
The traditional one:
Random() and RandomSeed()
Cryptologicaly secure:
RandomSecure() and RandomSecureSeed()
Even spread:
RandomSpread() and RandomSpreadSeed()
Yeah yeah silly names I know, it's just an example.
The cryptologic variant may fit better in the cipher lib.
The traditional (current) one is fine where it is.
The even spread on Im' unsure of where it belongs,
it's sorta game and math oriented really.
You know, PB's generator is pretty darn good actualy for games and stuff.
What might be needed in addition is a cryptologicaly "secure" variant
(and add it to the chiper lib).
Run this test:
If the spread is 100% that means it is perfectly uniform,
which is pretty much impossible to do without actualy keeping track
of all previous values, and no normal generators do that.
If it is anything other than 100% there is a bias,
which is why I show the count of each number so you can see the bias.
This is a standard way (as far as I could learn from info I found)
to test random generators.
Here on the test, 1 million numbers was generated,
if the generator was perfect it would result in 100% meaning
half a million 0's and half a million 1's.
PureBasic (and thus Fred actualy
) is very good.
With 1 million numbers generated the spread is over 99%
and the speed is very impressive too btw only fraction of a second.
The higher you set the numbers.l= the longer it takes to run the test obviously, 1 billion took over half a minute here,
but the spread weas even closer to 100%.
If you reduce the numbers.l= to something very low, you will find that the spread gets worse.
numbers.l=10 for example, you may actualy end up wih 0% spread
(only 0's for example), or anywhere between 0-100%.
So the more numbers/runs the the better spread you get.
Which is good, esp for a game that may need several thousand if not millions of random numbers during a game session for events etc.
A word of warning though (altough you can try).
Do not use RandomSeed(Date()) or similar right inside the loop.
You will find horrible spread of numbers.
My recommendation? Don't use RandomSeed() in the loop unless you really know what you are doing.
It would be nice with a GetRandomSeed() though as a game could then "save" the seed and then set it later (when a save game is loaded)
to ensure that the random state is consistent across save games.
Hmm. GetRandomSeed() and rename RandomSeed() to SetRandomSeed() so it matches the naming conventions of other stuff?
Anyway, Random() impress me, I wasn't aware it was as good as this.
EDIT:
For info on cryptographicaly secure random genrators here is a nice link,
http://www.ssh.fi/support/cryptography/algorithms/
http://www.itl.nist.gov/fipspubs/fip186.htm (no idea what license these algorythms has though)
What might be needed in addition is a cryptologicaly "secure" variant
(and add it to the chiper lib).
Run this test:
Code: Select all
DisableDebugger
numbers.l=1000000
zero.l=0
one.l=0
n.l=0
i.l=0
;RandomSeed(Date()) ;optional as PB allready do this at program start,
;but this is how/where you would restore/set the seed from a saved game or similar.
start=ElapsedMilliseconds()
For i=1 To numbers
n=Random(1)
If n=1
one+1
Else
zero+1
EndIf
Next
stop=ElapsedMilliseconds()
spread.d=one/zero
text$=Str(zero)+" zeros"+#LF$
text$+Str(one)+" ones"+#LF$
percent.d=0.0
If spread>1.0
percent=100.0/spread
Else
percent=spread*100.0
EndIf
text$+StrD(percent)+" percent uniform spread"+#LF$
speed.d=(stop-start)/1000.0
text$+StrD(speed)+" seconds to generate "+Str(numbers)+" numbers"+#LF$
MessageRequester("Random() Test",text$)
which is pretty much impossible to do without actualy keeping track
of all previous values, and no normal generators do that.
If it is anything other than 100% there is a bias,
which is why I show the count of each number so you can see the bias.
This is a standard way (as far as I could learn from info I found)
to test random generators.
Here on the test, 1 million numbers was generated,
if the generator was perfect it would result in 100% meaning
half a million 0's and half a million 1's.
PureBasic (and thus Fred actualy

With 1 million numbers generated the spread is over 99%
and the speed is very impressive too btw only fraction of a second.
The higher you set the numbers.l= the longer it takes to run the test obviously, 1 billion took over half a minute here,
but the spread weas even closer to 100%.
If you reduce the numbers.l= to something very low, you will find that the spread gets worse.
numbers.l=10 for example, you may actualy end up wih 0% spread
(only 0's for example), or anywhere between 0-100%.
So the more numbers/runs the the better spread you get.
Which is good, esp for a game that may need several thousand if not millions of random numbers during a game session for events etc.
A word of warning though (altough you can try).
Do not use RandomSeed(Date()) or similar right inside the loop.
You will find horrible spread of numbers.
My recommendation? Don't use RandomSeed() in the loop unless you really know what you are doing.
It would be nice with a GetRandomSeed() though as a game could then "save" the seed and then set it later (when a save game is loaded)
to ensure that the random state is consistent across save games.
Hmm. GetRandomSeed() and rename RandomSeed() to SetRandomSeed() so it matches the naming conventions of other stuff?
Anyway, Random() impress me, I wasn't aware it was as good as this.
EDIT:
For info on cryptographicaly secure random genrators here is a nice link,
http://www.ssh.fi/support/cryptography/algorithms/
http://www.itl.nist.gov/fipspubs/fip186.htm (no idea what license these algorythms has though)
@nco2k
A perfect 100% spread.
And your right, not much need for a even spread random,
current one is damn close and should be more than good enough for most games.
And if Fred added a GetRandomSeed() to fetch the currently used seed,
it would be easier for games that uses random numbers for stuff.
That way you could use one particular seed for AI, another for weather,
another for projectiles another for. well you get it.
Well, you can do that now too, but a GetRandomSeed() would be nice for us lazy people, and esp. since there is no way to get the seed that a PB program starts with currently.
@mskuma
Hehe, I find stuff like this facinating myself
A perfect 100% spread.
And your right, not much need for a even spread random,
current one is damn close and should be more than good enough for most games.
And if Fred added a GetRandomSeed() to fetch the currently used seed,
it would be easier for games that uses random numbers for stuff.
That way you could use one particular seed for AI, another for weather,
another for projectiles another for. well you get it.
Well, you can do that now too, but a GetRandomSeed() would be nice for us lazy people, and esp. since there is no way to get the seed that a PB program starts with currently.
@mskuma
Hehe, I find stuff like this facinating myself
