RND breadth

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

RND breadth

Postby albert » Feb 02, 2019 2:16

@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 19

dim as ulongint n

dim as ulongint low = 0
dim as ulongint hi = 0

for 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
   
next

print "10,000,000 loops of int( rnd * (2^64) )"
print " Random > 2^32 = " ; hi
print " Random < 2^32 = " ; low

sleep
end



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

Postby dodicat » Feb 02, 2019 4:40

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 generator

type Rand
   a as ulongint
   b as ulongint
   c as ulongint
   d as ulongint
end type

function 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.d
end 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)
        next
end sub

'=========
dim shared as rand z
init(z)
'========


dim as ulongint n

dim as ulongint low = 0
dim as ulongint hi = 0
dim as ulongint two32=2^32
dim as ulongint a
do
    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,two32
loop 'until low   
'next

print "10,000,000 loops of int( rnd * (2^64) )"
print " Random > 2^32 = " ; hi
print " Random < 2^32 = " ; low

sleep
end
 

After about a minute;

Code: Select all

536485710     1555398835    4294967296
1057045101    291252990     4294967296
3079478361    907588912     4294967296
3269997952    3076745340    4294967296
7458512934    4249469337    4294967296
17254913240   1653329772    4294967296
22280084453   1048105299    4294967296 
Munair
Posts: 886
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: Coders

Postby Munair » Feb 02, 2019 5:57

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

Re: Coders

Postby deltarho[1859] » Feb 02, 2019 6:53

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

Postby Tourist Trap » Feb 02, 2019 9:57

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

Postby albert » Feb 02, 2019 18:56

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

Code: Select all


screen 19

do
   
    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
Site Admin
Posts: 6236
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Coders RND

Postby counting_pine » Feb 02, 2019 20:23

Try this code:

Code: Select all

const N = 1e12
const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = N
dim as integer r1, r2, r3, r4
for 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 select
next i

print using "Numbers between & and &: &"; q0; q1; r1
print using "Numbers between & and &: &"; q1; q2; r2
print using "Numbers between & and &: &"; q2; q3; r3
print 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

Re: RND breadth

Postby albert » Feb 02, 2019 22:28

@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 19

const N = (2^64)
const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = N
dim as integer r1, r2, r3, r4
dim as ulongint value
dim as integer low = N
for 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 select
next i

print using "Numbers between & and &: &"; q0; q1; r1
print using "Numbers between & and &: &"; q1; q2; r2
print using "Numbers between & and &: &"; q2; q3; r3
print using "Numbers between & and &: &"; q3; q4; r4

print
print "lowest value of rnd*(2^64) = " ; low

sleep
end

MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: RND breadth

Postby MrSwiss » Feb 02, 2019 22:55

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 here
const q0 = 0ull, q1 = N/4ull, q2 = N/2ull, q3 = N*3/4ull, q4 = N
dim as integer r1, r2, r3, r4   ' don't use signed "integer" type (above is unsigned!)
dim as ulongint value
dim 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[1859]
Posts: 2749
Joined: Jan 02, 2017 0:34
Location: UK

Re: RND breadth

Postby deltarho[1859] » Feb 02, 2019 23:28

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

Re: RND breadth

Postby albert » Feb 02, 2019 23:39

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

Re: RND breadth

Postby MrSwiss » Feb 02, 2019 23:53

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

Re: RND breadth

Postby albert » Feb 03, 2019 0:00

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

Re: RND breadth

Postby MrSwiss » Feb 03, 2019 0:05

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

Re: RND breadth

Postby albert » Feb 03, 2019 0:16

If you can't fix why INT( RND * ( 2 ^ 63 ) ) never generates a value less than ( 2 ^ 32 ) , then don't post anything in this topic..

Code: Select all


screen 19

const N = (2^63)
const q0 = 0, q1 = N/4, q2 = N/2, q3 = N*3/4, q4 = N
dim as ulongint r1, r2, r3, r4
dim as ulongint value
dim as ulongint low = N
for 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 select
next i

print using "Numbers between & and &: &"; q0; q1; r1
print using "Numbers between & and &: &"; q1; q2; r2
print using "Numbers between & and &: &"; q2; q3; r3
print using "Numbers between & and &: &"; q3; q4; r4

print
print "lowest value of rnd = " ; low

sleep
end


Return to “General”

Who is online

Users browsing this forum: No registered users and 13 guests