Rnd and UlongInt

General FreeBASIC programming questions.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Rnd and UlongInt

Post by dodicat »

randomize ,5 is useless here.
randomize ,2 is the fastest.
Using the string method to get a random number, since I only require a random number between 48 and 57, I feel safe enough using randomize ,2

Code: Select all


Function rndX (s1 As String) As String
    #macro GetNumber
    #define range(f,l) Int(Rnd*((l+1)-(f))+(f))
      s[0]=range(48,s1[0])
    For n As Long = 1 To L-1
        s[n]=range(48,57)
    Next
    #endmacro
    #macro compare(n1,n2,ans)
    Scope
        Var lenn1=Len(n1),lenn2=Len(n2)
        If lenn1 > lenn2 Then ans=-1:Goto lbl
        If lenn1 < lenn2 Then ans=0:Goto lbl
        If n1 > n2 Then ans = -1  Else ans= 0
        lbl:
    End Scope
    #endmacro
    Dim As Long L=Len(s1),ans=1
    Dim As String s=String(L,0)
    While ans
        GetNumber
        compare(s,s1,ans)
    Wend
    Return Ltrim(s,"0")
End Function



Function Get64Bit() As UlongInt
Dim As Ulongint a, b
  a = (Cast( Ulongint, Rnd*(2^32) ) Shl 32) Or Cast( Ulongint, Rnd*(2^32) )
  b = (Cast( Ulongint, Rnd*(2^32) ) Shl 32) Or Cast( Ulongint, Rnd*(2^32) )
  Return a Xor b
End Function


dim as double t
dim as ulongint u=-1,v
dim as string su=str(u)
dim as string s

print u

randomize ,2

t=timer
for n as long=1 to 1000000
 s=rndX(su)
next
print s, timer-t
'======================


sleep 100


randomize ,5

t=timer
for n as long=1 to 1000000
 v=Get64Bit()
next
print v,timer-t
sleep


 

Code: Select all

18446744073709551615
14351978296743188418         0.8591712197521702
750512437885913434           12.63822316541337
 
If those magic numbers, 48 to 57, appear with equal probabilities then the string method never lies.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Rnd and UlongInt

Post by deltarho[1859] »

I am sorry dodicat but I have to take you to task on your last post.
Muggins here wrote:Note that I am using ' Randomize , 5' which is pityfully slow but we will not notice with only four calls.
I shouldn't think that Get64Bit is particularly fast but I am not concerned about that as it will only be used occasionally in the application it was designed for.
As indicated above Get64Bit is not intended to be called much during an application session so speed should not be an issue.

And what do you do? Call Get64Bit one million times.

I introduced the 'a Xor b' method for those that do not use 'Randomize , 5' so as to add some obfuscation.

And what do you do? Use 'Randomize , 5' AND the 'a Xor b' method.
since I only require a random number between 48 and 57, I feel safe enough using randomize ,2
I would feel safe using Randomize , 4! If safety is absolutely not an issue then I would not use 'Randomize , 5' nor would I use the 'a Xor b' method.

I do not have an issue with your string method but do not pit it against something which was designed to do something completely different.

Whilst on the subject of speed if .randse, with PCG32II.bas, was used in Get64Bit instead of Rnd then it comes in over five times faster than the string method.

<smile>
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Rnd and UlongInt

Post by dodicat »

Sorry deltarho{}
I thought that you recommend randomize ,5 for a random ulongint for any of your numerical methods.
But not so, I see.
The string method cannot be fast of course, but it is true.
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: Rnd and UlongInt

Post by TeeEmCee »

If you care about speed and wnat random, you shouldn't be using FB's PRNGs, due to the unnecessary and slow conversion from integer to double and back.

Don't ever use randomize method 2 (RND_FAST) with the xor-based Get64Bit! Because it is a LCG the 32th bit returned from RND alternates on every call, the 31th bit alternates after every 2 calls, etc. Which means that the 32nd and 64th bits returned from Get64Bit will always be zero, and the 31st and 63th bits will be either always 0 or always 1! In fact, even without the xor, the 32nd and 64th bits never change!

In fact, using randomize ,2 to generate a 32 bit integer is a bad idea, and the xor method to "improve" Get64Bit actually makes it worse. If you want to fix the bad bits produced by randomize ,2 should instead use some bit mixing, like PCG64 does. Well actually, if you did that, you would have actually implemented an algorithm in the PCG family! So I can't see the point of using FB's RNG at all in that case.

If you want to use Get64Bit, use either the default randomize method (3, Mersenne Twister), or 5 (CSRNG). Never use the other methods, they will all produce bits which never change.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Rnd and UlongInt

Post by deltarho[1859] »

@dodicat
I thought that you recommend randomize ,5 for a random ulongint for any of your numerical methods.
I am doing but I did try to stress that Get64Bit was not designed to be called many times. In PCG32II.bas, for example, if we supply a seed and a sequence index Get64Bit doesn't get used at all. If we don't supply either then Get64Bit will be called twice and if we stay with that setup for the remainder of the application session then Get64Bit takes 'an early bath'.

@TeeEmCee

I don't use FB's PRNGs, full stop. I may do to illustrate some code but I would not use them in my own use. I looked at FB's Mersenne twister at the begining of March figuring that it was the best of the bunch but did not like it. The engine was begging to be replaced with asm and the seeding was very poor. The asm was completed and the seeding made to be a full loading of the state vector instead of a small seed plus a 'cheapo' PRNG to fill the state vector. I only used it for fixed seeding because random seeding was a job given to CryptoRnd; a cryptographic output and much faster than Mersenne Twister. PCG32 came along and then PCG32II. CryptoRnd has now been pushed aside and PCG32II is now my default generator.

I used 5 (CPRNG) before I looked at Get64Bit and continued to use it when Get64Bit replaced the earlier method.

Thanks for the info on 2 ( Fast ). I thought that it was a 'bog' standard Multiply-With-Carry which Marsaglia originally introduced. I wouldn't touch it because Marsaglia improved upon that and his final tweak was not far away from his death in 2011. An LCG? Oh, dear!

I agree with your conclusion. I would add that if Mesenne Twister is used with Get64Bit and obfuscation is not needed then use the twin Rnd method. If obfuscation is needed then go with the twin RND plus xor method. In fact, it is not that much slower - it should be but it isn't. If speed is not an issue then forget about Mersenne Twister with or without obfuscation and go with the twin Rnd method ( no xor ) plus 5 (CPRNG ).

In my own version of PCG32II I am using the twin Rnd plus xor method and 5 (CPRNG). Why? Well, for the last 10 years or so I have done a lot of work on encryption, read Bruce Scnhneier's blogs and have become well and truly paranoid. <laugh>. Read his latest on the NSA's use of Traffic Shaping here.
Post Reply