Skip to content

Instantly share code, notes, and snippets.

@countingpine
Last active May 16, 2021 15:35
Show Gist options
  • Save countingpine/f47b37b8b3ff7223abe0c79ed9c142dc to your computer and use it in GitHub Desktop.
Save countingpine/f47b37b8b3ff7223abe0c79ed9c142dc to your computer and use it in GitHub Desktop.
Finds (negative) values of n that can be passed to QB's RND(n) function, in order to return the desired number
'' FreeBASIC has a number of pseudorandom algorithms: set the QB algorithm (4)
randomize 0, 4
function unrnd(byval r as double) as long
#define SEED2R(seed) ( ((seed) + ((seed) shr 24)) and &HFFFFFF )
'' accept [0,1) or [0,16777215]
if r > 0.0 and r < 1.0 then
r = int(r * 16777216)
end if
'' roll back to previous seed
r = (culng(r) * &H93155 + &HCDF641) and &HFFFFFF
dim seedh as ubyte, seedl as ulong, seed as ulong
dim seedf as double
seedl = r: seedh = 0
seed = seedl + (seedh shl 24)
assert(SEED2R(seed) = r)
seedh = &HBE
seedl = (seedl - &HBE) and &HFFFFFF
seed = seedl + (seedh shl 24)
assert(SEED2R(seed) = r)
seedf = cvs(seed)
'' increment exponent (and decrement mantissa) until seed is a whole number
do until frac(seedf) = 0
seedh = seedh + 1
seedl = (seedl - 1) and &HFFFFFF
seed = seedl + (seedh shl 24)
assert(((seed + (seed shr 24)) and 16777215) = r)
seedf = cvs(seed)
loop
return clng(seedf)
end function
print "Sanity check: unrnd(rnd(-1)) should be -1:"
print unrnd(rnd(-1))
print
print "Value that makes rnd return 0.0:"
print unrnd(0), rnd(unrnd(0))*16777216
print
print "unrnd(327680) - where 327680 is the initial value of RND(0) * 2^24, in QB:"
print unrnd(327680), '' -16184694
print rnd(unrnd(327680))*16777216
print
print "If you call rnd(-16184694) in QB mode, then the next call to rnd()"
print "will return 0.7055475, the first value returned by RND in QB:"
print rnd
@countingpine
Copy link
Author

countingpine commented Feb 18, 2017

Note: there is a fairly efficient way of generating these numbers which doesn't involve brute-forcing them, but it involves knowing details of the algorithm which aren't fresh in my mind.

@countingpine
Copy link
Author

I've now removed the whole lookup table method and used the more intelligent way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment