Page 1 of 1

Make Random() use quads instead of integers

Posted: Mon Jan 27, 2020 1:22 am
by BarryG
Random()'s max value can't exceed the maximum positive integer value, which on 32-bit PureBasic is 2147483647:

Code: Select all

Debug $FFFFFFFF ; Returns 4294967295 (not negative)
Debug Random($FFFFFFFF) ; "Can't be negative" error
So my request is that Random() support quads instead, so the above code works. 2147483647 is actually quite a low maximum.

Re: Make Random() use quads instead of integers

Posted: Mon Jan 27, 2020 1:47 am
by kenmo

Code: Select all

Procedure.i Random32bit()
  ProcedureReturn (Random($FFFF) << 16) | Random($FFFF)
EndProcedure

For i = 1 To 10
  Debug Hex(Random32bit(), #PB_Long)
Next i

Re: Make Random() use quads instead of integers

Posted: Mon Jan 27, 2020 1:49 am
by BarryG
Thanks, kenmo. I just edited my post because I was going to code a clunky string-based workaround, but your bit-flipping example is perfect! Now we just need Random() to be updated to avoid these little hacks.

Re: Make Random() use quads instead of integers

Posted: Mon Jan 27, 2020 10:01 am
by NicTheQuick
If all the 64 bits are good enough for you, this is also possible:

Code: Select all

Define q.q
RandomData(@q, SizeOf(Quad))

Debug q

Re: Make Random() use quads instead of integers

Posted: Sun Dec 12, 2021 4:42 pm
by STARGĂ…TE
I would also prefer if Random() allows quads instead of integers,
especially because a Random()-call already generate a 8 Byte sequence even on x86.

As long this is not possible, here is my RandomQuad()-code:

Code: Select all

Procedure.q RandomQuad(Max.q = $7FFFFFFFFFFFFFFF)
	
	Protected Quad.q, Limit.q
	Protected MaxPlusOne.q = Max+1
	
	If Max <= 0
		ProcedureReturn 0
	EndIf
	
	RandomData(@Quad, 8)
	Quad & $7FFFFFFFFFFFFFFF ; remove the sign bit
	
	If MaxPlusOne & Max = 0
		ProcedureReturn Quad & Max  ; no balancing needed when Max = 2^n-1
	EndIf
	
	Limit = $7FFFFFFFFFFFFFFF - $7FFFFFFFFFFFFFFF % MaxPlusOne - 1
	While Quad > Limit ; balancing needed, generate a new number
		RandomData(@Quad, 8)
		Quad & $7FFFFFFFFFFFFFFF ; remove the sign bit
	Wend
	
	ProcedureReturn Quad % MaxPlusOne ; reduce to the range [0, Max]
	
EndProcedure

Debug RandomQuad(1000000000000)