On Scaling random numbers. #439
Replies: 6 comments 11 replies
-
Starting Forth introduces the helper word CHOOSE for this purpose:
: CHOOSE ( u1 -- u2 ) RANDOM UM* NIP ;
where CHOOSE returns a random integer within the range 0 = or < u2 < u1
…On Wed, 13 Jul 2022 at 16:25, Whammo ***@***.***> wrote:
Say you're looking for a random number between 0 and 999, RND returns a
number between 0 and 65,535.
How are you going to preserve your carefully crafted randomness?
999 requires 10 bits to represent. But that's 1023, there's 24 left over,
a fraction off.
It's all easy-peasy until your range isn't a power of 2.
You could just throw away any random number larger than 1000 and call it
done.
But why waste a good random number?
Back in the deep dark ages of 7th grade, when only Dick Tracy had cell
phones,
I remember that you need the least common multiple. Great.
999 1023 um*
That's 1,021,977, it takes 20 bits to represent. But that's 1,048,575
there's 26,598 left over,
but because everything is scaled up, so everything divides evenly, this
fraction's below our threshold.
include rnd
: rndmaze page142 emitbegin $4d rnd 100/ $80 andif 1+ then
rnd rnd 12 rshift1023 um/mod nip1024 + c! key? until
key drop page 14 emit ;
—
Reply to this email directly, view it on GitHub
<#439>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAY34O67SI4AYBMIEEKPUA3VT3GWJANCNFSM53O5RNTA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Here's a simple analysis of the method I used for random numbers between 0-999 require rnd
: ud. <# #s #> type space ;
: viz page
1024 1000 0 fill
begin
rnd rnd 12 rshift
1023 um/mod nip dup
1024 + dup c@ 1+ dup rot c!
26 <> if drop else
0 s>d 2048 1024 do i c@ m+ loop
2dup
1000 um/mod key drop page
. . ud. .
exit then again
; |
Beta Was this translation helpful? Give feedback.
-
Here's the similar sort of thing with the marker foo
require rnd
: ud. <# #s #> type space ;
: viz page
1024 1000 0 fill
begin 1000
rnd um* nip dup
1024 + dup c@ 1+ dup rot c!
26 <> if drop else
0 s>d 2048 1024 do i c@ m+ loop
2dup
1000 um/mod key drop page
. . ud. .
exit then again
;
|
Beta Was this translation helpful? Give feedback.
-
For the fun of it, another visualization!
|
Beta Was this translation helpful? Give feedback.
-
Neat!
…On Tue, 26 Jul 2022 at 14:04, Yann Vernier ***@***.***> wrote:
require gfx
require rnd
create ys 320 allot
: choose rnd um* nip ;
: blood
ys 320 0 fill
$21 clrcol
hires
begin
320 choose
dup ys +
dup c@ dup 1+ rot c!
plot
again ; blood
Thank you for the demo! Comments:
variable and allot may not use contiguous regions
<https://forth-standard.org/standard/usage#usage:dataspace> in other
implementations. create let me specify the desired size.
x was an index, y was a pointer, p was an array. Picked different naming.
Moved initialization so I could rerun the demo.
+! was doing word access to a byte array (including out of bounds)
Today I learned gfx plot does bound check
I wonder if 320 should be a constant
—
Reply to this email directly, view it on GitHub
<#439 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAY34O2CIEKC2ZL4HTJ5UELVV7H5HANCNFSM53O5RNTA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Adapted for two bytes of sid noise. require gfx
create ys 320 allot
: sidini ( -- )
$ffff $d40e !
$80 $d412 c! ;
: rnd ( -- c )
$D41B c@
$D41B c@ $100 * + ;
: choose rnd um* nip ;
: blood sidini
ys 320 0 fill
$21 clrcol
hires
begin
320 choose
dup ys +
dup c@ dup 1+ rot c!
plot
again ; blood
|
Beta Was this translation helpful? Give feedback.
-
Say you're looking for a random number between 0 and 999, RND returns a number between 0 and 65,535.
How are you going to preserve your carefully crafted randomness?
999 requires 10 bits to represent. But that's 1023, there's 24 left over, a fraction off.
It's all easy-peasy until your range isn't a power of 2.
You could just throw away any random number larger than 1000 and call it done.
But why waste a good random number?
Back in the deep dark ages of 7th grade, when only Dick Tracy had cell phones,
I remember that you need the least common multiple. Great.
That's 1,021,977, it takes 20 bits to represent. But that's 1,048,575 there's 26,598 left over,
but because everything is scaled up, so everything divides evenly, this fraction's below our threshold.
Beta Was this translation helpful? Give feedback.
All reactions