General FreeBASIC programming questions.
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

@Coders

Can you make the RND function so it returns a full breadth of numbers?

It keeps generating above the median of Int( Rnd * ?? )

Try this code..

Code: Select all

`screen 19dim as ulongint ndim as ulongint low = 0dim as ulongint hi = 0for a as longint = 1 to 10000000        n = int( rnd*(2^64) )        if n >= (2^32) then hi+=1    if n <= (2^32) then low+=1    nextprint "10,000,000 loops of int( rnd * (2^64) )"print " Random > 2^32 = " ; hiprint " Random < 2^32 = " ; lowsleepend`

Out of 10,000,000 loops , of Int( Rnd * (2^64) ) , It doesn't get any numbers below (2^32) They are all higher than (2^32)
Last edited by albert on Feb 02, 2019 19:07, edited 1 time in total.
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: Coders

A proper ulongint generator has a better chance.
But 2^32 is very far left of the mean of the range.
Try dividing 2^32/2^64.

Code: Select all

` 'screen 19' ulongint generatortype Rand   a as ulongint   b as ulongint   c as ulongint   d as ulongintend typefunction ranulong(x as rand) as ulongint   dim e as ulongint = x.a - ((x.b shl 7) or (x.b shr (64 - 7)))   x.a = x.b xor ((x.c shl 13) or (x.c shr (64 - 13)))   x.b = x.c + ((x.d shl 37) or (x.d shr (64 - 37)))   x.c = x.d + e   x.d = e + x.a   return x.dend function'function randouble(x as rand) as double ''NOT NEEDED    'return ranulong(x)/18446744073709551615ull   ' end function sub init(x as rand, byval seed as ulongint=100)   dim i as ulongint    x=type(4058668781,seed,seed,seed)    for i as ulongint=1 to 20        ranulong(x)        nextend sub'=========dim shared as rand zinit(z)'========dim as ulongint ndim as ulongint low = 0dim as ulongint hi = 0dim as ulongint two32=2^32dim as ulongint ado    a+=1'for a as longint = 1 to 10000000        n = ranulong(z)'int( rnd*(2^64) )       ' if n >= (two) then hi+=1    if n <= (two32) then low+=1:print a,n,two32loop 'until low   'nextprint "10,000,000 loops of int( rnd * (2^64) )"print " Random > 2^32 = " ; hiprint " Random < 2^32 = " ; lowsleepend `

Code: Select all

`536485710     1555398835    42949672961057045101    291252990     42949672963079478361    907588912     42949672963269997952    3076745340    42949672967458512934    4249469337    429496729617254913240   1653329772    429496729622280084453   1048105299    4294967296  `
Munair
Posts: 886
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

### Re: Coders

Could you make the title more fitting?
deltarho
Posts: 2749
Joined: Jan 02, 2017 0:34
Location: UK

### Re: Coders

The 'half way' mark is 2^64/2 = 2^63 and not 2^64/2^32 = 2^32.

Replacing 2^32 with 2^63 in the opening code gives

Code: Select all

`10,000,000 loops of int( rnd * (2^64) ) Random > 2^63 = 5001478 Random < 2^63 = 4998522`

and always will because Randomize is not being used.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

### Re: Coders

Munair wrote:Could you make the title more fitting?

I second this, titles are important when we do a forum search. Otherwise the informations gathered here will be lost as soon as people will stop answering to it, which generally doesnt take long.
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

### Re: Coders

With RND * 256 , it returns a full breadth of values... with RND * ( higher than 256 ) it mostly returns higher vals.

Code: Select all

`screen 19do        randomize        dim as ulongint n        dim as longint v1 = 0    dim as longint v2 = 0    dim as longint v3 = 0    dim as longint v4 = 0        for a as longint = 1 to 10000000                n = int( rnd*256 )                if n >=   0 and n <  64 then v1+=1        if n >=  65 and n < 128 then v2+=1        if n >= 129 and n < 192 then v3+=1        if n >= 193 and n < 256 then v4+=1            next        print    print "10,000,000 loops of int( rnd * 256 )"    print " Random   0 to  64 = " ; v1    print " Random  65 to 128 = " ; v2    print " Random 129 to 192 = " ; v3    print " Random 193 to 256 = " ; v4    loop until inkey = chr(27)end`
counting_pine
Posts: 6236
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

### Re: Coders RND

Try this code:

Code: Select all

`const N = 1e12const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = Ndim as integer r1, r2, r3, r4for i as integer = 1 to 10e6    select case int(rnd * N)    case q0 to q1: r1 += 1    case q1 to q2: r2 += 1    case q2 to q3: r3 += 1    case q3 to q4: r4 += 1    end selectnext iprint using "Numbers between & and &: &"; q0; q1; r1print using "Numbers between & and &: &"; q1; q2; r2print using "Numbers between & and &: &"; q2; q3; r3print using "Numbers between & and &: &"; q3; q4; r4`

Try the value of N that you want.
There should be about 2.5 million numbers in each group. Let us know if that's not the case.
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

@counting_pine

Thanks it worked....But it still doen't go low... Here's your code , modified to return the lowest value randomly selected.

Code: Select all

`screen 19const N = (2^64)const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = Ndim as integer r1, r2, r3, r4dim as ulongint valuedim as integer low = Nfor i as integer = 1 to 10e6    value = int(rnd*N)    select case value    case q0 to q1: r1 += 1: if value < low then low = value     case q1 to q2: r2 += 1    case q2 to q3: r3 += 1    case q3 to q4: r4 += 1    end selectnext iprint using "Numbers between & and &: &"; q0; q1; r1print using "Numbers between & and &: &"; q1; q2; r2print using "Numbers between & and &: &"; q2; q3; r3print using "Numbers between & and &: &"; q3; q4; r4printprint "lowest value of rnd*(2^64) = " ; lowsleepend`
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

albert wrote:... modified to return the lowest value randomly selected.
Sorry mate, but the fault is in your code:

Code: Select all

`const N = (2^64)ull   ' we want ULongInt hereconst q0 = 0ull, q1 = N/4ull, q2 = N/2ull, q3 = N*3/4ull, q4 = Ndim as integer r1, r2, r3, r4   ' don't use signed "integer" type (above is unsigned!)dim as ulongint valuedim as integer low = N   ' not randomly selected, it's "highest possible value"`
Secondly, you shoult use the same data-type as N (for low = 0).
deltarho
Posts: 2749
Joined: Jan 02, 2017 0:34
Location: UK

The last few posts by albert and counting_pine, after correcting warnings and data-types, are fine but do nothing to explain the behaviour of the opening post which is a different issue.

The logic of the opening post is flawed.

Lets look at a simple example.

2^8 = 256

The logic of the opening post would say that the mid-point of 2^8 is 2^4. 2^4 = 16 and, clearly, is not the mid-point of 2^8. The mid-point of 2^8 is 2^8/2 = 2^7 = 128.

In general, the mid-point of 2^n is 2^(n-1) and NOT 2^(n/2).

So, the mid-point of 2^64 is 2^63. Half of the generated values will fall below 2^63 and the other half will fall above 2^63 - see my last post.

The chance of falling below 2^32 is very small.

2^32/2^64 = 0.0000000002328.

So
albert wrote:Out of 10,000,000 loops , of Int( Rnd * (2^64) ) , It doesn't get any numbers below (2^32) They are all higher than (2^32)

should come as no surprise.

On average, we would need to do 2^32 ( 4,294,967,296 ) tests, as opposed to 10,000,000, to see one number below 2^32.

Actually, the mid-point is not exactly as described above but I do not want to confuse the issue by being 'pedantic'.
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

My initial post , was a complaint that , out of INT( RND* (2^64) ) , it never generates values less than ( 2 ^ 32 )

I stated that it never generates values below the median , and you guys started complaining that (2^32) wasn't the median....

My complaint was that , the lowest generated value is greater than 9 digits...

And none of your guy's posts , solved the dilema...
It requies the FB coders attention , to alter the RND function to return a full breadth of values..

if a do 512 loops of Int( RND * 256 ) it should chose each of 256 values , at least once..
Last edited by albert on Feb 02, 2019 23:57, edited 1 time in total.
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

Nope, not true and, counting_pine's code proofes that ...
Rnd gives values between 0.000....... and 0.99999999.........
(but never reaching 1.0), which is denoted by inteval [0, 1).

albert wrote:The lowest generated value is greater than 9 digits...
This has no relation to the value, that's returned.
(because you are mixing decimal value BASE10, with binary value BASE 2)
Last edited by MrSwiss on Feb 03, 2019 0:00, edited 1 time in total.
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

My initial post , was a complaint that , out of INT( RND* (2^64) ) , it never generates values less than ( 2 ^ 32 )

I stated that it never generates values below the median , and you guys started complaining that (2^32) wasn't the median....

My complaint was that , the lowest generated value is greater than 9 digits...

And none of your guy's posts , solved the dilema...
It requies the FB coders attention , to alter the RND function to return a full breadth of values..

if a do 512 loops of Int( RND * 256 ) it should chose each of 256 values , at least once..
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

albert wrote:if a do 512 loops of Int( RND * 256 ) it should chose each of 256 values , at least once..
No, this now relates to the randomizers randomness, meaning, you cannot know
when a certain number appears. The only guaranteed fact is, that it eventually
will appear ... provided, you run the randomizer for many enough run's.

This is in fact, a randmizers purpose for existing, aka: "expected behaviour".
albert
Posts: 5927
Joined: Sep 28, 2006 2:41
Location: California, USA

`screen 19const N = (2^63)const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = Ndim as ulongint r1, r2, r3, r4dim as ulongint valuedim as ulongint low = Nfor i as integer = 1 to 10e6    value = int(rnd*N)    select case value    case q0 to q1: r1 += 1: if value < low then low = value     case q1 to q2: r2 += 1    case q2 to q3: r3 += 1    case q3 to q4: r4 += 1    end selectnext iprint using "Numbers between & and &: &"; q0; q1; r1print using "Numbers between & and &: &"; q1; q2; r2print using "Numbers between & and &: &"; q2; q3; r3print using "Numbers between & and &: &"; q3; q4; r4printprint "lowest value of rnd = " ; lowsleepend`