Last active
May 16, 2021 15:35
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'' 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 "Value that makes rnd return 0.0:" | |
print unrnd(0), rnd(unrnd(0))*16777216 | |
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 "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 |
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
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.