Make Random() use quads instead of integers

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
BarryG
Addict
Addict
Posts: 3324
Joined: Thu Apr 18, 2019 8:17 am

Make Random() use quads instead of integers

Post 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.
Last edited by BarryG on Mon Jan 27, 2020 1:48 am, edited 1 time in total.
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: Make Random() use quads instead of integers

Post 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
BarryG
Addict
Addict
Posts: 3324
Joined: Thu Apr 18, 2019 8:17 am

Re: Make Random() use quads instead of integers

Post 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.
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Make Random() use quads instead of integers

Post 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
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
STARGÅTE
Addict
Addict
Posts: 2089
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Make Random() use quads instead of integers

Post 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)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Post Reply